Better handling of ConstString types.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
09b6fd92ce
commit
aacca6e5e2
|
@ -1,66 +0,0 @@
|
||||||
#ifndef ARBUTILS_CASEINSENSITIVECONSTSTRING_HPP
|
|
||||||
#define ARBUTILS_CASEINSENSITIVECONSTSTRING_HPP
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace Arbutils {
|
|
||||||
class CaseInsensitiveConstString {
|
|
||||||
private:
|
|
||||||
const char* _str;
|
|
||||||
size_t _length;
|
|
||||||
uint32_t _hash;
|
|
||||||
|
|
||||||
inline static constexpr char charToLower(const char c) { return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; }
|
|
||||||
inline static uint32_t constexpr Hash(char const* input) {
|
|
||||||
return charToLower(*input) ? static_cast<uint32_t>(charToLower(*input)) + 33 * Hash(input + 1) : 5381;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static int constexpr Length(const char* str) { return *str ? 1 + Length(str + 1) : 0; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
constexpr CaseInsensitiveConstString() : _str(""), _length(0), _hash(Hash("")){};
|
|
||||||
constexpr explicit CaseInsensitiveConstString(const char* str)
|
|
||||||
: _str(str), _length(Length(str)), _hash(Hash(str)){};
|
|
||||||
constexpr explicit CaseInsensitiveConstString(const std::string& str)
|
|
||||||
: _str(str.c_str()), _length(str.length()), _hash(Hash(str.c_str())){};
|
|
||||||
constexpr explicit CaseInsensitiveConstString(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; }
|
|
||||||
|
|
||||||
constexpr std::size_t operator()(CaseInsensitiveConstString const& s) const noexcept { return s.GetHash(); }
|
|
||||||
inline constexpr operator uint32_t() const { return _hash; }
|
|
||||||
|
|
||||||
inline constexpr bool operator==(const CaseInsensitiveConstString& rhs) const { return _hash == rhs._hash; }
|
|
||||||
inline constexpr bool operator!=(const CaseInsensitiveConstString& rhs) const { return _hash != rhs._hash; }
|
|
||||||
inline constexpr bool operator==(const std::string& rhs) const { return _hash == Hash(rhs.c_str()); }
|
|
||||||
inline constexpr 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 constexpr Arbutils::CaseInsensitiveConstString operator"" _const_nocase(const char* c, size_t l) {
|
|
||||||
return Arbutils::CaseInsensitiveConstString(c, l);
|
|
||||||
}
|
|
||||||
inline constexpr Arbutils::CaseInsensitiveConstString operator"" _cnc(const char* c, size_t l) {
|
|
||||||
return Arbutils::CaseInsensitiveConstString(c, l);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
template <> struct hash<Arbutils::CaseInsensitiveConstString> {
|
|
||||||
constexpr std::size_t operator()(Arbutils::CaseInsensitiveConstString const& s) const noexcept {
|
|
||||||
return s.GetHash();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ARBUTILS_CASEINSENSITIVECONSTSTRING_HPP
|
|
|
@ -5,61 +5,33 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "__ConstStringCore.hpp"
|
||||||
|
|
||||||
namespace Arbutils {
|
ConstStringCore(
|
||||||
class ConstString {
|
ConstString,
|
||||||
private:
|
|
||||||
const char* _str;
|
|
||||||
size_t _length;
|
|
||||||
uint32_t _hash;
|
|
||||||
|
|
||||||
inline static uint32_t constexpr Hash(char const* input) {
|
inline static uint32_t constexpr Hash(char const* input) {
|
||||||
return (*input) ? static_cast<uint32_t>((*input)) + 33 * Hash(input + 1) : 5381;
|
return (*input) ? static_cast<uint32_t>((*input)) + 33 * Hash(input + 1) : 5381;
|
||||||
}
|
};)
|
||||||
|
|
||||||
inline static constexpr char charToLower(const char c) { return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; }
|
inline constexpr Arbutils::ConstString
|
||||||
inline static uint32_t constexpr LowercaseHash(char const* input) {
|
operator"" _const(const char* c, size_t l) {
|
||||||
return charToLower(*input) ? static_cast<uint32_t>(charToLower(*input)) + 33 * LowercaseHash(input + 1)
|
|
||||||
: 5381;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static int constexpr Length(const char* str) { return *str ? 1 + Length(str + 1) : 0; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
constexpr ConstString() : _str(""), _length(0), _hash(Hash("")){};
|
|
||||||
constexpr explicit ConstString(const char* str) : _str(str), _length(Length(str)), _hash(Hash(str)){};
|
|
||||||
constexpr explicit ConstString(const std::string& str)
|
|
||||||
: _str(str.c_str()), _length(str.length()), _hash(Hash(str.c_str())){};
|
|
||||||
constexpr explicit ConstString(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; }
|
|
||||||
|
|
||||||
constexpr std::size_t operator()(ConstString const& s) const noexcept { return s.GetHash(); }
|
|
||||||
inline constexpr operator uint32_t() const { return _hash; }
|
|
||||||
|
|
||||||
inline constexpr bool operator==(const ConstString& rhs) const { return _hash == rhs._hash; }
|
|
||||||
inline constexpr bool operator!=(const ConstString& rhs) const { return _hash != rhs._hash; }
|
|
||||||
inline constexpr bool operator==(const std::string& rhs) const { return _hash == Hash(rhs.c_str()); }
|
|
||||||
inline constexpr 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 constexpr Arbutils::ConstString operator"" _const(const char* c, size_t l) {
|
|
||||||
return Arbutils::ConstString(c, l);
|
return Arbutils::ConstString(c, l);
|
||||||
}
|
}
|
||||||
inline constexpr Arbutils::ConstString operator"" _c(const char* c, size_t l) { return Arbutils::ConstString(c, l); }
|
inline constexpr Arbutils::ConstString operator"" _c(const char* c, size_t l) { return Arbutils::ConstString(c, l); }
|
||||||
|
|
||||||
namespace std {
|
ConstStringCore(
|
||||||
template <> struct hash<Arbutils::ConstString> {
|
CaseInsensitiveConstString,
|
||||||
constexpr std::size_t operator()(Arbutils::ConstString const& s) const noexcept { return s.GetHash(); }
|
inline static constexpr char charToLower(const char c) {
|
||||||
};
|
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
|
||||||
|
} inline static uint32_t constexpr Hash(char const* input) {
|
||||||
|
return charToLower(*input) ? static_cast<uint32_t>(charToLower(*input)) + 33 * Hash(input + 1) : 5381;
|
||||||
|
};);
|
||||||
|
|
||||||
|
inline constexpr Arbutils::CaseInsensitiveConstString operator"" _const_nocase(const char* c, size_t l) {
|
||||||
|
return Arbutils::CaseInsensitiveConstString(c, l);
|
||||||
|
}
|
||||||
|
inline constexpr Arbutils::CaseInsensitiveConstString operator"" _cnc(const char* c, size_t l) {
|
||||||
|
return Arbutils::CaseInsensitiveConstString(c, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ARBUTILS_CONSTSTRING_HPP
|
#endif // ARBUTILS_CONSTSTRING_HPP
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
#ifndef ARBUTILS_CONSTSTRINGCORE_HPP
|
||||||
|
#define ARBUTILS_CONSTSTRINGCORE_HPP
|
||||||
|
|
||||||
|
#if WINDOWS
|
||||||
|
#define STDSTRINGEQUALITY \
|
||||||
|
inline bool operator==(const std::string& rhs) const { return _hash == Hash(rhs.c_str()); } \
|
||||||
|
inline bool operator!=(const std::string& rhs) const { return _hash != Hash(rhs.c_str()); }
|
||||||
|
#else
|
||||||
|
#define STDSTRINGEQUALITY \
|
||||||
|
inline constexpr bool operator==(const std::string& rhs) const { return _hash == Hash(rhs.c_str()); } \
|
||||||
|
inline constexpr bool operator!=(const std::string& rhs) const { return _hash != Hash(rhs.c_str()); }
|
||||||
|
#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)){}; \
|
||||||
|
constexpr 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; } \
|
||||||
|
\
|
||||||
|
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; } \
|
||||||
|
STDSTRINGEQUALITY \
|
||||||
|
inline constexpr bool operator==(const char* rhs) const { return _hash == Hash(rhs); } \
|
||||||
|
inline constexpr bool operator!=(const char* rhs) const { return _hash != Hash(rhs); } \
|
||||||
|
}; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
namespace std { \
|
||||||
|
template <> struct hash<Arbutils::name> { \
|
||||||
|
constexpr std::size_t operator()(Arbutils::name const& s) const noexcept { return s.GetHash(); } \
|
||||||
|
}; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,7 +2,6 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "../extern/catch.hpp"
|
#include "../extern/catch.hpp"
|
||||||
#include "../src/CaseInsensitiveConstString.hpp"
|
|
||||||
#include "../src/ConstString.hpp"
|
#include "../src/ConstString.hpp"
|
||||||
|
|
||||||
TEST_CASE("Use const string in unordered_map", "[Utilities]") {
|
TEST_CASE("Use const string in unordered_map", "[Utilities]") {
|
||||||
|
|
Loading…
Reference in New Issue