Adobe Source Libraries 2.0.0
A collection of C++ libraries.
Loading...
Searching...
No Matches
name.hpp
Go to the documentation of this file.
1/*
2 Copyright 2005-2013 Adobe Systems Incorporated
3 Distributed under the Boost Software License - Version 1.0 (see the accompanying file LICENSE
4 or a copy at https://stlab.github.io/adobe_source_libraries/licenses.html)
5*/
6
7/**************************************************************************************************/
8
9#ifndef ADOBE_NAME_HPP
10#define ADOBE_NAME_HPP
11
12/**************************************************************************************************/
13
14// stdc++
15#include <cstring>
16#include <functional>
17#include <iosfwd>
18#include <string_view>
19
20// boost
21#include <boost/mpl/bool.hpp>
22#include <boost/operators.hpp>
23
24// asl
25#include <adobe/conversion.hpp>
26#include <adobe/fnv.hpp>
27
44/**************************************************************************************************/
45
46namespace adobe {
47
48/**************************************************************************************************/
49
50namespace detail {
51
52/**************************************************************************************************/
53
54constexpr std::size_t sizesz_k = sizeof(std::size_t);
55
56constexpr bool sizeok_k = sizesz_k == 8 || sizesz_k == 4;
57
58constexpr std::size_t name_fnv_prime_k =
59 sizesz_k == 8 ? static_cast<std::size_t>(0x100000001b3) : static_cast<std::size_t>(0x1000193);
60
61constexpr std::size_t name_fnv_basis_k = sizesz_k == 8
62 ? static_cast<std::size_t>(0xcbf29ce484222325ULL)
63 : static_cast<std::size_t>(0x811c9dc5);
64
65constexpr std::size_t name_hash(const char* str, std::size_t len, std::size_t n,
66 std::size_t state) {
67 static_assert(sizeok_k, "Unknown sizeof std::size_t (must be 4 or 8).");
68
69 return n < len ? name_hash(str, len, n + 1,
70 (state ^ static_cast<std::size_t>(str[n])) * name_fnv_prime_k)
71 : state;
72}
73
74constexpr std::size_t name_hash(const char* str, std::size_t len) {
75 static_assert(sizeok_k, "Unknown sizeof std::size_t (must be 4 or 8).");
76
77 return name_hash(str, len, 0, name_fnv_basis_k);
78}
79
80template <std::size_t N>
81constexpr std::size_t name_hash(const char (&str)[N]) {
82 static_assert(sizeok_k, "Unknown sizeof std::size_t (must be 4 or 8).");
83
84 return name_hash(str, N - 1);
85}
86
87/**************************************************************************************************/
88
89} // namespace detail
90
91/**************************************************************************************************/
92
93struct static_name_t;
94
95/**************************************************************************************************/
96
97namespace literals {
98
99/**************************************************************************************************/
100
101inline constexpr static_name_t operator""_name(const char* str, std::size_t n);
102
103/**************************************************************************************************/
104
105} // namespace literals
106
107/**************************************************************************************************/
108
109using namespace literals;
110
111/**************************************************************************************************/
135struct static_name_t {
143 explicit operator bool() const;
144
145 friend bool operator==(const static_name_t& x, const static_name_t& y) {
146 return x.hash_m == y.hash_m;
147 }
148
149 friend bool operator!=(const static_name_t& x, const static_name_t& y) { return !(x == y); }
150
151 friend bool operator<(const static_name_t& x, const static_name_t& y);
152
155 std::size_t hash() const { return hash_m; }
156
157private:
158 static_name_t() = delete;
159
160 constexpr static_name_t(const char* str, std::size_t hash) : string_m(str), hash_m(hash) {}
161
162 friend struct name_t;
163
164 friend constexpr static_name_t literals::operator""_name(const char* str, std::size_t n);
165
166 friend std::ostream& operator<<(std::ostream& s, const static_name_t& name);
167
168 const char* string_m;
169 std::size_t hash_m;
170};
171
172/**************************************************************************************************/
173
174namespace literals {
175
176/**************************************************************************************************/
204inline constexpr static_name_t operator""_name(const char* str, std::size_t n) {
205 return static_name_t{str, detail::name_hash(str, n)};
206}
207
208/**************************************************************************************************/
209
210} // namespace literals
211
212/**************************************************************************************************/
220struct name_t : boost::totally_ordered<name_t, name_t> {
221 using const_iterator = const char*;
222 using iterator = const char*;
223
224 explicit name_t(const char* s = "") : ptr_m(map_string(s)) {}
225 operator std::string_view() const { return ptr_m; }
226
230 name_t(const static_name_t& static_name)
231 : ptr_m(map_string(static_name.string_m, static_name.hash_m, true)) {}
232
233 friend std::ostream& operator<<(std::ostream& s, const name_t& name);
234
242 explicit operator bool() const;
243
248 friend bool operator==(const name_t& x, const name_t& y) { return x.ptr_m == y.ptr_m; }
249
257 friend bool operator<(const name_t& x, const name_t& y) {
258 return std::strcmp(x.ptr_m, y.ptr_m) < 0;
259 }
260
261 const char* c_str() const { return ptr_m; }
262
263 const char* begin() const { return ptr_m; }
264 const char* end() const { return begin() + std::strlen(begin()); }
265
281 bool operator()(const name_t& x, const name_t& y) const { return x.ptr_m < y.ptr_m; }
282 };
283
287 [[deprecated("use `fast_compare{}` instead")]] static inline bool fast_sort(const name_t& x,
288 const name_t& y) {
289 return hash(x) < hash(y);
290 }
291
292private:
293 friend struct std::hash<name_t>;
294
302 static inline std::size_t hash(const name_t& x) { return std::hash<const char*>{}(x.ptr_m); }
303
304 static const char* map_string(const char* str);
305 static const char* map_string(const char* str, std::size_t hash, bool is_static);
306
307 const char* ptr_m;
308};
309
310/**************************************************************************************************/
319template <>
321 typedef name_t type;
322};
323
324/**************************************************************************************************/
325
326} // namespace adobe
327
328/**************************************************************************************************/
329
330namespace std {
331
332/**************************************************************************************************/
341template <>
342struct hash<adobe::name_t> {
343public:
344 inline std::size_t operator()(adobe::name_t const& name) const {
345 return adobe::name_t::hash(name);
346 }
347};
348
358template <>
359struct hash<adobe::static_name_t> {
360public:
361 inline std::size_t operator()(adobe::static_name_t const& name) const {
362 return std::hash<adobe::name_t>()(name);
363 }
364};
365
366/**************************************************************************************************/
367
368} // namespace std
369
370/**************************************************************************************************/
371
372#endif
373
374/**************************************************************************************************/
STL namespace.
bool operator()(const name_t &x, const name_t &y) const
Definition name.hpp:281
A character string class for immutable strings.
Definition name.hpp:220
const char * c_str() const
Definition name.hpp:261
name_t(const char *s="")
Definition name.hpp:224
const char * begin() const
Definition name.hpp:263
friend std::ostream & operator<<(std::ostream &s, const name_t &name)
const char * const_iterator
Definition name.hpp:221
friend bool operator==(const name_t &x, const name_t &y)
Definition name.hpp:248
const char * end() const
Definition name.hpp:264
friend bool operator<(const name_t &x, const name_t &y)
Definition name.hpp:257
static bool fast_sort(const name_t &x, const name_t &y)
Definition name.hpp:287
const char * iterator
Definition name.hpp:222
name_t(const static_name_t &static_name)
Definition name.hpp:230
A struct for compile-time type promotion.
Utility wrapper to construct name_t with strings of static storage duration.
Definition name.hpp:135
friend bool operator==(const static_name_t &x, const static_name_t &y)
Definition name.hpp:145
friend bool operator<(const static_name_t &x, const static_name_t &y)
friend struct name_t
Definition name.hpp:162
friend bool operator!=(const static_name_t &x, const static_name_t &y)
Definition name.hpp:149
friend std::ostream & operator<<(std::ostream &s, const static_name_t &name)
std::size_t hash() const
Return the hash value of the name_t.
Definition name.hpp:155
std::size_t operator()(adobe::name_t const &name) const
Definition name.hpp:344
std::size_t operator()(adobe::static_name_t const &name) const
Definition name.hpp:361