SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
Token.h
1 //=========================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //=========================================================================
10 #ifndef smtk_string_Token_h
11 #define smtk_string_Token_h
12 
13 #include "smtk/common/Deprecation.h"
14 #include "smtk/string/Manager.h"
15 
16 namespace smtk
17 {
18 namespace string
19 {
20 
30 class SMTKCORE_EXPORT Token
31 {
32 public:
34  Token(const char* data = nullptr, std::size_t size = std::string::npos);
36  Token(const std::string& data);
39  inline constexpr Token(Hash tokenId) noexcept
40  : m_id(tokenId)
41  {
42  }
43 
45  Hash id() const { return m_id; }
47  const std::string& data() const;
48 
50  bool operator==(const Token& other) const;
52  bool operator!=(const Token& other) const;
53 
55  bool operator<(const Token& other) const;
56  bool operator>(const Token& other) const;
57  bool operator<=(const Token& other) const;
58  bool operator>=(const Token& other) const;
59 
61  static Manager& manager();
62 
63 protected:
64  // ----
65  // Adapted from https://notes.underscorediscovery.com/constexpr-fnv1a/index.html
66  // which declared the source as public domain or equivalent. Retrieved on 2022-07-22.
67  // See also https://gist.github.com/ruby0x1/81308642d0325fd386237cfa3b44785c .
68  static constexpr uint32_t hash32a_const = 0x811c9dc5;
69  static constexpr uint32_t hash32b_const = 0x1000193;
70  static constexpr uint64_t hash64a_const = 0xcbf29ce484222325;
71  static constexpr uint64_t hash64b_const = 0x100000001b3;
72 
73  // Compute a 32-bit hash of a string.
74  // Unlike the original, this version handles embedded null characters so that
75  // unicode multi-byte sequences can be hashed.
76  template<typename T>
77  inline static constexpr typename std::enable_if<sizeof(T) == 4, T>::type
78  hash_fnv1a_const(const char* str, std::size_t size, T value) noexcept
79  {
80  return (!str || size <= 0)
81  ? value
82  : hash_fnv1a_const<T>(&str[1], size - 1, (value ^ uint32_t(str[0])) * hash32b_const);
83  }
84 
85  template<typename T>
86  inline static constexpr typename std::enable_if<sizeof(T) == 4, std::size_t>::type
87  hash_fnv1a_seed()
88  {
89  return hash32a_const;
90  }
91 
92  // Compute a 64-bit hash of a string.
93  template<typename T>
94  inline static constexpr typename std::enable_if<sizeof(T) == 8, std::size_t>::type
95  hash_fnv1a_const(const char* str, std::size_t size, uint64_t value) noexcept
96  {
97  return (!str || size <= 0)
98  ? value
99  : hash_fnv1a_const<T>(&str[1], size - 1, (value ^ uint64_t(str[0])) * hash64b_const);
100  }
101 
102  template<typename T>
103  inline static constexpr typename std::enable_if<sizeof(T) == 8, std::size_t>::type
104  hash_fnv1a_seed()
105  {
106  return hash64a_const;
107  }
108 
109 public:
112  inline static constexpr Hash stringHash(const char* data, std::size_t size) noexcept
113  {
114  return Token::hash_fnv1a_const<std::size_t>(data, size, Token::hash_fnv1a_seed<std::size_t>());
115  }
116 
120  static Token fromHash(Hash h);
121 
122 protected:
123  Hash m_id;
124  static std::shared_ptr<Manager> s_manager;
125 };
126 
127 SMTK_DEPRECATED_IN_22_11("Moving to smtk::string::literals namespace.")
128 inline Token operator""_token(const char* data, std::size_t size)
129 {
130  return Token{ data, size };
131 }
132 
133 namespace literals
134 {
135 
142 inline Token operator""_token(const char* data, std::size_t size)
143 {
144  return Token{ data, size };
145 }
146 
147 inline constexpr Hash operator""_hash(const char* data, std::size_t size)
148 {
149  return Token::stringHash(data, size);
150 }
151 
152 } // namespace literals
153 } // namespace string
154 } // namespace smtk
155 
156 bool SMTKCORE_EXPORT operator==(const std::string& a, const smtk::string::Token& b);
157 bool SMTKCORE_EXPORT operator!=(const std::string& a, const smtk::string::Token& b);
158 bool SMTKCORE_EXPORT operator>(const std::string& a, const smtk::string::Token& b);
159 bool SMTKCORE_EXPORT operator<(const std::string& a, const smtk::string::Token& b);
160 bool SMTKCORE_EXPORT operator>=(const std::string& a, const smtk::string::Token& b);
161 bool SMTKCORE_EXPORT operator<=(const std::string& a, const smtk::string::Token& b);
162 
163 bool SMTKCORE_EXPORT operator==(const smtk::string::Token& a, const std::string& b);
164 bool SMTKCORE_EXPORT operator!=(const smtk::string::Token& a, const std::string& b);
165 bool SMTKCORE_EXPORT operator>(const smtk::string::Token& a, const std::string& b);
166 bool SMTKCORE_EXPORT operator<(const smtk::string::Token& a, const std::string& b);
167 bool SMTKCORE_EXPORT operator>=(const smtk::string::Token& a, const std::string& b);
168 bool SMTKCORE_EXPORT operator<=(const smtk::string::Token& a, const std::string& b);
169 
170 bool SMTKCORE_EXPORT operator==(const char* a, const smtk::string::Token& b);
171 bool SMTKCORE_EXPORT operator!=(const char* a, const smtk::string::Token& b);
172 bool SMTKCORE_EXPORT operator>(const char* a, const smtk::string::Token& b);
173 bool SMTKCORE_EXPORT operator<(const char* a, const smtk::string::Token& b);
174 bool SMTKCORE_EXPORT operator>=(const char* a, const smtk::string::Token& b);
175 bool SMTKCORE_EXPORT operator<=(const char* a, const smtk::string::Token& b);
176 
177 bool SMTKCORE_EXPORT operator==(const smtk::string::Token& a, const char* b);
178 bool SMTKCORE_EXPORT operator!=(const smtk::string::Token& a, const char* b);
179 bool SMTKCORE_EXPORT operator>(const smtk::string::Token& a, const char* b);
180 bool SMTKCORE_EXPORT operator<(const smtk::string::Token& a, const char* b);
181 bool SMTKCORE_EXPORT operator>=(const smtk::string::Token& a, const char* b);
182 bool SMTKCORE_EXPORT operator<=(const smtk::string::Token& a, const char* b);
183 
184 namespace std
185 {
187 template<>
188 struct SMTKCORE_EXPORT hash<smtk::string::Token>
189 {
190  std::size_t operator()(const smtk::string::Token& t) const { return t.id(); }
191 };
192 } // namespace std
193 
194 #endif // smtk_string_Token_h
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
smtk::string::Token::stringHash
static constexpr Hash stringHash(const char *data, std::size_t size) noexcept
Return the hash of a string This is used internally but also by the ""_token() literal operator.
Definition: Token.h:112
smtk::string::Token::Token
constexpr Token(Hash tokenId) noexcept
Construct a token given its hash value.
Definition: Token.h:39
smtk::string::Hash
std::size_t Hash
A fixed-size integer type used to represent an arbitrary-length string.
Definition: Manager.h:34
smtk::string::Token::id
Hash id() const
Return the token's ID (usually its hash but possibly not in the case of collisions).
Definition: Token.h:45
smtk::string::Token
A string token identified by an integer.
Definition: Token.h:30
smtk::string::Manager
The string manager class is a dictionary mapping integers to (constant) string values.
Definition: Manager.h:40