uuid.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. // http://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. #ifndef BOOST_UUID_HPP
  30. #define BOOST_UUID_HPP
  31. #include <boost/config.hpp>
  32. #include <stddef.h>
  33. #include <boost/cstdint.hpp>
  34. #include <algorithm>
  35. #include <boost/config.hpp> // for static assert
  36. #ifndef BOOST_UUID_NO_TYPE_TRAITS
  37. #include <boost/type_traits/is_pod.hpp>
  38. #include <boost/type_traits/integral_constant.hpp>
  39. #endif
  40. #if defined(_MSC_VER)
  41. #pragma warning(push) // Save warning settings.
  42. #pragma warning(disable : 4996) // Disable deprecated std::swap_ranges, std::equal
  43. #endif
  44. #ifdef BOOST_NO_STDC_NAMESPACE
  45. namespace std {
  46. using ::size_t;
  47. using ::ptrdiff_t;
  48. } //namespace std
  49. #endif //BOOST_NO_STDC_NAMESPACE
  50. namespace boost {
  51. namespace uuids {
  52. struct uuid
  53. {
  54. public:
  55. typedef uint8_t value_type;
  56. typedef uint8_t& reference;
  57. typedef uint8_t const& const_reference;
  58. typedef uint8_t* iterator;
  59. typedef uint8_t const* const_iterator;
  60. typedef std::size_t size_type;
  61. typedef std::ptrdiff_t difference_type;
  62. // This does not work on some compilers
  63. // They seem to want the variable definec in
  64. // a cpp file
  65. //BOOST_STATIC_CONSTANT(size_type, static_size = 16);
  66. static size_type static_size() { return 16; }
  67. public:
  68. iterator begin() { return data; } /* throw() */
  69. const_iterator begin() const { return data; } /* throw() */
  70. iterator end() { return data+size(); } /* throw() */
  71. const_iterator end() const { return data+size(); } /* throw() */
  72. size_type size() const { return static_size(); } /* throw() */
  73. bool is_nil() const /* throw() */
  74. {
  75. for(size_t i=0; i<static_size(); i++) {
  76. if (data[i] != 0U) {
  77. return false;
  78. }
  79. }
  80. return true;
  81. }
  82. enum variant_type
  83. {
  84. variant_ncs, // NCS backward compatibility
  85. variant_rfc_4122, // defined in RFC 4122 document
  86. variant_microsoft, // Microsoft Corporation backward compatibility
  87. variant_future // future definition
  88. };
  89. variant_type variant() const /* throw() */
  90. {
  91. // variant is stored in octet 7
  92. // which is index 8, since indexes count backwards
  93. unsigned char octet7 = data[8]; // octet 7 is array index 8
  94. if ( (octet7 & 0x80) == 0x00 ) { // 0b0xxxxxxx
  95. return variant_ncs;
  96. } else if ( (octet7 & 0xC0) == 0x80 ) { // 0b10xxxxxx
  97. return variant_rfc_4122;
  98. } else if ( (octet7 & 0xE0) == 0xC0 ) { // 0b110xxxxx
  99. return variant_microsoft;
  100. } else {
  101. //assert( (octet7 & 0xE0) == 0xE0 ) // 0b111xxxx
  102. return variant_future;
  103. }
  104. }
  105. enum version_type
  106. {
  107. version_unknown = -1,
  108. version_time_based = 1,
  109. version_dce_security = 2,
  110. version_name_based_md5 = 3,
  111. version_random_number_based = 4,
  112. version_name_based_sha1 = 5
  113. };
  114. version_type version() const /* throw() */
  115. {
  116. //version is stored in octet 9
  117. // which is index 6, since indexes count backwards
  118. unsigned char octet9 = data[6];
  119. if ( (octet9 & 0xF0) == 0x10 ) {
  120. return version_time_based;
  121. } else if ( (octet9 & 0xF0) == 0x20 ) {
  122. return version_dce_security;
  123. } else if ( (octet9 & 0xF0) == 0x30 ) {
  124. return version_name_based_md5;
  125. } else if ( (octet9 & 0xF0) == 0x40 ) {
  126. return version_random_number_based;
  127. } else if ( (octet9 & 0xF0) == 0x50 ) {
  128. return version_name_based_sha1;
  129. } else {
  130. return version_unknown;
  131. }
  132. }
  133. // note: linear complexity
  134. void swap(uuid& rhs) /* throw() */
  135. {
  136. std::swap_ranges(begin(), end(), rhs.begin());
  137. }
  138. public:
  139. // or should it be array<uint8_t, 16>
  140. uint8_t data[16];
  141. };
  142. inline bool operator==(uuid const& lhs, uuid const& rhs) /* throw() */
  143. {
  144. return std::equal(lhs.begin(), lhs.end(), rhs.begin());
  145. }
  146. inline bool operator!=(uuid const& lhs, uuid const& rhs) /* throw() */
  147. {
  148. return !(lhs == rhs);
  149. }
  150. inline bool operator<(uuid const& lhs, uuid const& rhs) /* throw() */
  151. {
  152. return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
  153. }
  154. inline bool operator>(uuid const& lhs, uuid const& rhs) /* throw() */
  155. {
  156. return rhs < lhs;
  157. }
  158. inline bool operator<=(uuid const& lhs, uuid const& rhs) /* throw() */
  159. {
  160. return !(rhs < lhs);
  161. }
  162. inline bool operator>=(uuid const& lhs, uuid const& rhs) /* throw() */
  163. {
  164. return !(lhs < rhs);
  165. }
  166. inline void swap(uuid& lhs, uuid& rhs) /* throw() */
  167. {
  168. lhs.swap(rhs);
  169. }
  170. // This is equivalent to boost::hash_range(u.begin(), u.end());
  171. inline std::size_t hash_value(uuid const& u) /* throw() */
  172. {
  173. std::size_t seed = 0;
  174. for(uuid::const_iterator i=u.begin(); i != u.end(); ++i)
  175. {
  176. seed ^= static_cast<std::size_t>(*i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
  177. }
  178. return seed;
  179. }
  180. }} //namespace boost::uuids
  181. #ifndef BOOST_UUID_NO_TYPE_TRAITS
  182. // type traits specializations
  183. namespace boost {
  184. template <>
  185. struct is_pod<uuids::uuid> : true_type {};
  186. } // namespace boost
  187. #endif
  188. #if defined(_MSC_VER)
  189. #pragma warning(pop) // Restore warnings to previous state.
  190. #endif
  191. #endif // BOOST_UUID_HPP