Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-05 08:50:32

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(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L && defined(__has_include)
0024 # if __has_include(<compare>)
0025 #  include <compare>
0026 #  if defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
0027 #   define BOOST_UUID_HAS_THREE_WAY_COMPARISON __cpp_lib_three_way_comparison
0028 #  elif defined(_LIBCPP_VERSION)
0029 //  https://github.com/llvm/llvm-project/issues/73953
0030 #   define BOOST_UUID_HAS_THREE_WAY_COMPARISON _LIBCPP_VERSION
0031 #  endif
0032 # endif
0033 #endif
0034 
0035 namespace boost {
0036 namespace uuids {
0037 
0038 struct uuid
0039 {
0040 private:
0041 
0042     using repr_type = std::uint8_t[ 16 ];
0043 
0044     struct data_type
0045     {
0046     private:
0047 
0048         union
0049         {
0050 #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
0051 
0052             std::uint8_t repr_[ 16 ] = {};
0053 
0054 #else
0055 
0056             std::uint8_t repr_[ 16 ];
0057 
0058 #endif
0059 
0060 #if !defined(BOOST_UUID_DISABLE_ALIGNMENT)
0061 
0062             std::uint64_t align_u64_;
0063 
0064 #endif
0065         };
0066 
0067     public:
0068 
0069         operator repr_type& () noexcept { return repr_; }
0070         operator repr_type const& () const noexcept { return repr_; }
0071 
0072         std::uint8_t* operator()() noexcept { return repr_; }
0073         std::uint8_t const* operator()() const noexcept { return repr_; }
0074 
0075 #if BOOST_WORKAROUND(BOOST_MSVC, < 1930)
0076 
0077         std::uint8_t* operator+( std::ptrdiff_t i ) noexcept { return repr_ + i; }
0078         std::uint8_t const* operator+( std::ptrdiff_t i ) const noexcept { return repr_ + i; }
0079 
0080         std::uint8_t& operator[]( std::ptrdiff_t i ) noexcept { return repr_[ i ]; }
0081         std::uint8_t const& operator[]( std::ptrdiff_t i ) const noexcept { return repr_[ i ]; }
0082 
0083 #endif
0084     };
0085 
0086 public:
0087 
0088     // data
0089 
0090 #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
0091 
0092     data_type data;
0093 
0094 #else
0095 
0096     data_type data = {};
0097 
0098 #endif
0099 
0100 public:
0101 
0102     // constructors
0103 
0104     uuid() = default;
0105 
0106     uuid( repr_type const& r )
0107     {
0108         std::memcpy( data, r, 16 );
0109     }
0110 
0111     // iteration
0112 
0113     using value_type = std::uint8_t;
0114     using reference = std::uint8_t&;
0115     using const_reference = std::uint8_t const&;
0116     using iterator = std::uint8_t*;
0117     using const_iterator = std::uint8_t const*;
0118     using size_type = std::size_t;
0119     using difference_type = std::ptrdiff_t;
0120 
0121     iterator begin() noexcept { return data; }
0122     const_iterator begin() const noexcept { return data; }
0123 
0124     iterator end() noexcept { return data + size(); }
0125     const_iterator end() const noexcept { return data + size(); }
0126 
0127     // size
0128 
0129     constexpr size_type size() const noexcept { return static_size(); }
0130 
0131     // This does not work on some compilers
0132     // They seem to want the variable defined in
0133     // a cpp file
0134     //BOOST_STATIC_CONSTANT(size_type, static_size = 16);
0135     static constexpr size_type static_size() noexcept { return 16; }
0136 
0137     // is_nil
0138 
0139     bool is_nil() const noexcept;
0140 
0141     // variant
0142 
0143     enum variant_type
0144     {
0145         variant_ncs, // NCS backward compatibility
0146         variant_rfc_4122, // defined in RFC 4122 document
0147         variant_microsoft, // Microsoft Corporation backward compatibility
0148         variant_future // future definition
0149     };
0150 
0151     variant_type variant() const noexcept
0152     {
0153         // variant is stored in octet 7
0154         // which is index 8, since indexes count backwards
0155         unsigned char octet7 = data[8]; // octet 7 is array index 8
0156         if ( (octet7 & 0x80) == 0x00 ) { // 0b0xxxxxxx
0157             return variant_ncs;
0158         } else if ( (octet7 & 0xC0) == 0x80 ) { // 0b10xxxxxx
0159             return variant_rfc_4122;
0160         } else if ( (octet7 & 0xE0) == 0xC0 ) { // 0b110xxxxx
0161             return variant_microsoft;
0162         } else {
0163             //assert( (octet7 & 0xE0) == 0xE0 ) // 0b111xxxx
0164             return variant_future;
0165         }
0166     }
0167 
0168     // version
0169 
0170     enum version_type
0171     {
0172         version_unknown = -1,
0173         version_time_based = 1,
0174         version_dce_security = 2,
0175         version_name_based_md5 = 3,
0176         version_random_number_based = 4,
0177         version_name_based_sha1 = 5,
0178         version_time_based_v6 = 6,
0179         version_time_based_v7 = 7,
0180         version_custom_v8 = 8
0181     };
0182 
0183     version_type version() const noexcept
0184     {
0185         // version is stored in octet 9
0186         // which is index 6, since indexes count backwards
0187         std::uint8_t octet9 = data[6];
0188         if ( (octet9 & 0xF0) == 0x10 ) {
0189             return version_time_based;
0190         } else if ( (octet9 & 0xF0) == 0x20 ) {
0191             return version_dce_security;
0192         } else if ( (octet9 & 0xF0) == 0x30 ) {
0193             return version_name_based_md5;
0194         } else if ( (octet9 & 0xF0) == 0x40 ) {
0195             return version_random_number_based;
0196         } else if ( (octet9 & 0xF0) == 0x50 ) {
0197             return version_name_based_sha1;
0198         } else if ( (octet9 & 0xF0) == 0x60 ) {
0199             return version_time_based_v6;
0200         } else if ( (octet9 & 0xF0) == 0x70 ) {
0201             return version_time_based_v7;
0202         } else if ( (octet9 & 0xF0) == 0x80 ) {
0203             return version_custom_v8;
0204         } else {
0205             return version_unknown;
0206         }
0207     }
0208 
0209     // timestamp
0210 
0211     using timestamp_type = std::uint64_t;
0212 
0213     timestamp_type timestamp_v1() const noexcept
0214     {
0215         std::uint32_t time_low = detail::load_big_u32( this->data + 0 );
0216         std::uint16_t time_mid = detail::load_big_u16( this->data + 4 );
0217         std::uint16_t time_hi = detail::load_big_u16( this->data + 6 ) & 0x0FFF;
0218 
0219         return time_low | static_cast<std::uint64_t>( time_mid ) << 32 | static_cast<std::uint64_t>( time_hi ) << 48;
0220     }
0221 
0222     timestamp_type timestamp_v6() const noexcept
0223     {
0224         std::uint32_t time_high = detail::load_big_u32( this->data + 0 );
0225         std::uint16_t time_mid = detail::load_big_u16( this->data + 4 );
0226         std::uint16_t time_low = detail::load_big_u16( this->data + 6 ) & 0x0FFF;
0227 
0228         return time_low | static_cast<std::uint64_t>( time_mid ) << 12 | static_cast<std::uint64_t>( time_high ) << 28;
0229     }
0230 
0231     timestamp_type timestamp_v7() const noexcept
0232     {
0233         std::uint64_t time_and_version = detail::load_big_u64( this->data + 0 );
0234         return time_and_version >> 16;
0235     }
0236 
0237     // time_point
0238 
0239     uuid_clock::time_point time_point_v1() const noexcept
0240     {
0241         return uuid_clock::from_timestamp( timestamp_v1() );
0242     }
0243 
0244     uuid_clock::time_point time_point_v6() const noexcept
0245     {
0246         return uuid_clock::from_timestamp( timestamp_v6() );
0247     }
0248 
0249     std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> time_point_v7() const noexcept
0250     {
0251         return std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>( std::chrono::milliseconds( timestamp_v7() ) );
0252     }
0253 
0254     // clock_seq
0255 
0256     using clock_seq_type = std::uint16_t;
0257 
0258     clock_seq_type clock_seq() const noexcept
0259     {
0260         return detail::load_big_u16( this->data + 8 ) & 0x3FFF;
0261     }
0262 
0263     // node_identifier
0264 
0265     using node_type = std::array<std::uint8_t, 6>;
0266 
0267     node_type node_identifier() const noexcept
0268     {
0269         node_type node = {};
0270 
0271         std::memcpy( node.data(), this->data + 10, 6 );
0272         return node;
0273     }
0274 
0275     // swap
0276 
0277     void swap( uuid& rhs ) noexcept;
0278 };
0279 
0280 // operators
0281 
0282 inline bool operator==( uuid const& lhs, uuid const& rhs ) noexcept;
0283 inline bool operator< ( uuid const& lhs, uuid const& rhs ) noexcept;
0284 
0285 inline bool operator!=( uuid const& lhs, uuid const& rhs ) noexcept
0286 {
0287     return !(lhs == rhs);
0288 }
0289 
0290 inline bool operator>( uuid const& lhs, uuid const& rhs ) noexcept
0291 {
0292     return rhs < lhs;
0293 }
0294 inline bool operator<=( uuid const& lhs, uuid const& rhs ) noexcept
0295 {
0296     return !(rhs < lhs);
0297 }
0298 
0299 inline bool operator>=( uuid const& lhs, uuid const& rhs ) noexcept
0300 {
0301     return !(lhs < rhs);
0302 }
0303 
0304 #if defined(BOOST_UUID_HAS_THREE_WAY_COMPARISON)
0305 
0306 inline std::strong_ordering operator<=>( uuid const& lhs, uuid const& rhs ) noexcept;
0307 
0308 #endif
0309 
0310 // swap
0311 
0312 inline void swap( uuid& lhs, uuid& rhs ) noexcept
0313 {
0314     lhs.swap( rhs );
0315 }
0316 
0317 // hash_value
0318 
0319 inline std::size_t hash_value( uuid const& u ) noexcept
0320 {
0321     std::uint64_t r = 0;
0322 
0323     r = detail::hash_mix_mx( r + detail::load_little_u32( u.data +  0 ) );
0324     r = detail::hash_mix_mx( r + detail::load_little_u32( u.data +  4 ) );
0325     r = detail::hash_mix_mx( r + detail::load_little_u32( u.data +  8 ) );
0326     r = detail::hash_mix_mx( r + detail::load_little_u32( u.data + 12 ) );
0327 
0328     return static_cast<std::size_t>( detail::hash_mix_fmx( r ) );
0329 }
0330 
0331 }} //namespace boost::uuids
0332 
0333 // Boost.Serialization support
0334 
0335 // BOOST_CLASS_IMPLEMENTATION(boost::uuids::uuid, boost::serialization::primitive_type)
0336 
0337 namespace boost
0338 {
0339 namespace serialization
0340 {
0341 
0342 template<class T> struct implementation_level_impl;
0343 template<> struct implementation_level_impl<const uuids::uuid>: boost::integral_constant<int, 1> {};
0344 
0345 } // namespace serialization
0346 } // namespace boost
0347 
0348 // std::hash support
0349 
0350 namespace std
0351 {
0352 
0353 template<> struct hash<boost::uuids::uuid>
0354 {
0355     std::size_t operator()( boost::uuids::uuid const& value ) const noexcept
0356     {
0357         return boost::uuids::hash_value( value );
0358     }
0359 };
0360 
0361 } // namespace std
0362 
0363 #if defined(BOOST_UUID_USE_SSE2)
0364 # include <boost/uuid/detail/uuid_x86.ipp>
0365 #elif defined(__SIZEOF_INT128__)
0366 # include <boost/uuid/detail/uuid_uint128.ipp>
0367 #else
0368 # include <boost/uuid/detail/uuid_generic.ipp>
0369 #endif
0370 
0371 #endif // BOOST_UUID_UUID_HPP_INCLUDED