123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- #ifndef BOOST_UUID_UUID_HPP_INCLUDED
- #define BOOST_UUID_UUID_HPP_INCLUDED
- // Copyright 2006 Andy Tompkins
- // Copyright 2024 Peter Dimov
- // Distributed under the Boost Software License, Version 1.0.
- // https://www.boost.org/LICENSE_1_0.txt
- #include <boost/uuid/uuid_clock.hpp>
- #include <boost/uuid/detail/endian.hpp>
- #include <boost/uuid/detail/hash_mix.hpp>
- #include <boost/uuid/detail/config.hpp>
- #include <boost/type_traits/integral_constant.hpp> // for Serialization support
- #include <boost/config.hpp>
- #include <boost/config/workaround.hpp>
- #include <array>
- #include <chrono>
- #include <typeindex> // cheapest std::hash
- #include <cstddef>
- #include <cstdint>
- #include <cstring>
- #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L && defined(__has_include)
- # if __has_include(<compare>)
- # include <compare>
- # if defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
- # define BOOST_UUID_HAS_THREE_WAY_COMPARISON __cpp_lib_three_way_comparison
- # elif defined(_LIBCPP_VERSION)
- // https://github.com/llvm/llvm-project/issues/73953
- # define BOOST_UUID_HAS_THREE_WAY_COMPARISON _LIBCPP_VERSION
- # endif
- # endif
- #endif
- namespace boost {
- namespace uuids {
- struct uuid
- {
- private:
- using repr_type = std::uint8_t[ 16 ];
- struct data_type
- {
- private:
- union
- {
- #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
- std::uint8_t repr_[ 16 ] = {};
- #else
- std::uint8_t repr_[ 16 ];
- #endif
- #if !defined(BOOST_UUID_DISABLE_ALIGNMENT)
- std::uint64_t align_u64_;
- #endif
- };
- public:
- operator repr_type& () noexcept { return repr_; }
- operator repr_type const& () const noexcept { return repr_; }
- std::uint8_t* operator()() noexcept { return repr_; }
- std::uint8_t const* operator()() const noexcept { return repr_; }
- #if BOOST_WORKAROUND(BOOST_MSVC, < 1930)
- std::uint8_t* operator+( std::ptrdiff_t i ) noexcept { return repr_ + i; }
- std::uint8_t const* operator+( std::ptrdiff_t i ) const noexcept { return repr_ + i; }
- std::uint8_t& operator[]( std::ptrdiff_t i ) noexcept { return repr_[ i ]; }
- std::uint8_t const& operator[]( std::ptrdiff_t i ) const noexcept { return repr_[ i ]; }
- #endif
- };
- public:
- // data
- #if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
- data_type data;
- #else
- data_type data = {};
- #endif
- public:
- // constructors
- uuid() = default;
- uuid( repr_type const& r )
- {
- std::memcpy( data, r, 16 );
- }
- // iteration
- using value_type = std::uint8_t;
- using reference = std::uint8_t&;
- using const_reference = std::uint8_t const&;
- using iterator = std::uint8_t*;
- using const_iterator = std::uint8_t const*;
- using size_type = std::size_t;
- using difference_type = std::ptrdiff_t;
- iterator begin() noexcept { return data; }
- const_iterator begin() const noexcept { return data; }
- iterator end() noexcept { return data + size(); }
- const_iterator end() const noexcept { return data + size(); }
- // size
- constexpr size_type size() const noexcept { return static_size(); }
- // This does not work on some compilers
- // They seem to want the variable defined in
- // a cpp file
- //BOOST_STATIC_CONSTANT(size_type, static_size = 16);
- static constexpr size_type static_size() noexcept { return 16; }
- // is_nil
- bool is_nil() const noexcept;
- // variant
- enum variant_type
- {
- variant_ncs, // NCS backward compatibility
- variant_rfc_4122, // defined in RFC 4122 document
- variant_microsoft, // Microsoft Corporation backward compatibility
- variant_future // future definition
- };
- variant_type variant() const noexcept
- {
- // variant is stored in octet 7
- // which is index 8, since indexes count backwards
- unsigned char octet7 = data[8]; // octet 7 is array index 8
- if ( (octet7 & 0x80) == 0x00 ) { // 0b0xxxxxxx
- return variant_ncs;
- } else if ( (octet7 & 0xC0) == 0x80 ) { // 0b10xxxxxx
- return variant_rfc_4122;
- } else if ( (octet7 & 0xE0) == 0xC0 ) { // 0b110xxxxx
- return variant_microsoft;
- } else {
- //assert( (octet7 & 0xE0) == 0xE0 ) // 0b111xxxx
- return variant_future;
- }
- }
- // version
- enum version_type
- {
- version_unknown = -1,
- version_time_based = 1,
- version_dce_security = 2,
- version_name_based_md5 = 3,
- version_random_number_based = 4,
- version_name_based_sha1 = 5,
- version_time_based_v6 = 6,
- version_time_based_v7 = 7,
- version_custom_v8 = 8
- };
- version_type version() const noexcept
- {
- // version is stored in octet 9
- // which is index 6, since indexes count backwards
- std::uint8_t octet9 = data[6];
- if ( (octet9 & 0xF0) == 0x10 ) {
- return version_time_based;
- } else if ( (octet9 & 0xF0) == 0x20 ) {
- return version_dce_security;
- } else if ( (octet9 & 0xF0) == 0x30 ) {
- return version_name_based_md5;
- } else if ( (octet9 & 0xF0) == 0x40 ) {
- return version_random_number_based;
- } else if ( (octet9 & 0xF0) == 0x50 ) {
- return version_name_based_sha1;
- } else if ( (octet9 & 0xF0) == 0x60 ) {
- return version_time_based_v6;
- } else if ( (octet9 & 0xF0) == 0x70 ) {
- return version_time_based_v7;
- } else if ( (octet9 & 0xF0) == 0x80 ) {
- return version_custom_v8;
- } else {
- return version_unknown;
- }
- }
- // timestamp
- using timestamp_type = std::uint64_t;
- timestamp_type timestamp_v1() const noexcept
- {
- std::uint32_t time_low = detail::load_big_u32( this->data + 0 );
- std::uint16_t time_mid = detail::load_big_u16( this->data + 4 );
- std::uint16_t time_hi = detail::load_big_u16( this->data + 6 ) & 0x0FFF;
- return time_low | static_cast<std::uint64_t>( time_mid ) << 32 | static_cast<std::uint64_t>( time_hi ) << 48;
- }
- timestamp_type timestamp_v6() const noexcept
- {
- std::uint32_t time_high = detail::load_big_u32( this->data + 0 );
- std::uint16_t time_mid = detail::load_big_u16( this->data + 4 );
- std::uint16_t time_low = detail::load_big_u16( this->data + 6 ) & 0x0FFF;
- return time_low | static_cast<std::uint64_t>( time_mid ) << 12 | static_cast<std::uint64_t>( time_high ) << 28;
- }
- timestamp_type timestamp_v7() const noexcept
- {
- std::uint64_t time_and_version = detail::load_big_u64( this->data + 0 );
- return time_and_version >> 16;
- }
- // time_point
- uuid_clock::time_point time_point_v1() const noexcept
- {
- return uuid_clock::from_timestamp( timestamp_v1() );
- }
- uuid_clock::time_point time_point_v6() const noexcept
- {
- return uuid_clock::from_timestamp( timestamp_v6() );
- }
- std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> time_point_v7() const noexcept
- {
- return std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>( std::chrono::milliseconds( timestamp_v7() ) );
- }
- // clock_seq
- using clock_seq_type = std::uint16_t;
- clock_seq_type clock_seq() const noexcept
- {
- return detail::load_big_u16( this->data + 8 ) & 0x3FFF;
- }
- // node_identifier
- using node_type = std::array<std::uint8_t, 6>;
- node_type node_identifier() const noexcept
- {
- node_type node = {};
- std::memcpy( node.data(), this->data + 10, 6 );
- return node;
- }
- // swap
- void swap( uuid& rhs ) noexcept;
- };
- // operators
- inline bool operator==( uuid const& lhs, uuid const& rhs ) noexcept;
- inline bool operator< ( uuid const& lhs, uuid const& rhs ) noexcept;
- inline bool operator!=( uuid const& lhs, uuid const& rhs ) noexcept
- {
- return !(lhs == rhs);
- }
- inline bool operator>( uuid const& lhs, uuid const& rhs ) noexcept
- {
- return rhs < lhs;
- }
- inline bool operator<=( uuid const& lhs, uuid const& rhs ) noexcept
- {
- return !(rhs < lhs);
- }
- inline bool operator>=( uuid const& lhs, uuid const& rhs ) noexcept
- {
- return !(lhs < rhs);
- }
- #if defined(BOOST_UUID_HAS_THREE_WAY_COMPARISON)
- inline std::strong_ordering operator<=>( uuid const& lhs, uuid const& rhs ) noexcept;
- #endif
- // swap
- inline void swap( uuid& lhs, uuid& rhs ) noexcept
- {
- lhs.swap( rhs );
- }
- // hash_value
- inline std::size_t hash_value( uuid const& u ) noexcept
- {
- std::uint64_t r = 0;
- r = detail::hash_mix_mx( r + detail::load_little_u32( u.data + 0 ) );
- r = detail::hash_mix_mx( r + detail::load_little_u32( u.data + 4 ) );
- r = detail::hash_mix_mx( r + detail::load_little_u32( u.data + 8 ) );
- r = detail::hash_mix_mx( r + detail::load_little_u32( u.data + 12 ) );
- return static_cast<std::size_t>( detail::hash_mix_fmx( r ) );
- }
- }} //namespace boost::uuids
- // Boost.Serialization support
- // BOOST_CLASS_IMPLEMENTATION(boost::uuids::uuid, boost::serialization::primitive_type)
- namespace boost
- {
- namespace serialization
- {
- template<class T> struct implementation_level_impl;
- template<> struct implementation_level_impl<const uuids::uuid>: boost::integral_constant<int, 1> {};
- } // namespace serialization
- } // namespace boost
- // std::hash support
- namespace std
- {
- template<> struct hash<boost::uuids::uuid>
- {
- std::size_t operator()( boost::uuids::uuid const& value ) const noexcept
- {
- return boost::uuids::hash_value( value );
- }
- };
- } // namespace std
- #if defined(BOOST_UUID_USE_SSE2)
- # include <boost/uuid/detail/uuid_x86.ipp>
- #elif defined(__SIZEOF_INT128__)
- # include <boost/uuid/detail/uuid_uint128.ipp>
- #else
- # include <boost/uuid/detail/uuid_generic.ipp>
- #endif
- #endif // BOOST_UUID_UUID_HPP_INCLUDED
|