uuid.hpp 6.4 KB

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