Arbutils/src/__ConstStringCore.hpp

62 lines
6.1 KiB
C++

#ifndef ARBUTILS_CONSTSTRINGCORE_HPP
#define ARBUTILS_CONSTSTRINGCORE_HPP
#if WINDOWS
#define STDSTRINGCONSTEXPR
#else
#define STDSTRINGCONSTEXPR constexpr
#endif
#define ConstStringCore(name, hashFunction) \
namespace Arbutils { \
class name { \
private: \
const char* _str; \
size_t _length; \
uint32_t _hash; \
\
hashFunction; \
\
inline static int constexpr Length(const char* str) { return *str ? 1 + Length(str + 1) : 0; } \
\
public: \
constexpr name() : _str(""), _length(0), _hash(Hash("")){}; \
constexpr explicit name(const char* str) : _str(str), _length(Length(str)), _hash(Hash(str)){}; \
STDSTRINGCONSTEXPR explicit name(const std::string& str) \
: _str(str.c_str()), _length(str.length()), _hash(Hash(str.c_str())){}; \
constexpr explicit name(const char* str, size_t size) : _str(str), _length(size), _hash(Hash(str)){}; \
\
[[nodiscard]] inline constexpr const char* c_str() const noexcept { return _str; } \
[[nodiscard]] inline std::string std_str() const { return std::string(_str, _length); } \
\
[[nodiscard]] inline constexpr size_t Length() const noexcept { return _length; } \
\
[[nodiscard]] inline constexpr uint32_t GetHash() const noexcept { return _hash; } \
inline constexpr bool Empty() const noexcept { return _length == 0; } \
\
constexpr std::size_t operator()(name const& s) const noexcept { return s.GetHash(); } \
inline constexpr operator uint32_t() const { return _hash; } \
\
inline constexpr bool operator==(const name& rhs) const { return _hash == rhs._hash; } \
inline constexpr bool operator!=(const name& rhs) const { return _hash != rhs._hash; } \
inline STDSTRINGCONSTEXPR bool operator==(const std::string& rhs) const { \
return _hash == Hash(rhs.c_str()); \
} \
inline STDSTRINGCONSTEXPR bool operator!=(const std::string& rhs) const { \
return _hash != Hash(rhs.c_str()); \
} \
inline constexpr bool operator==(const char* rhs) const { return _hash == Hash(rhs); } \
inline constexpr bool operator!=(const char* rhs) const { return _hash != Hash(rhs); } \
\
inline static constexpr uint32_t GetHash(const char* val) { return Hash(val); } \
inline static STDSTRINGCONSTEXPR uint32_t GetHash(const std::string& val) { return Hash(val.c_str()); } \
}; \
} \
\
namespace std { \
template <> struct hash<Arbutils::name> { \
constexpr std::size_t operator()(Arbutils::name const& s) const noexcept { return s.GetHash(); } \
}; \
}
#endif