C ++ converts string literal to multi-character literal at compile time
Basically, if I have this line:
"abcd"
I want to get the equivalent:
'abcd'
at compile time. I've tried using macros, preprocessor magic, and Microsoft's charize ( #@
) operator , but none of them work correctly. The end result should allow me to do something like this:
template <long N> struct some_type {};
long whatever = STR_TO_MULTI_CHAR_LITERAL("abcd");
some_type<whatever> xyz;
source to share
Suppose now we can forget about big / small endian, you can use constexpr
union
like
union dirty_hack {
long l;
char[4] chars;
};
If we need to consider endian, it becomes more complex. Also, the size long
can be 8, not 4.
Another thought if long
32bit is char32_t char4b = U'\UAABBFFFF'
supported in C ++ 11. But then you need to figure out the map from A
to 45
(hex value A
). Then we discard char4b
in long
.
source to share
If you can compile in C ++ 11 (or higher) mode, you will be allowed to index into string literals with a constant expression:
#define STR_TO_MULTI_CHAR_LITERAL(s) \
(sizeof(s) == 5 \
? s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3] \
: throw "wrong length")
some_type<STR_TO_MULTI_CHAR_LITERAL("abcd")> xyz;
That said, if you are allowed to use C ++ 11 mode, you should also be able to use constexpr
:
constexpr std::int32_t strToMultiCharLiteral(char const (&s)[5]) {
return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
}
some_type<strToMultiCharLiteral("abcd")> xyz;
You can even write a custom string literal:
constexpr std::int32_t operator""_multiCharLiteral(char const *s, std::size_t len)
{
return len == 4 ? s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]
: throw "wrong length";
}
some_type<"abcd"_multiCharLiteral> xyz;
source to share