File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/x86_64-linux/CPP/Boost/Mini.x/i/boost/uuid/random_generator.hpp
Criterion Covered Total %
statement 9 9 100.0
branch 1 2 50.0
condition n/a
subroutine n/a
pod n/a
total 10 11 90.9


line stmt bran cond sub pod time code
1             // Boost random_generator.hpp header file ----------------------------------------------//
2              
3             // Copyright 2010 Andy Tompkins.
4             // Copyright 2017 James E. King III
5             // Distributed under the Boost Software License, Version 1.0. (See
6             // accompanying file LICENSE_1_0.txt or copy at
7             // http://www.boost.org/LICENSE_1_0.txt)
8              
9             #ifndef BOOST_UUID_RANDOM_GENERATOR_HPP
10             #define BOOST_UUID_RANDOM_GENERATOR_HPP
11              
12             #include
13             #include
14             #include
15             #include
16             #include
17             #include
18             #include
19             #include
20             #include
21             #include
22             #include
23             #include
24              
25             namespace boost {
26             namespace uuids {
27              
28             namespace detail {
29             template
30 1001           U& set_uuid_random_vv(U& u)
31             {
32             // set variant
33             // must be 0b10xxxxxx
34 1001           *(u.begin() + 8) &= 0xBF;
35 1001           *(u.begin() + 8) |= 0x80;
36              
37             // set version
38             // must be 0b0100xxxx
39 1001           *(u.begin() + 6) &= 0x4F; //0b01001111
40 1001           *(u.begin() + 6) |= 0x40; //0b01000000
41              
42 1001           return u;
43             }
44              
45             BOOST_TTI_HAS_MEMBER_FUNCTION(seed)
46             }
47              
48             //! generate a random-based uuid
49             //! \param[in] UniformRandomNumberGenerator see Boost.Random documentation
50             template
51             class basic_random_generator
52             {
53             BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_random_generator)
54              
55             private:
56             typedef uniform_int distribution_type;
57             typedef variate_generator generator_type;
58              
59             struct impl
60             {
61             generator_type generator;
62              
63             explicit impl(UniformRandomNumberGenerator* purng_arg) :
64             generator(purng_arg, distribution_type((std::numeric_limits::min)(), (std::numeric_limits::max)()))
65             {
66             }
67              
68             virtual ~impl() {}
69              
70             BOOST_DELETED_FUNCTION(impl(impl const&))
71             BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
72             };
73              
74             struct urng_holder
75             {
76             UniformRandomNumberGenerator urng;
77             };
78              
79             #if defined(BOOST_MSVC)
80             #pragma warning(push)
81             // 'this' : used in base member initializer list
82             #pragma warning(disable: 4355)
83             #endif
84              
85             struct self_contained_impl :
86             public urng_holder,
87             public impl
88             {
89             self_contained_impl() : impl(&this->urng_holder::urng)
90             {
91             }
92             };
93              
94             #if defined(BOOST_MSVC)
95             #pragma warning(pop)
96             #endif
97              
98             public:
99             typedef uuid result_type;
100              
101             // default constructor creates the random number generator and
102             // if the UniformRandomNumberGenerator is a PseudoRandomNumberGenerator
103             // then it gets seeded by a random_provider.
104             basic_random_generator() : m_impl(new self_contained_impl())
105             {
106             // seed the random number generator if it is capable
107             seed(static_cast< self_contained_impl* >(m_impl)->urng);
108             }
109              
110             // keep a reference to a random number generator
111             // don't seed a given random number generator
112             explicit basic_random_generator(UniformRandomNumberGenerator& gen) : m_impl(new impl(&gen))
113             {
114             }
115              
116             // keep a pointer to a random number generator
117             // don't seed a given random number generator
118             explicit basic_random_generator(UniformRandomNumberGenerator* gen) : m_impl(new impl(gen))
119             {
120             BOOST_ASSERT(!!gen);
121             }
122              
123             basic_random_generator(BOOST_RV_REF(basic_random_generator) that) BOOST_NOEXCEPT : m_impl(that.m_impl)
124             {
125             that.m_impl = 0;
126             }
127              
128             basic_random_generator& operator= (BOOST_RV_REF(basic_random_generator) that) BOOST_NOEXCEPT
129             {
130             delete m_impl;
131             m_impl = that.m_impl;
132             that.m_impl = 0;
133             return *this;
134             }
135              
136             ~basic_random_generator()
137             {
138             delete m_impl;
139             }
140              
141             result_type operator()()
142             {
143             result_type u;
144              
145             int i=0;
146             unsigned long random_value = m_impl->generator();
147             for (uuid::iterator it = u.begin(), end = u.end(); it != end; ++it, ++i) {
148             if (i==sizeof(unsigned long)) {
149             random_value = m_impl->generator();
150             i = 0;
151             }
152              
153             // static_cast gets rid of warnings of converting unsigned long to boost::uint8_t
154             *it = static_cast((random_value >> (i*8)) & 0xFF);
155             }
156              
157             return detail::set_uuid_random_vv(u);
158             }
159              
160             private:
161             // Detect whether UniformRandomNumberGenerator has a seed() method which indicates that
162             // it is a PseudoRandomNumberGenerator and needs a seed to initialize it. This allows
163             // basic_random_generator to take any type of UniformRandomNumberGenerator and still
164             // meet the post-conditions for the default constructor.
165              
166             template
167             typename boost::enable_if >::type
168             seed(MaybePseudoRandomNumberGenerator& rng)
169             {
170             detail::random_provider seeder;
171             rng.seed(seeder);
172             }
173              
174             template
175             typename boost::disable_if >::type
176             seed(MaybePseudoRandomNumberGenerator&)
177             {
178             }
179              
180             impl* m_impl;
181             };
182              
183             //! \brief a far less complex random generator that uses
184             //! operating system provided entropy which will
185             //! satisfy the majority of use cases
186             class random_generator_pure
187             {
188             BOOST_MOVABLE_BUT_NOT_COPYABLE(random_generator_pure)
189              
190             public:
191             typedef uuid result_type;
192              
193             BOOST_DEFAULTED_FUNCTION(random_generator_pure(), {})
194              
195             random_generator_pure(BOOST_RV_REF(random_generator_pure) that) BOOST_NOEXCEPT :
196             prov_(boost::move(that.prov_))
197             {
198             }
199              
200             random_generator_pure& operator= (BOOST_RV_REF(random_generator_pure) that) BOOST_NOEXCEPT
201             {
202             prov_ = boost::move(that.prov_);
203             return *this;
204             }
205              
206             //! \returns a random, valid uuid
207             //! \throws entropy_error
208 1001           result_type operator()()
209             {
210             result_type result;
211 1001 50         prov_.get_random_bytes(&result, sizeof(result_type));
212 1001           return detail::set_uuid_random_vv(result);
213             }
214              
215             private:
216             detail::random_provider prov_;
217             };
218              
219             #if defined(BOOST_UUID_RANDOM_GENERATOR_COMPAT)
220             typedef basic_random_generator random_generator;
221             #else
222             typedef random_generator_pure random_generator;
223             typedef basic_random_generator random_generator_mt19937;
224             #endif
225              
226             }} // namespace boost::uuids
227              
228             #endif // BOOST_UUID_RANDOM_GENERATOR_HPP