Back to home page

EIC code displayed by LXR

 
 

    


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 // Copyright 2006 Andy Tompkins
0005 // Copyright 2024 Peter Dimov
0006 // Distributed under the Boost Software License, Version 1.0.
0007 // https://www.boost.org/LICENSE_1_0.txt
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 //  https://github.com/llvm/llvm-project/issues/73953
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     // data
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     // constructors
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     // iteration
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     // size
0163 
0164     constexpr size_type size() const noexcept { return static_size(); }
0165 
0166     // This does not work on some compilers
0167     // They seem to want the variable defined in
0168     // a cpp file
0169     //BOOST_STATIC_CONSTANT(size_type, static_size = 16);
0170     static constexpr size_type static_size() noexcept { return 16; }
0171 
0172     // is_nil
0173 
0174     bool is_nil() const noexcept;
0175 
0176     // variant
0177 
0178     enum variant_type
0179     {
0180         variant_ncs, // NCS backward compatibility
0181         variant_rfc_4122, // defined in RFC 4122 document
0182         variant_microsoft, // Microsoft Corporation backward compatibility
0183         variant_future // future definition
0184     };
0185 
0186     variant_type variant() const noexcept
0187     {
0188         // variant is stored in octet 7
0189         // which is index 8, since indexes count backwards
0190         unsigned char octet7 = data[8]; // octet 7 is array index 8
0191         if ( (octet7 & 0x80) == 0x00 ) { // 0b0xxxxxxx
0192             return variant_ncs;
0193         } else if ( (octet7 & 0xC0) == 0x80 ) { // 0b10xxxxxx
0194             return variant_rfc_4122;
0195         } else if ( (octet7 & 0xE0) == 0xC0 ) { // 0b110xxxxx
0196             return variant_microsoft;
0197         } else {
0198             //assert( (octet7 & 0xE0) == 0xE0 ) // 0b111xxxx
0199             return variant_future;
0200         }
0201     }
0202 
0203     // version
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         // version is stored in octet 9
0221         // which is index 6, since indexes count backwards
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     // timestamp
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     // time_point
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     // clock_seq
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     // node_identifier
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     // swap
0311 
0312     void swap( uuid& rhs ) noexcept;
0313 };
0314 
0315 // operators
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 // swap
0346 
0347 inline void swap( uuid& lhs, uuid& rhs ) noexcept
0348 {
0349     lhs.swap( rhs );
0350 }
0351 
0352 // hash_value
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 }} //namespace boost::uuids
0367 
0368 // Boost.Serialization support
0369 
0370 // BOOST_CLASS_IMPLEMENTATION(boost::uuids::uuid, boost::serialization::primitive_type)
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 } // namespace serialization
0381 } // namespace boost
0382 
0383 // std::hash support
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 } // namespace std
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 // BOOST_UUID_UUID_HPP_INCLUDED