Даже не знаю как User-define literals правильно перевести на Русский, посему пусть будет так.
Чего хочется - создать Шаблон для UDL, дабы подобный код прекрасно работал
auto a { "1a2bdead99"_hex };
auto b { "1111111111abcde"_hex };
Сам UDL составить не сложно, для входа фиксированной длинны, вот так например
using sha2 = std::array<uint8_t, 32>;
constexpr sha2 operator "" _hex(const char lit[64], size_t size) {
sha2 result {0};
char hex_str[3] { 0 };
char byte {0};
for (size_t i = 0; i < size; i += 2) {
hex_str[0] = lit[i];
hex_str[1] = lit[i+1];
byte = (char)strtol(hex_str, 0, 16);
result[i/2]=byte;
}
return result;
}
Но никак не могу подогнать под него шаблон
Чутка поэксперементировал, вот с этим
template <typename T, size_t n>
constexpr std::array<T,n> arr_test( const T (&arr)[n] ) {
std::array<T,n> result {0};
std::copy(std::begin(arr), std::end(arr), result.begin());
return result;
}
uint8_t my_array[200];
auto x = arr_test(my_array);
cout << x.size() << endl;
И тут всё хорошо, но только если не натягивать его на operator
В ограничениях на UDL говорится, что
If the literal operator is a template, it must have an empty parameter list and can have only one template parameter, which must be a non-type template parameter pack with element type
char
(in which case it is known as a numeric literal operator template)
И только сейчас до меня дошло, что надо использовать variadic template, в любом случае, если есть идеи как это сделать красиво, буду рад послушать
Вот такой черновик получился, может кому будет полезен
template <typename T, T... CharSet>
constexpr std::array<uint8_t,(sizeof...(CharSet))/2> operator "" _hex () {
std::array<uint8_t,(sizeof...(CharSet))/2> result;
T lit[sizeof...(CharSet)] { CharSet... };
char hex_str[3] { 0 };
char byte {0};
for (size_t i = 0; i < sizeof...(CharSet); i += 2) {
hex_str[0] = lit[i];
hex_str[1] = lit[i+1];
byte = (char)strtol(hex_str, 0, 16);
result[i/2]=byte;
}
return result;
}
auto some_hex { "aabbccddee1234"_hex};
cout << "Result type: " << abi::__cxa_demangle(typeid(some_hex).name(),0,0,&status) << endl;
cout << std::hex << setw(2) << setfill('0');
for (auto i : some_hex) {
cout << +i;
}
cout << endl;
Result type: std::array<unsigned char, 7ul>
aabbccddee1234