25 template<
class value_t>
 
   26 constexpr 
size_t djb2a_hash(
const value_t* pszStr, 
size_t nSeed, 
size_t nLen)
 
   30     for (
size_t i = 0; i < nLen; ++i)
 
   31         nHash = nHash * 33 ^ pszStr[i];
 
   43 template<
class value_t>
 
   44 constexpr 
size_t djb2a_hash(
const value_t* pszStr, 
size_t nSeed)
 
   48     for (
size_t i = 0; pszStr[i]; ++i)
 
   49         nHash = nHash * 33 ^ pszStr[i];
 
   64 template<
class value_t>
 
   65 constexpr 
size_t murmur_32_hash(
const value_t* pStr, 
size_t nSeed, 
size_t nLen) noexcept
 
   77             static_assert(
sizeof(value_t) == 1 || 
sizeof(value_t) == 2 || 
sizeof(value_t) == 4);
 
   79             if constexpr (
sizeof(value_t) == 
sizeof(
u32))
 
   83             else if constexpr (
sizeof(value_t) == 
sizeof(
u16))
 
  103             k = (k << 15) | (k >> 17);
 
  107             nHash = (nHash << 13) | (nHash >> 19);
 
  108             nHash = nHash * 5 + 0xe6546b64; 
 
  122         k = (k << 15) | (k >> 17);
 
  128     nHash ^= nHash >> 16;
 
  130     nHash ^= nHash >> 13;
 
  132     nHash ^= nHash >> 16;
 
  149 template<
class fwd_it_1_t, 
class fwd_it_2_t>
 
  150 constexpr 
int iter_strcmp(fwd_it_1_t itBegin1, fwd_it_1_t itEnd1, fwd_it_2_t itBegin2, fwd_it_2_t itEnd2) noexcept
 
  155     while (it1 != itEnd1 && it2 != itEnd2 && *it1 == *it2)
 
  161     if (it1 == itEnd1 && it2 == itEnd2)
 
  165         return -
static_cast<int>(*it2);
 
  168         return static_cast<int>(*it1);
 
  170     return static_cast<int>(*it1) - 
static_cast<int>(*it2);
 
  182 template<
class value_t>
 
  183 constexpr 
int strcmp(
const value_t* pszLeft, 
const value_t* pszRight)
 
  185     while (*pszLeft && (*pszLeft == *pszRight))
 
  190     return *pszLeft - *pszRight;
 
  196 template<
class value_t>
 
  197 constexpr 
const value_t* choose_str_prefix(
const char*, 
const wchar_t*) noexcept;
 
  200 constexpr 
const char* choose_str_prefix<char>(
const char* c, 
const wchar_t*) noexcept
 
  206 constexpr 
const wchar_t* choose_str_prefix<wchar_t>(
const char*, 
const wchar_t* w) noexcept
 
  211 template<
class value_t>
 
  212 constexpr value_t choose_char_prefix(
char, 
wchar_t) noexcept;
 
  215 constexpr 
char choose_char_prefix<char>(
char c, 
wchar_t) noexcept
 
  221 constexpr 
wchar_t choose_char_prefix<wchar_t>(
char, 
wchar_t w) noexcept
 
  232 #define _QX_TO_WCHAR(x) L##x 
  235     #define _QX_TO_WSTRING(x) __LPREFIX(x) 
  237     #define _QX_TO_WSTRING(x) _QX_TO_WCHAR(x) 
  245 #define QX_TO_WSTRING(str) _QX_TO_WSTRING(str) 
  253 #define QX_STR_PREFIX(value_t, str) qx::details::choose_str_prefix<value_t>(str, QX_TO_WSTRING(str)) 
  261 #define QX_CHAR_PREFIX(value_t, ch) qx::details::choose_char_prefix<value_t>(ch, _QX_TO_WCHAR(ch)) 
  268 #define QX_STATIC_ASSERT_STR_EQ(a, b) static_assert(qx::strcmp((a), (b)) == 0) 
  269 #define QX_STATIC_ASSERT_STR_NE(a, b) static_assert(qx::strcmp((a), (b)) != 0) 
  270 #define QX_STATIC_ASSERT_STR_LT(a, b) static_assert(qx::strcmp((a), (b)) < 0) 
  271 #define QX_STATIC_ASSERT_STR_LE(a, b) static_assert(qx::strcmp((a), (b)) <= 0) 
  272 #define QX_STATIC_ASSERT_STR_GT(a, b) static_assert(qx::strcmp((a), (b)) > 0) 
  273 #define QX_STATIC_ASSERT_STR_GE(a, b) static_assert(qx::strcmp((a), (b)) >= 0) 
  286 template<
class value_t, 
class T>
 
  289     const value_t* pszFormat = 
nullptr;
 
  291     using test_type = std::remove_cvref_t<T>;
 
  293     if constexpr (std::is_same_v<test_type, char>)
 
  297     else if constexpr (std::is_same_v<test_type, unsigned char>)
 
  301     else if constexpr (std::is_same_v<test_type, short>)
 
  305     else if constexpr (std::is_same_v<test_type, unsigned short>)
 
  309     else if constexpr (std::is_same_v<test_type, int>)
 
  313     else if constexpr (std::is_same_v<test_type, unsigned int>)
 
  317     else if constexpr (std::is_same_v<test_type, long>)
 
  321     else if constexpr (std::is_same_v<test_type, unsigned long>)
 
  325     else if constexpr (std::is_same_v<test_type, long long>)
 
  329     else if constexpr (std::is_same_v<test_type, unsigned long long>)
 
  333     else if constexpr (std::is_same_v<test_type, float>)
 
  337     else if constexpr (std::is_same_v<test_type, double>)
 
  341     else if constexpr (std::is_same_v<test_type, long double>)
 
  345     else if constexpr (std::is_same_v<std::remove_cv_t<std::remove_pointer_t<test_type>>, 
char>)
 
  349     else if constexpr (std::is_same_v<std::remove_cv_t<std::remove_pointer_t<test_type>>, 
wchar_t>)
 
  353     else if constexpr (std::is_pointer_v<test_type>)
 
  372 template<
class value_t>
 
  373 constexpr std::size_t 
strlen(
const value_t* psz)
 
  378     std::size_t nLen = 0;
 
constexpr size_t djb2a_hash(const value_t *pszStr, size_t nSeed, size_t nLen)
djb2a hash
 
#define QX_CHAR_PREFIX(value_t, ch)
Chose witch of prefixes add to char : L or none.
 
constexpr int iter_strcmp(fwd_it_1_t itBegin1, fwd_it_1_t itEnd1, fwd_it_2_t itBegin2, fwd_it_2_t itEnd2) noexcept
Compares string 1 with string 2.
 
constexpr auto get_format_specifier() noexcept
Get format specifier for type.
 
constexpr size_t murmur_32_hash(const value_t *pStr, size_t nSeed, size_t nLen) noexcept
Murmur nHash.
 
constexpr int strcmp(const value_t *pszLeft, const value_t *pszRight)
Constexpr compare two strings.
 
constexpr std::size_t strlen(const value_t *psz)
Naive but constexpr string length algorithm, for runtime prefer std::strlen as there are may be a lot...
 
#define QX_STR_PREFIX(value_t, str)
Chose witch of prefixes add to string : L or none.
 
std::uint8_t u8
0 .. 65 535
 
std::uint32_t u32
0 .. 18 446 744 073 709 551 615
 
std::uint16_t u16
0 .. 4 294 967 295