I like this trick that I use in C. It's limited, as it only matches string prefixes, but it works pretty well in the end: https://tia.mat.br/posts/2018/02/01/more_on_string_switch_in... It allows you to write something like this: https://github.com/lpereira/lwan/blob/master/src/lib/lwan-ti... -- which is generated as a binary search by GCC.
Cttrie – Compile-time trie-based string matching for C++
11–20 of 21 posts
Re: Cttrie – Compile-time trie-based string matching for C++
#12====================
C preprocessor based compile time hash from lolengine:
http://lolengine.net/blog/2011/12/20/cpp-constant-string-has...
====================
#define H1(s,i,x)(x65599u+(uint8_t)s[(i) #define H4(s,i,x) H1(s,i,H1(s,i+1,H1(s,i+2,H1(s,i+3,x))))
#define H16(s,i,x) H4(s,i,H4(s,i+4,H4(s,i+8,H4(s,i+12,x))))
#define H64(s,i,x) H16(s,i,H16(s,i+16,H16(s,i+32,H16(s,i+48,x))))
#define H256(s,i,x) H64(s,i,H64(s,i+64,H64(s,i+128,H64(s,i+192,x))))
#define HASH(s) ((uint32_t)(H256(s,0,0)^(H256(s,0,0)>>16)))
template constexpr uint32_t h(char const (&s)[N]) { return HASH(s); }
constexpr uint32_t h(const char s) { return HASH(s); }
uint32_t h(const std::string& s) { return h(s.c_str()); }
int main(int argc, const char argv) {
auto s = "keep";
std::string x = "simple";
switch(h(x))
{
case h("keep") : std::cout Re: Cttrie – Compile-time trie-based string matching for C++
#13Why not just hash the string using constexpr ? ==================== C preprocessor based compile time hash from lolengine: http://lolengine.net/blog/2011/12/20/cpp-constant-string-has... ==================== #define H1(s,i,x)(x 65599u+(uint8_t)s[(i) #define H4(s,i,x) H1(s,i,H1(s,i+1,H1(s,i+2,H1(s,i+3,x)))) #define H16(s,i,x) H4(s,i,H4(s,i+4,H4(s,i+8,H4(s,i+12,x)))) #define H64(s,i,x) H16(s,i,H16(s,i+16,H16(s,i+32,H16…
Does the trie have to as well?
Re: Cttrie – Compile-time trie-based string matching for C++
#14Why not just hash the string using constexpr ? ==================== C preprocessor based compile time hash from lolengine: http://lolengine.net/blog/2011/12/20/cpp-constant-string-has... ==================== #define H1(s,i,x)(x 65599u+(uint8_t)s[(i) #define H4(s,i,x) H1(s,i,H1(s,i+1,H1(s,i+2,H1(s,i+3,x)))) #define H16(s,i,x) H4(s,i,H4(s,i+4,H4(s,i+8,H4(s,i+12,x)))) #define H64(s,i,x) H16(s,i,H16(s,i+16,H16(s,i+32,H16…
The hash has to look at all the chars in the string. Does the trie have to as well?
Otherwise there are some cases you can skip characters. I generally don’t use this optimization when writing Tries because it’s tricky and rarely makes a difference.
Re: Cttrie – Compile-time trie-based string matching for C++
#15Why not just hash the string using constexpr ? ==================== C preprocessor based compile time hash from lolengine: http://lolengine.net/blog/2011/12/20/cpp-constant-string-has... ==================== #define H1(s,i,x)(x 65599u+(uint8_t)s[(i) #define H4(s,i,x) H1(s,i,H1(s,i+1,H1(s,i+2,H1(s,i+3,x)))) #define H16(s,i,x) H4(s,i,H4(s,i+4,H4(s,i+8,H4(s,i+12,x)))) #define H64(s,i,x) H16(s,i,H16(s,i+16,H16(s,i+32,H16…
Also with that approach since it can't be made into a jump table it's still going to compile into a bunch of if/else combinations. At least with the trie it can early-return if the input doesn't have any chance of matching anything.
Re: Cttrie – Compile-time trie-based string matching for C++
#16If you're OK with textual code generation, you can also use something like re2c: http://re2c.org/ And then you get the power of regexes too. re2c will match an arbitrary set of regexes (including constant strings) by walking through the string byte-by-byte, a single time. A trie is basically a special case of a DFA.
Re: Cttrie – Compile-time trie-based string matching for C++
#17Re: Cttrie – Compile-time trie-based string matching for C++
#18For more practical reasons, what about just using runtime interned strings? Each unique string is hashed and allocated in heap memory only once, and to compare the strings you just compare the hashed values (which is just uint_64 comparison). Then you can easily use switch statements to compare your strings... As for performance, interning has an initial runtime cost for each string, but it will probably be miniscule compared to the massive compile time cost induced by crazy constexpr stuff.
Example of a string interning library:
https://github.com/mattiasgustavsson/libs/blob/master/docs/s...
Re: Cttrie – Compile-time trie-based string matching for C++
#19Why not just hash the string using constexpr ? ==================== C preprocessor based compile time hash from lolengine: http://lolengine.net/blog/2011/12/20/cpp-constant-string-has... ==================== #define H1(s,i,x)(x 65599u+(uint8_t)s[(i) #define H4(s,i,x) H1(s,i,H1(s,i+1,H1(s,i+2,H1(s,i+3,x)))) #define H16(s,i,x) H4(s,i,H4(s,i+4,H4(s,i+8,H4(s,i+12,x)))) #define H64(s,i,x) H16(s,i,H16(s,i+16,H16(s,i+32,H16…
Re: Cttrie – Compile-time trie-based string matching for C++
#20Why not just hash the string using constexpr ? ==================== C preprocessor based compile time hash from lolengine: http://lolengine.net/blog/2011/12/20/cpp-constant-string-has... ==================== #define H1(s,i,x)(x 65599u+(uint8_t)s[(i) #define H4(s,i,x) H1(s,i,H1(s,i+1,H1(s,i+2,H1(s,i+3,x)))) #define H16(s,i,x) H4(s,i,H4(s,i+4,H4(s,i+8,H4(s,i+12,x)))) #define H64(s,i,x) H16(s,i,H16(s,i+16,H16(s,i+32,H16…
The hash has to look at all the chars in the string. Does the trie have to as well?