diff --git a/src/ConstString.hpp b/src/ConstString.hpp index ce45b47..0b58616 100644 --- a/src/ConstString.hpp +++ b/src/ConstString.hpp @@ -13,12 +13,11 @@ ConstStringCore( return (*input) ? static_cast((*input)) + 33 * Hash(input + 1) : 5381; };) - inline constexpr Arbutils::ConstString - operator"" _const(const char* c, size_t l) { - return Arbutils::ConstString::Literal(c, l); +inline constexpr Arbutils::ConstString_Literal operator"" _const(const char* c, size_t l) { + return Arbutils::ConstString_Literal(c, l); } -inline constexpr Arbutils::ConstString operator"" _c(const char* c, size_t l) { - return Arbutils::ConstString::Literal(c, l); +inline constexpr Arbutils::ConstString_Literal operator"" _c(const char* c, size_t l) { + return Arbutils::ConstString_Literal(c, l); } ConstStringCore( @@ -29,11 +28,11 @@ ConstStringCore( return charToLower(*input) ? static_cast(charToLower(*input)) + 33 * Hash(input + 1) : 5381; };); -inline constexpr Arbutils::CaseInsensitiveConstString operator"" _const_nocase(const char* c, size_t l) { - return Arbutils::CaseInsensitiveConstString::Literal(c, l); +inline constexpr Arbutils::CaseInsensitiveConstString_Literal operator"" _const_nocase(const char* c, size_t l) { + return Arbutils::CaseInsensitiveConstString_Literal(c, l); } -inline constexpr Arbutils::CaseInsensitiveConstString operator"" _cnc(const char* c, size_t l) { - return Arbutils::CaseInsensitiveConstString::Literal(c, l); +inline constexpr Arbutils::CaseInsensitiveConstString_Literal operator"" _cnc(const char* c, size_t l) { + return Arbutils::CaseInsensitiveConstString_Literal(c, l); } #endif // ARBUTILS_CONSTSTRING_HPP diff --git a/src/__ConstStringCore.hpp b/src/__ConstStringCore.hpp index abdab50..8a241ec 100644 --- a/src/__ConstStringCore.hpp +++ b/src/__ConstStringCore.hpp @@ -19,19 +19,16 @@ \ inline static int constexpr Length(const char* str) { return *str ? 1 + Length(str + 1) : 0; } \ \ - constexpr explicit name(const char* str, size_t size, bool) \ - : _str(const_cast(str)), _length(size), _hash(Hash(str)) {} \ - \ public: \ - explicit name(const char* str, size_t size) : _str(nullptr), _length(size), _hash(Hash(str)) { \ - _str = new char[size]; \ + name(const char* str, size_t size) : _str(nullptr), _length(size), _hash(Hash(str)) { \ + _str = new char[size + 1]; \ strcpy(_str, str); \ } \ name() : name("", 0){}; \ explicit name(const char* str) : name(str, Length(str)){}; \ explicit name(const std::string& str) : name(str.c_str(), str.size()){}; \ - \ - static constexpr inline name Literal(const char* str, size_t size) { return name(str, size, false); } \ + name(const name& other) : name(other._str, other._length) {} \ + ~name() { delete[] _str; } \ \ [[nodiscard]] inline constexpr const char* c_str() const noexcept { return _str; } \ [[nodiscard]] inline std::string std_str() const { return std::string(_str, _length); } \ @@ -57,6 +54,44 @@ \ 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()); } \ + }; \ + \ + class name##_Literal { \ + 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; } \ + \ + constexpr explicit name##_Literal(const char* str, size_t size, bool) \ + : _str(const_cast(str)), _length(size), _hash(Hash(str)) {} \ + \ + public: \ + constexpr name##_Literal(const char* str, size_t size) : _str(str), _length(size), _hash(Hash(str)) {} \ + explicit name##_Literal(const char* str) : name##_Literal(str, Length(str)){}; \ + [[nodiscard]] inline constexpr const char* c_str() const noexcept { return _str; } \ + [[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##_Literal const& s) const noexcept { return s.GetHash(); } \ + inline constexpr operator uint32_t() const { return _hash; } \ + inline operator name() const { return name(_str, _length); } \ + \ + inline constexpr bool operator==(const name##_Literal& rhs) const { return _hash == rhs._hash; } \ + inline constexpr bool operator!=(const name##_Literal& 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); } \ }; \ } \ \ @@ -64,6 +99,9 @@ template <> struct hash { \ constexpr std::size_t operator()(Arbutils::name const& s) const noexcept { return s.GetHash(); } \ }; \ + template <> struct hash { \ + constexpr std::size_t operator()(Arbutils::name##_Literal const& s) const noexcept { return s.GetHash(); } \ + }; \ } #endif \ No newline at end of file