I want to implement a kind of Symbol in the same way ruby ββdoes.
To do this, I created a custom literal that returned std::hash corresponding std::basic_string<T> .
The code was wonderful, but since I read somewhere , the hash function may not be consistent across multiple executions of the same program. Moreover, I would like to do this calculation at compile time, which was 1) not supported by std::hash and 2) if std::hash changed the return value, I would have broken the code.
So, I wrote the following implementation based on java.lang.String.hashCode .
typedef size_t symbol; template<typename CharT> constexpr size_t constant_hash(const CharT* p, size_t h = 0) noexcept { return (*p == 0) ? h : constant_hash(p + 1, h * 31 + static_cast<size_t>(*p)); } constexpr symbol operator "" _sym (const char* p, size_t n) noexcept { return constant_hash(p); }
My question is : are there any problems with this implementation?
I can only test it on GCC 4.7.1, and I would like to know if it complies with the standard and should also work with another compiler.
I ask this because the previous implementation worked on GCC, but called segfault if the binary was compiled using clang ++ (the problem is undefined behavior with index operators, which I think).
Thanks in advance
Edit
Work with clang ++ (thanks KennyTM)
source share