Adobe Source Libraries  1.43
name.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2005-2013 Adobe Systems Incorporated
3  Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
4  or a copy at http://stlab.adobe.com/licenses.html)
5 */
6 
7 /**************************************************************************************************/
8 
9 #ifndef ADOBE_NAME_HPP
10 #define ADOBE_NAME_HPP
11 
12 /**************************************************************************************************/
13 
14 // stdc++
15 #include <functional>
16 #include <iosfwd>
17 
18 // boost
19 #include <boost/operators.hpp>
20 #include <boost/type_traits/is_pod.hpp>
21 
22 // asl
23 #include <adobe/conversion.hpp>
24 #include <adobe/cstring.hpp>
25 #include <adobe/fnv.hpp>
26 
43 /**************************************************************************************************/
44 
45 namespace adobe {
46 
47 /**************************************************************************************************/
48 
49 namespace detail {
50 
51 /**************************************************************************************************/
52 
53 constexpr std::size_t sizesz_k = sizeof(std::size_t);
54 
55 constexpr bool sizeok_k = sizesz_k == 8 || sizesz_k == 4;
56 
57 constexpr std::size_t name_fnv_prime_k =
58  sizesz_k == 8 ? static_cast<std::size_t>(0x100000001b3) : static_cast<std::size_t>(0x1000193);
59 
60 constexpr std::size_t name_fnv_basis_k = sizesz_k == 8
61  ? static_cast<std::size_t>(0xcbf29ce484222325ULL)
62  : static_cast<std::size_t>(0x811c9dc5);
63 
64 constexpr std::size_t name_hash(const char* str, std::size_t len, std::size_t n,
65  std::size_t state) {
66  static_assert(sizeok_k, "Unknown sizeof std::size_t (must be 4 or 8).");
67 
68  return n < len ? name_hash(str, len, n + 1,
69  (state xor static_cast<std::size_t>(str[n])) * name_fnv_prime_k)
70  : state;
71 }
72 
73 constexpr std::size_t name_hash(const char* str, std::size_t len) {
74  static_assert(sizeok_k, "Unknown sizeof std::size_t (must be 4 or 8).");
75 
76  return name_hash(str, len, 0, name_fnv_basis_k);
77 }
78 
79 template <std::size_t N>
80 constexpr std::size_t name_hash(const char (&str)[N]) {
81  static_assert(sizeok_k, "Unknown sizeof std::size_t (must be 4 or 8).");
82 
83  return name_hash(str, N - 1);
84 }
85 
86 /**************************************************************************************************/
87 
88 } // namespace detail
89 
90 /**************************************************************************************************/
91 
92 struct static_name_t;
93 
94 /**************************************************************************************************/
95 
96 namespace literals {
97 
98 /**************************************************************************************************/
99 
100 inline constexpr static_name_t operator"" _name(const char* str, std::size_t n);
101 
102 /**************************************************************************************************/
103 
104 } // namespace literals
105 
106 /**************************************************************************************************/
107 
108 using namespace literals;
109 
110 /**************************************************************************************************/
142  explicit operator bool() const;
143 
144  friend bool operator==(const static_name_t& x, const static_name_t& y) {
145  return x.hash_m == y.hash_m;
146  }
147 
148  friend bool operator!=(const static_name_t& x, const static_name_t& y) { return !(x == y); }
149 
150  friend bool operator<(const static_name_t& x, const static_name_t& y);
151 
152 private:
153  static_name_t() = delete;
154 
155  constexpr static_name_t(const char* str, std::size_t hash) : string_m(str), hash_m(hash) {}
156 
157  friend struct name_t;
158 
159  friend constexpr static_name_t literals::operator"" _name(const char* str, std::size_t n);
160 
161  friend std::ostream& operator<<(std::ostream& s, const static_name_t& name);
162 
163  const char* string_m;
164 
165  std::size_t hash_m;
166 };
167 
168 /**************************************************************************************************/
169 
170 namespace literals {
171 
172 /**************************************************************************************************/
200 inline constexpr static_name_t operator"" _name(const char* str, std::size_t n) {
201  return static_name_t{str, detail::name_hash(str, n)};
202 }
203 
204 /**************************************************************************************************/
205 
206 } // namespace literals
207 
208 /**************************************************************************************************/
216 struct name_t : boost::totally_ordered<name_t, name_t> {
217  explicit name_t(const char* s = "") : ptr_m(map_string(s)) {}
218 
222  name_t(const static_name_t& static_name)
223  : ptr_m(map_string(static_name.string_m, static_name.hash_m)) {}
224 
225  friend std::ostream& operator<<(std::ostream& s, const name_t& name);
226 
234  explicit operator bool() const;
235 
240  friend bool operator==(const name_t& x, const name_t& y) { return x.ptr_m == y.ptr_m; }
241 
249  friend bool operator<(const name_t& x, const name_t& y) {
250  return std::strcmp(x.ptr_m, y.ptr_m) < 0;
251  }
252 
253  const char* c_str() const { return ptr_m; }
254 
255  const char* begin() const { return ptr_m; }
256  const char* end() const { return begin() + std::strlen(begin()); }
257 
272  static inline bool fast_sort(const name_t& x, const name_t& y) { return hash(x) < hash(y); }
273 
274 private:
275  friend struct std::hash<name_t>;
276 
284  static inline std::size_t hash(const name_t& x) {
285  return reinterpret_cast<std::size_t>(x.ptr_m);
286  }
287 
288  static const char* map_string(const char* str);
289  static const char* map_string(const char* str, std::size_t hash);
290 
291  const char* ptr_m;
292 };
293 
294 /**************************************************************************************************/
303 template <>
304 struct promote<static_name_t> {
305  typedef name_t type;
306 };
307 
308 /**************************************************************************************************/
309 
310 } // namespace adobe
311 
312 /**************************************************************************************************/
313 
314 namespace std {
315 
316 /**************************************************************************************************/
325 template <>
326 struct hash<adobe::name_t> {
327 public:
328  inline std::size_t operator()(adobe::name_t const& name) const {
329  return adobe::name_t::hash(name);
330  }
331 };
332 
342 template <>
343 struct hash<adobe::static_name_t> {
344 public:
345  inline std::size_t operator()(adobe::static_name_t const& name) const {
346  return std::hash<adobe::name_t>()(name);
347  }
348 };
349 
350 /**************************************************************************************************/
351 
352 } // namespace std
353 
354 /**************************************************************************************************/
355 
356 namespace boost {
357 
358 /**************************************************************************************************/
359 
365 template <>
366 struct is_pod<adobe::name_t> : boost::mpl::true_ {};
367 
368 /**************************************************************************************************/
369 
370 } // namespace boost
371 
372 /**************************************************************************************************/
373 
374 #endif
375 
376 /**************************************************************************************************/
friend bool operator==(const name_t &x, const name_t &y)
Definition: name.hpp:240
name_t(const char *s="")
Definition: name.hpp:217
const char * begin() const
Definition: name.hpp:255
const char * end() const
Definition: name.hpp:256
friend bool operator<(const name_t &x, const name_t &y)
Definition: name.hpp:249
friend bool operator!=(const static_name_t &x, const static_name_t &y)
Definition: name.hpp:148
std::ostream & operator<<(std::ostream &out, const array_t &x)
Definition: array.hpp:38
std::size_t operator()(adobe::name_t const &name) const
Definition: name.hpp:328
const char * c_str() const
Definition: name.hpp:253
friend bool operator==(const static_name_t &x, const static_name_t &y)
Definition: name.hpp:144
std::size_t operator()(adobe::static_name_t const &name) const
Definition: name.hpp:345
static bool fast_sort(const name_t &x, const name_t &y)
Definition: name.hpp:272
name_t(const static_name_t &static_name)
Definition: name.hpp:222