1 | // Boost uuid.hpp header file ----------------------------------------------// |
2 | |
3 | // Copyright 2006 Andy Tompkins. |
4 | // Distributed under the Boost Software License, Version 1.0. (See |
5 | // accompanying file LICENSE_1_0.txt or copy at |
6 | // http://www.boost.org/LICENSE_1_0.txt) |
7 | |
8 | // Revision History |
9 | // 06 Feb 2006 - Initial Revision |
10 | // 09 Nov 2006 - fixed variant and version bits for v4 guids |
11 | // 13 Nov 2006 - added serialization |
12 | // 17 Nov 2006 - added name-based guid creation |
13 | // 20 Nov 2006 - add fixes for gcc (from Tim Blechmann) |
14 | // 07 Mar 2007 - converted to header only |
15 | // 10 May 2007 - removed need for Boost.Thread |
16 | // - added better seed - thanks Peter Dimov |
17 | // - removed null() |
18 | // - replaced byte_count() and output_bytes() with size() and begin() and end() |
19 | // 11 May 2007 - fixed guid(ByteInputIterator first, ByteInputIterator last) |
20 | // - optimized operator>> |
21 | // 14 May 2007 - converted from guid to uuid |
22 | // 29 May 2007 - uses new implementation of sha1 |
23 | // 01 Jun 2007 - removed using namespace directives |
24 | // 09 Nov 2007 - moved implementation to uuid.ipp file |
25 | // 12 Nov 2007 - moved serialize code to uuid_serialize.hpp file |
26 | // 25 Feb 2008 - moved to namespace boost::uuids |
27 | // 19 Mar 2009 - changed to a POD, reorganized files |
28 | // 28 Nov 2009 - disabled deprecated warnings for MSVC |
29 | // 30 Nov 2009 - used BOOST_STATIC_CONSTANT |
30 | // 02 Dec 2009 - removed BOOST_STATIC_CONSTANT - not all compilers like it |
31 | // 29 Apr 2013 - added support for noexcept and constexpr, added optimizations for SSE/AVX |
32 | |
33 | #ifndef BOOST_UUID_HPP |
34 | #define BOOST_UUID_HPP |
35 | |
36 | #include <cstddef> |
37 | #include <boost/cstdint.hpp> |
38 | #include <boost/uuid/detail/config.hpp> |
39 | #ifndef BOOST_UUID_NO_TYPE_TRAITS |
40 | #include <boost/type_traits/is_pod.hpp> |
41 | #include <boost/type_traits/integral_constant.hpp> |
42 | #endif |
43 | |
44 | #ifdef BOOST_HAS_PRAGMA_ONCE |
45 | #pragma once |
46 | #endif |
47 | |
48 | #if defined(_MSC_VER) |
49 | #pragma warning(push) // Save warning settings. |
50 | #pragma warning(disable : 4996) // Disable deprecated std::swap_ranges, std::equal |
51 | #endif |
52 | |
53 | #ifdef BOOST_NO_STDC_NAMESPACE |
54 | namespace std { |
55 | using ::size_t; |
56 | using ::ptrdiff_t; |
57 | } //namespace std |
58 | #endif //BOOST_NO_STDC_NAMESPACE |
59 | |
60 | namespace boost { |
61 | namespace uuids { |
62 | |
63 | struct uuid |
64 | { |
65 | public: |
66 | typedef uint8_t value_type; |
67 | typedef uint8_t& reference; |
68 | typedef uint8_t const& const_reference; |
69 | typedef uint8_t* iterator; |
70 | typedef uint8_t const* const_iterator; |
71 | typedef std::size_t size_type; |
72 | typedef std::ptrdiff_t difference_type; |
73 | |
74 | // This does not work on some compilers |
75 | // They seem to want the variable definec in |
76 | // a cpp file |
77 | //BOOST_STATIC_CONSTANT(size_type, static_size = 16); |
78 | static BOOST_CONSTEXPR size_type static_size() BOOST_NOEXCEPT { return 16; } |
79 | |
80 | public: |
81 | iterator begin() BOOST_NOEXCEPT { return data; } |
82 | const_iterator begin() const BOOST_NOEXCEPT { return data; } |
83 | iterator end() BOOST_NOEXCEPT { return data+size(); } |
84 | const_iterator end() const BOOST_NOEXCEPT { return data+size(); } |
85 | |
86 | BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT { return static_size(); } |
87 | |
88 | bool is_nil() const BOOST_NOEXCEPT; |
89 | |
90 | enum variant_type |
91 | { |
92 | variant_ncs, // NCS backward compatibility |
93 | variant_rfc_4122, // defined in RFC 4122 document |
94 | variant_microsoft, // Microsoft Corporation backward compatibility |
95 | variant_future // future definition |
96 | }; |
97 | variant_type variant() const BOOST_NOEXCEPT |
98 | { |
99 | // variant is stored in octet 7 |
100 | // which is index 8, since indexes count backwards |
101 | unsigned char octet7 = data[8]; // octet 7 is array index 8 |
102 | if ( (octet7 & 0x80) == 0x00 ) { // 0b0xxxxxxx |
103 | return variant_ncs; |
104 | } else if ( (octet7 & 0xC0) == 0x80 ) { // 0b10xxxxxx |
105 | return variant_rfc_4122; |
106 | } else if ( (octet7 & 0xE0) == 0xC0 ) { // 0b110xxxxx |
107 | return variant_microsoft; |
108 | } else { |
109 | //assert( (octet7 & 0xE0) == 0xE0 ) // 0b111xxxx |
110 | return variant_future; |
111 | } |
112 | } |
113 | |
114 | enum version_type |
115 | { |
116 | version_unknown = -1, |
117 | version_time_based = 1, |
118 | version_dce_security = 2, |
119 | version_name_based_md5 = 3, |
120 | version_random_number_based = 4, |
121 | version_name_based_sha1 = 5 |
122 | }; |
123 | version_type version() const BOOST_NOEXCEPT |
124 | { |
125 | // version is stored in octet 9 |
126 | // which is index 6, since indexes count backwards |
127 | uint8_t octet9 = data[6]; |
128 | if ( (octet9 & 0xF0) == 0x10 ) { |
129 | return version_time_based; |
130 | } else if ( (octet9 & 0xF0) == 0x20 ) { |
131 | return version_dce_security; |
132 | } else if ( (octet9 & 0xF0) == 0x30 ) { |
133 | return version_name_based_md5; |
134 | } else if ( (octet9 & 0xF0) == 0x40 ) { |
135 | return version_random_number_based; |
136 | } else if ( (octet9 & 0xF0) == 0x50 ) { |
137 | return version_name_based_sha1; |
138 | } else { |
139 | return version_unknown; |
140 | } |
141 | } |
142 | |
143 | // note: linear complexity |
144 | void swap(uuid& rhs) BOOST_NOEXCEPT; |
145 | |
146 | public: |
147 | // or should it be array<uint8_t, 16> |
148 | uint8_t data[16]; |
149 | }; |
150 | |
151 | bool operator== (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT; |
152 | bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT; |
153 | |
154 | inline bool operator!=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT |
155 | { |
156 | return !(lhs == rhs); |
157 | } |
158 | |
159 | inline bool operator>(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT |
160 | { |
161 | return rhs < lhs; |
162 | } |
163 | inline bool operator<=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT |
164 | { |
165 | return !(rhs < lhs); |
166 | } |
167 | |
168 | inline bool operator>=(uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT |
169 | { |
170 | return !(lhs < rhs); |
171 | } |
172 | |
173 | inline void swap(uuid& lhs, uuid& rhs) BOOST_NOEXCEPT |
174 | { |
175 | lhs.swap(rhs); |
176 | } |
177 | |
178 | // This is equivalent to boost::hash_range(u.begin(), u.end()); |
179 | inline std::size_t hash_value(uuid const& u) BOOST_NOEXCEPT |
180 | { |
181 | std::size_t seed = 0; |
182 | for(uuid::const_iterator i=u.begin(), e=u.end(); i != e; ++i) |
183 | { |
184 | seed ^= static_cast<std::size_t>(*i) + 0x9e3779b9 + (seed << 6) + (seed >> 2); |
185 | } |
186 | |
187 | return seed; |
188 | } |
189 | |
190 | }} //namespace boost::uuids |
191 | |
192 | #ifndef BOOST_UUID_NO_TYPE_TRAITS |
193 | // type traits specializations |
194 | namespace boost { |
195 | |
196 | template <> |
197 | struct is_pod<uuids::uuid> : true_type {}; |
198 | |
199 | } // namespace boost |
200 | #endif |
201 | |
202 | #if defined(BOOST_UUID_USE_SSE2) |
203 | #include <boost/uuid/detail/uuid_x86.hpp> |
204 | #else |
205 | #include <boost/uuid/detail/uuid_generic.hpp> |
206 | #endif |
207 | |
208 | #if defined(_MSC_VER) |
209 | #pragma warning(pop) // Restore warnings to previous state. |
210 | #endif |
211 | |
212 | #endif // BOOST_UUID_HPP |
213 | |