Skip to content

Commit 9fe9e26

Browse files
committed
PS-9233: UUID Boost library parts to supoort uuid_vx component
https://perconadev.atlassian.net/browse/PS-9233 UUID lib is from dev branch of upcoming version 1.86 The boost::uuid lib is from develop branch, last coomit hash 02c82ce Small fixe for the compatibility fith older boost_1_77_0 (cherry picked from commit 0592d68)
1 parent b12015e commit 9fe9e26

36 files changed

+3697
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef BOOST_UUID_HPP_INCLUDED
2+
#define BOOST_UUID_HPP_INCLUDED
3+
4+
// Copyright 2024 Peter Dimov
5+
// Distributed under the Boost Software License, Version 1.0.
6+
// https://www.boost.org/LICENSE_1_0.txt
7+
8+
#include <boost/uuid/uuid.hpp>
9+
#include <boost/uuid/uuid_io.hpp>
10+
#include <boost/uuid/uuid_generators.hpp>
11+
12+
#endif // #ifndef BOOST_UUID_HPP_INCLUDED
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef BOOST_UUID_BASIC_NAME_GENERATOR_HPP_INCLUDED
2+
#define BOOST_UUID_BASIC_NAME_GENERATOR_HPP_INCLUDED
3+
4+
// Copyright 2024 Peter Dimov
5+
// Distributed under the Boost Software License, Version 1.0.
6+
// https://www.boost.org/LICENSE_1_0.txt
7+
8+
// This header is only provided for compatibility with
9+
// Boost release 1.85 and earlier.
10+
11+
#include <boost/uuid/detail/basic_name_generator.hpp>
12+
13+
namespace boost {
14+
namespace uuids {
15+
16+
// Only provided for compatibility with 1.85
17+
using detail::basic_name_generator;
18+
19+
} // uuids
20+
} // boost
21+
22+
#endif // BOOST_UUID_BASIC_NAME_GENERATOR_HPP_INCLUDED
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#ifndef BOOST_UUID_BASIC_RANDOM_GENERATOR_HPP_INCLUDED
2+
#define BOOST_UUID_BASIC_RANDOM_GENERATOR_HPP_INCLUDED
3+
4+
// Copyright 2010 Andy Tompkins
5+
// Copyright 2017 James E. King III
6+
// Copyright 2024 Peter Dimov
7+
// Distributed under the Boost Software License, Version 1.0.
8+
// https://www.boost.org/LICENSE_1_0.txt
9+
10+
#include <boost/uuid/uuid.hpp>
11+
#include <boost/uuid/detail/random_provider.hpp>
12+
#include <boost/uuid/detail/endian.hpp>
13+
#include <boost/assert.hpp>
14+
#include <type_traits>
15+
#include <random>
16+
#include <cstdint>
17+
18+
namespace boost {
19+
namespace uuids {
20+
21+
template<class UniformRandomNumberGenerator>
22+
class basic_random_generator
23+
{
24+
private:
25+
26+
UniformRandomNumberGenerator* p_;
27+
UniformRandomNumberGenerator g_;
28+
29+
public:
30+
31+
using result_type = uuid;
32+
33+
// default constructor creates the random number generator and
34+
// if the UniformRandomNumberGenerator is a PseudoRandomNumberGenerator
35+
// then it gets seeded by a random_provider.
36+
basic_random_generator(): p_( 0 ), g_()
37+
{
38+
// seed the random number generator if it is capable
39+
seed( g_, 0 );
40+
}
41+
42+
// keep a reference to a random number generator
43+
// don't seed a given random number generator
44+
explicit basic_random_generator( UniformRandomNumberGenerator& gen ): p_( &gen )
45+
{
46+
}
47+
48+
// keep a pointer to a random number generator
49+
// don't seed a given random number generator
50+
explicit basic_random_generator( UniformRandomNumberGenerator* gen ): p_( gen )
51+
{
52+
BOOST_ASSERT( gen != 0 );
53+
}
54+
55+
result_type operator()()
56+
{
57+
UniformRandomNumberGenerator& gen = p_? *p_: g_;
58+
59+
std::uniform_int_distribution<std::uint32_t> dist;
60+
61+
result_type u;
62+
63+
detail::store_native_u32( u.data + 0, dist( gen ) );
64+
detail::store_native_u32( u.data + 4, dist( gen ) );
65+
detail::store_native_u32( u.data + 8, dist( gen ) );
66+
detail::store_native_u32( u.data + 12, dist( gen ) );
67+
68+
// set variant
69+
// must be 0b10xxxxxx
70+
*(u.begin() + 8) &= 0x3F;
71+
*(u.begin() + 8) |= 0x80;
72+
73+
// set version
74+
// must be 0b0100xxxx
75+
*(u.begin() + 6) &= 0x0F; //0b00001111
76+
*(u.begin() + 6) |= 0x40; //0b01000000
77+
78+
return u;
79+
}
80+
81+
private:
82+
83+
// Detect whether UniformRandomNumberGenerator has a seed() method which indicates that
84+
// it is a PseudoRandomNumberGenerator and needs a seed to initialize it. This allows
85+
// basic_random_generator to take any type of UniformRandomNumberGenerator and still
86+
// meet the post-conditions for the default constructor.
87+
88+
template<class MaybePseudoRandomNumberGenerator, class En = decltype( std::declval<MaybePseudoRandomNumberGenerator&>().seed() )>
89+
void seed( MaybePseudoRandomNumberGenerator& rng, int )
90+
{
91+
detail::random_provider seeder;
92+
rng.seed(seeder);
93+
}
94+
95+
template<class MaybePseudoRandomNumberGenerator>
96+
void seed( MaybePseudoRandomNumberGenerator&, long )
97+
{
98+
}
99+
};
100+
101+
}} // namespace boost::uuids
102+
103+
#endif // BOOST_UUID_BASIC_RANDOM_GENERATOR_HPP_INCLUDED
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
#ifndef BOOST_UUID_DETAIL_BASIC_NAME_GENERATOR_HPP_INCLUDED
2+
#define BOOST_UUID_DETAIL_BASIC_NAME_GENERATOR_HPP_INCLUDED
3+
4+
// Boost basic_name_generator.hpp header file -----------------------//
5+
6+
// Copyright 2010 Andy Tompkins.
7+
// Copyright 2017 James E. King III
8+
9+
// Distributed under the Boost Software License, Version 1.0. (See
10+
// accompanying file LICENSE_1_0.txt or copy at
11+
// https://www.boost.org/LICENSE_1_0.txt)
12+
13+
#include <boost/uuid/namespaces.hpp>
14+
#include <boost/uuid/uuid.hpp>
15+
#include <boost/uuid/detail/static_assert.hpp>
16+
#include <boost/config.hpp>
17+
#include <string>
18+
#include <cstdint>
19+
#include <cstring> // for strlen, wcslen
20+
21+
namespace boost {
22+
namespace uuids {
23+
namespace detail {
24+
25+
template<class HashAlgo>
26+
class basic_name_generator
27+
{
28+
private:
29+
30+
uuid namespace_uuid_;
31+
32+
private:
33+
34+
using digest_type = typename HashAlgo::digest_type;
35+
36+
public:
37+
38+
using result_type = uuid;
39+
40+
explicit basic_name_generator( uuid const& namespace_uuid ) noexcept
41+
: namespace_uuid_( namespace_uuid )
42+
{}
43+
44+
template<class Ch> uuid operator()( Ch const* name ) const noexcept
45+
{
46+
HashAlgo hash;
47+
48+
hash.process_bytes( namespace_uuid_.begin(), namespace_uuid_.size() );
49+
process_characters( hash, name, std::char_traits<Ch>().length( name ) );
50+
51+
return hash_to_uuid( hash );
52+
}
53+
54+
template<class Ch, class Traits, class Alloc>
55+
uuid operator()( std::basic_string<Ch, Traits, Alloc> const& name ) const noexcept
56+
{
57+
HashAlgo hash;
58+
59+
hash.process_bytes( namespace_uuid_.begin(), namespace_uuid_.size() );
60+
process_characters( hash, name.c_str(), name.length() );
61+
62+
return hash_to_uuid( hash );
63+
}
64+
65+
uuid operator()( void const* buffer, std::size_t byte_count ) const noexcept
66+
{
67+
HashAlgo hash;
68+
69+
hash.process_bytes( namespace_uuid_.begin(), namespace_uuid_.size() );
70+
hash.process_bytes( buffer, byte_count );
71+
72+
return hash_to_uuid( hash );
73+
}
74+
75+
private:
76+
77+
void process_characters( HashAlgo& hash, char const* p, std::size_t n ) const noexcept
78+
{
79+
hash.process_bytes( p, n );
80+
}
81+
82+
// For portability, we convert all wide characters to uint32_t so that each
83+
// character is 4 bytes regardless of sizeof(wchar_t).
84+
85+
void process_characters( HashAlgo& hash, wchar_t const* p, std::size_t n ) const noexcept
86+
{
87+
BOOST_UUID_STATIC_ASSERT( sizeof( std::uint32_t ) >= sizeof( wchar_t ) );
88+
89+
for( std::size_t i = 0; i < n; ++i)
90+
{
91+
std::uint32_t ch = p[ i ];
92+
93+
unsigned char bytes[ 4 ] =
94+
{
95+
static_cast<unsigned char>( ( ch >> 0 ) & 0xFF ),
96+
static_cast<unsigned char>( ( ch >> 8 ) & 0xFF ),
97+
static_cast<unsigned char>( ( ch >> 16 ) & 0xFF ),
98+
static_cast<unsigned char>( ( ch >> 24 ) & 0xFF )
99+
};
100+
101+
hash.process_bytes( bytes, 4 );
102+
}
103+
}
104+
105+
void process_characters( HashAlgo& hash, char32_t const* p, std::size_t n ) const noexcept
106+
{
107+
for( std::size_t i = 0; i < n; ++i)
108+
{
109+
process_utf32_codepoint( hash, p[ i ] );
110+
}
111+
}
112+
113+
void process_characters( HashAlgo& hash, char16_t const* p, std::size_t n ) const noexcept
114+
{
115+
for( std::size_t i = 0; i < n; ++i)
116+
{
117+
char16_t ch = p[ i ];
118+
119+
if( ch >= 0xD800 && ch <= 0xDBFF && i + 1 < n && p[ i+1 ] >= 0xDC00 && p[ i+1 ] <= 0xDFFF )
120+
{
121+
char16_t ch2 = p[ ++i ];
122+
123+
std::uint32_t high = ch - 0xD800;
124+
std::uint32_t low = ch2 - 0xDC00;
125+
126+
process_utf32_codepoint( hash, ( high << 10 ) + low + 0x10000 );
127+
}
128+
else
129+
{
130+
process_utf32_codepoint( hash, ch );
131+
}
132+
}
133+
}
134+
135+
void process_utf32_codepoint( HashAlgo& hash, std::uint32_t cp ) const noexcept
136+
{
137+
if( ( cp >= 0xD800 && cp <= 0xDFFF ) || cp > 0x10FFFF )
138+
{
139+
cp = 0xFFFD; // Unicode replacement character
140+
}
141+
142+
if( cp < 0x80 )
143+
{
144+
hash.process_byte( static_cast<unsigned char>( cp ) );
145+
}
146+
else if( cp < 0x800 )
147+
{
148+
unsigned char bytes[ 2 ] =
149+
{
150+
static_cast<unsigned char>( 0xC0 | (cp >> 6) ),
151+
static_cast<unsigned char>( 0x80 | (cp & 0x3F) )
152+
};
153+
154+
hash.process_bytes( bytes, 2 );
155+
}
156+
else if( cp < 0x10000 )
157+
{
158+
unsigned char bytes[ 3 ] =
159+
{
160+
static_cast<unsigned char>( 0xE0 | (cp >> 12) ),
161+
static_cast<unsigned char>( 0x80 | ((cp >> 6) & 0x3F) ),
162+
static_cast<unsigned char>( 0x80 | (cp & 0x3F) )
163+
};
164+
165+
hash.process_bytes( bytes, 3 );
166+
}
167+
else
168+
{
169+
unsigned char bytes[ 4 ] =
170+
{
171+
static_cast<unsigned char>( 0xF0 | ( cp >> 18 ) ),
172+
static_cast<unsigned char>( 0x80 | ((cp >> 12 ) & 0x3F ) ),
173+
static_cast<unsigned char>( 0x80 | ((cp >> 6 ) & 0x3F ) ),
174+
static_cast<unsigned char>( 0x80 | (cp & 0x3F) )
175+
};
176+
177+
hash.process_bytes( bytes, 4 );
178+
}
179+
}
180+
181+
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
182+
183+
void process_characters( HashAlgo& hash, char8_t const* p, std::size_t n ) const noexcept
184+
{
185+
hash.process_bytes( p, n );
186+
}
187+
188+
#endif
189+
190+
uuid hash_to_uuid( HashAlgo& hash ) const noexcept
191+
{
192+
digest_type digest;
193+
hash.get_digest(digest);
194+
195+
BOOST_UUID_STATIC_ASSERT( sizeof(digest_type) >= 16 );
196+
197+
uuid u;
198+
std::memcpy( u.data, digest, 16 );
199+
200+
// set variant: must be 0b10xxxxxx
201+
*(u.begin()+8) &= 0x3F;
202+
*(u.begin()+8) |= 0x80;
203+
204+
// set version
205+
unsigned char hashver = hash.get_version();
206+
*(u.begin()+6) &= 0x0F; // clear out the relevant bits
207+
*(u.begin()+6) |= (hashver << 4); // and apply them
208+
209+
return u;
210+
}
211+
};
212+
213+
} // namespace detail
214+
} // uuids
215+
} // boost
216+
217+
#endif // BOOST_UUID_DETAIL_BASIC_NAME_GENERATOR_HPP_INCLUDED

0 commit comments

Comments
 (0)