File indexing completed on 2025-09-17 08:52:46
0001 #ifndef BOOST_UUID_UUID_HPP_INCLUDED
0002 #define BOOST_UUID_UUID_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/uuid/uuid_clock.hpp>
0010 #include <boost/uuid/detail/endian.hpp>
0011 #include <boost/uuid/detail/hash_mix.hpp>
0012 #include <boost/uuid/detail/config.hpp>
0013 #include <boost/type_traits/integral_constant.hpp> // for Serialization support
0014 #include <boost/config.hpp>
0015 #include <boost/config/workaround.hpp>
0016 #include <array>
0017 #include <chrono>
0018 #include <typeindex> // cheapest std::hash
0019 #include <cstddef>
0020 #include <cstdint>
0021 #include <cstring>
0022
0023 #if defined(__has_builtin)
0024 # if __has_builtin(__builtin_is_constant_evaluated)
0025 # define BOOST_UUID_HAS_BUILTIN_ISCONSTEVAL
0026 # endif
0027 #endif
0028
0029 #if !defined(BOOST_UUID_HAS_BUILTIN_ISCONSTEVAL) && defined(BOOST_MSVC) && BOOST_MSVC >= 1925
0030 # define BOOST_UUID_HAS_BUILTIN_ISCONSTEVAL
0031 #endif
0032
0033 #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L && defined(__has_include)
0034 # if __has_include(<compare>)
0035 # include <compare>
0036 # if defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
0037 # define BOOST_UUID_HAS_THREE_WAY_COMPARISON __cpp_lib_three_way_comparison
0038 # elif defined(_LIBCPP_VERSION)
0039
0040 # define BOOST_UUID_HAS_THREE_WAY_COMPARISON _LIBCPP_VERSION
0041 # endif
0042 # endif
0043 #endif
0044
0045 namespace boost {
0046 namespace uuids {
0047
0048 struct uuid
0049 {
0050 private:
0051
0052 using repr_type = std::uint8_t[ 16 ];
0053
0054 struct data_type
0055 {
0056 private:
0057
0058 union
0059 {
0060 #if BOOST_WORKAROUND(BOOST_MSVC, < 1950)
0061
0062 std::uint8_t repr_[ 16 ] = {};
0063
0064 #else
0065
0066 std::uint8_t repr_[ 16 ];
0067
0068 #endif
0069
0070 #if !defined(BOOST_UUID_DISABLE_ALIGNMENT)
0071
0072 std::uint64_t align_u64_;
0073
0074 #endif
0075 };
0076
0077 public:
0078
0079 BOOST_CXX14_CONSTEXPR operator repr_type& () noexcept { return repr_; }
0080 constexpr operator repr_type const& () const noexcept { return repr_; }
0081
0082 BOOST_CXX14_CONSTEXPR std::uint8_t* operator()() noexcept { return repr_; }
0083 constexpr std::uint8_t const* operator()() const noexcept { return repr_; }
0084
0085 #if BOOST_WORKAROUND(BOOST_MSVC, < 1930)
0086
0087 BOOST_CXX14_CONSTEXPR std::uint8_t* operator+( std::ptrdiff_t i ) noexcept { return repr_ + i; }
0088 constexpr std::uint8_t const* operator+( std::ptrdiff_t i ) const noexcept { return repr_ + i; }
0089
0090 BOOST_CXX14_CONSTEXPR std::uint8_t& operator[]( std::ptrdiff_t i ) noexcept { return repr_[ i ]; }
0091 constexpr std::uint8_t const& operator[]( std::ptrdiff_t i ) const noexcept { return repr_[ i ]; }
0092
0093 #endif
0094 };
0095
0096 public:
0097
0098
0099
0100 #if BOOST_WORKAROUND(BOOST_MSVC, < 1950)
0101
0102 data_type data;
0103
0104 #else
0105
0106 data_type data = {};
0107
0108 #endif
0109
0110 public:
0111
0112
0113
0114 uuid() = default;
0115
0116 #if defined(BOOST_NO_CXX14_CONSTEXPR)
0117
0118 uuid( repr_type const& r ) noexcept
0119 {
0120 std::memcpy( data, r, 16 );
0121 }
0122
0123 #elif defined(BOOST_UUID_HAS_BUILTIN_ISCONSTEVAL)
0124
0125 constexpr uuid( repr_type const& r ) noexcept
0126 {
0127 if( __builtin_is_constant_evaluated() )
0128 {
0129 for( int i = 0; i < 16; ++i ) data[ i ] = r[ i ];
0130 }
0131 else
0132 {
0133 std::memcpy( data, r, 16 );
0134 }
0135 }
0136
0137 #else
0138
0139 constexpr uuid( repr_type const& r ) noexcept
0140 {
0141 for( int i = 0; i < 16; ++i ) data[ i ] = r[ i ];
0142 }
0143
0144 #endif
0145
0146
0147
0148 using value_type = std::uint8_t;
0149 using reference = std::uint8_t&;
0150 using const_reference = std::uint8_t const&;
0151 using iterator = std::uint8_t*;
0152 using const_iterator = std::uint8_t const*;
0153 using size_type = std::size_t;
0154 using difference_type = std::ptrdiff_t;
0155
0156 iterator begin() noexcept { return data; }
0157 const_iterator begin() const noexcept { return data; }
0158
0159 iterator end() noexcept { return data() + size(); }
0160 const_iterator end() const noexcept { return data() + size(); }
0161
0162
0163
0164 constexpr size_type size() const noexcept { return static_size(); }
0165
0166
0167
0168
0169
0170 static constexpr size_type static_size() noexcept { return 16; }
0171
0172
0173
0174 bool is_nil() const noexcept;
0175
0176
0177
0178 enum variant_type
0179 {
0180 variant_ncs,
0181 variant_rfc_4122,
0182 variant_microsoft,
0183 variant_future
0184 };
0185
0186 variant_type variant() const noexcept
0187 {
0188
0189
0190 unsigned char octet7 = data[8];
0191 if ( (octet7 & 0x80) == 0x00 ) {
0192 return variant_ncs;
0193 } else if ( (octet7 & 0xC0) == 0x80 ) {
0194 return variant_rfc_4122;
0195 } else if ( (octet7 & 0xE0) == 0xC0 ) {
0196 return variant_microsoft;
0197 } else {
0198
0199 return variant_future;
0200 }
0201 }
0202
0203
0204
0205 enum version_type
0206 {
0207 version_unknown = -1,
0208 version_time_based = 1,
0209 version_dce_security = 2,
0210 version_name_based_md5 = 3,
0211 version_random_number_based = 4,
0212 version_name_based_sha1 = 5,
0213 version_time_based_v6 = 6,
0214 version_time_based_v7 = 7,
0215 version_custom_v8 = 8
0216 };
0217
0218 version_type version() const noexcept
0219 {
0220
0221
0222 std::uint8_t octet9 = data[6];
0223 if ( (octet9 & 0xF0) == 0x10 ) {
0224 return version_time_based;
0225 } else if ( (octet9 & 0xF0) == 0x20 ) {
0226 return version_dce_security;
0227 } else if ( (octet9 & 0xF0) == 0x30 ) {
0228 return version_name_based_md5;
0229 } else if ( (octet9 & 0xF0) == 0x40 ) {
0230 return version_random_number_based;
0231 } else if ( (octet9 & 0xF0) == 0x50 ) {
0232 return version_name_based_sha1;
0233 } else if ( (octet9 & 0xF0) == 0x60 ) {
0234 return version_time_based_v6;
0235 } else if ( (octet9 & 0xF0) == 0x70 ) {
0236 return version_time_based_v7;
0237 } else if ( (octet9 & 0xF0) == 0x80 ) {
0238 return version_custom_v8;
0239 } else {
0240 return version_unknown;
0241 }
0242 }
0243
0244
0245
0246 using timestamp_type = std::uint64_t;
0247
0248 timestamp_type timestamp_v1() const noexcept
0249 {
0250 std::uint32_t time_low = detail::load_big_u32( this->data + 0 );
0251 std::uint16_t time_mid = detail::load_big_u16( this->data + 4 );
0252 std::uint16_t time_hi = detail::load_big_u16( this->data + 6 ) & 0x0FFF;
0253
0254 return time_low | static_cast<std::uint64_t>( time_mid ) << 32 | static_cast<std::uint64_t>( time_hi ) << 48;
0255 }
0256
0257 timestamp_type timestamp_v6() const noexcept
0258 {
0259 std::uint32_t time_high = detail::load_big_u32( this->data + 0 );
0260 std::uint16_t time_mid = detail::load_big_u16( this->data + 4 );
0261 std::uint16_t time_low = detail::load_big_u16( this->data + 6 ) & 0x0FFF;
0262
0263 return time_low | static_cast<std::uint64_t>( time_mid ) << 12 | static_cast<std::uint64_t>( time_high ) << 28;
0264 }
0265
0266 timestamp_type timestamp_v7() const noexcept
0267 {
0268 std::uint64_t time_and_version = detail::load_big_u64( this->data + 0 );
0269 return time_and_version >> 16;
0270 }
0271
0272
0273
0274 uuid_clock::time_point time_point_v1() const noexcept
0275 {
0276 return uuid_clock::from_timestamp( timestamp_v1() );
0277 }
0278
0279 uuid_clock::time_point time_point_v6() const noexcept
0280 {
0281 return uuid_clock::from_timestamp( timestamp_v6() );
0282 }
0283
0284 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> time_point_v7() const noexcept
0285 {
0286 return std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>( std::chrono::milliseconds( timestamp_v7() ) );
0287 }
0288
0289
0290
0291 using clock_seq_type = std::uint16_t;
0292
0293 clock_seq_type clock_seq() const noexcept
0294 {
0295 return detail::load_big_u16( this->data + 8 ) & 0x3FFF;
0296 }
0297
0298
0299
0300 using node_type = std::array<std::uint8_t, 6>;
0301
0302 node_type node_identifier() const noexcept
0303 {
0304 node_type node = {{}};
0305
0306 std::memcpy( node.data(), this->data + 10, 6 );
0307 return node;
0308 }
0309
0310
0311
0312 void swap( uuid& rhs ) noexcept;
0313 };
0314
0315
0316
0317 inline bool operator==( uuid const& lhs, uuid const& rhs ) noexcept;
0318 inline bool operator< ( uuid const& lhs, uuid const& rhs ) noexcept;
0319
0320 inline bool operator!=( uuid const& lhs, uuid const& rhs ) noexcept
0321 {
0322 return !(lhs == rhs);
0323 }
0324
0325 inline bool operator>( uuid const& lhs, uuid const& rhs ) noexcept
0326 {
0327 return rhs < lhs;
0328 }
0329 inline bool operator<=( uuid const& lhs, uuid const& rhs ) noexcept
0330 {
0331 return !(rhs < lhs);
0332 }
0333
0334 inline bool operator>=( uuid const& lhs, uuid const& rhs ) noexcept
0335 {
0336 return !(lhs < rhs);
0337 }
0338
0339 #if defined(BOOST_UUID_HAS_THREE_WAY_COMPARISON)
0340
0341 inline std::strong_ordering operator<=>( uuid const& lhs, uuid const& rhs ) noexcept;
0342
0343 #endif
0344
0345
0346
0347 inline void swap( uuid& lhs, uuid& rhs ) noexcept
0348 {
0349 lhs.swap( rhs );
0350 }
0351
0352
0353
0354 inline std::size_t hash_value( uuid const& u ) noexcept
0355 {
0356 std::uint64_t r = 0;
0357
0358 r = detail::hash_mix_mx( r + detail::load_little_u32( u.data + 0 ) );
0359 r = detail::hash_mix_mx( r + detail::load_little_u32( u.data + 4 ) );
0360 r = detail::hash_mix_mx( r + detail::load_little_u32( u.data + 8 ) );
0361 r = detail::hash_mix_mx( r + detail::load_little_u32( u.data + 12 ) );
0362
0363 return static_cast<std::size_t>( detail::hash_mix_fmx( r ) );
0364 }
0365
0366 }}
0367
0368
0369
0370
0371
0372 namespace boost
0373 {
0374 namespace serialization
0375 {
0376
0377 template<class T> struct implementation_level_impl;
0378 template<> struct implementation_level_impl<const uuids::uuid>: boost::integral_constant<int, 1> {};
0379
0380 }
0381 }
0382
0383
0384
0385 namespace std
0386 {
0387
0388 template<> struct hash<boost::uuids::uuid>
0389 {
0390 std::size_t operator()( boost::uuids::uuid const& value ) const noexcept
0391 {
0392 return boost::uuids::hash_value( value );
0393 }
0394 };
0395
0396 }
0397
0398 #if defined(BOOST_UUID_USE_SSE2)
0399 # include <boost/uuid/detail/uuid_x86.ipp>
0400 #elif defined(__SIZEOF_INT128__)
0401 # include <boost/uuid/detail/uuid_uint128.ipp>
0402 #else
0403 # include <boost/uuid/detail/uuid_generic.ipp>
0404 #endif
0405
0406 #endif