]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | // |
2 | // Copyright (c) 2017 James E. King III | |
3 | // | |
4 | // Distributed under the Boost Software License, Version 1.0. | |
5 | // (See accompanying file LICENSE_1_0.txt or copy at | |
92f5a8d4 | 6 | // https://www.boost.org/LICENSE_1_0.txt) |
11fdf7f2 TL |
7 | // |
8 | // Platform-specific random entropy provider | |
9 | // | |
10 | ||
11 | #ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP | |
12 | #define BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP | |
13 | ||
92f5a8d4 | 14 | #include <boost/config.hpp> |
11fdf7f2 TL |
15 | #include <boost/cstdint.hpp> |
16 | #include <boost/limits.hpp> | |
17 | #include <boost/static_assert.hpp> | |
92f5a8d4 TL |
18 | #include <boost/move/core.hpp> |
19 | #include <boost/move/utility_core.hpp> | |
11fdf7f2 TL |
20 | #include <boost/type_traits/is_integral.hpp> |
21 | #include <boost/type_traits/is_unsigned.hpp> | |
22 | #include <boost/uuid/entropy_error.hpp> | |
23 | #include <climits> | |
24 | #include <iterator> | |
25 | ||
26 | // Detection of the platform is separated from inclusion of the correct | |
27 | // header to facilitate mock testing of the provider implementations. | |
28 | ||
29 | #include <boost/uuid/detail/random_provider_detect_platform.hpp> | |
30 | #include <boost/uuid/detail/random_provider_include_platform.hpp> | |
31 | ||
32 | ||
33 | namespace boost { | |
34 | namespace uuids { | |
35 | namespace detail { | |
36 | ||
37 | //! \brief Contains code common to all random_provider implementations. | |
38 | //! \note random_provider_base is required to provide this method: | |
39 | //! void get_random_bytes(void *buf, size_t siz); | |
40 | //! \note noncopyable because of some base implementations so | |
41 | //! this makes it uniform across platforms to avoid any | |
42 | //! porting surprises | |
92f5a8d4 TL |
43 | class random_provider : |
44 | public detail::random_provider_base | |
11fdf7f2 | 45 | { |
92f5a8d4 TL |
46 | BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider) |
47 | ||
11fdf7f2 | 48 | public: |
92f5a8d4 TL |
49 | BOOST_DEFAULTED_FUNCTION(random_provider(), {}) |
50 | ||
51 | random_provider(BOOST_RV_REF(random_provider) that) BOOST_NOEXCEPT : | |
52 | detail::random_provider_base(boost::move(static_cast< detail::random_provider_base& >(that))) | |
53 | { | |
54 | } | |
55 | ||
56 | random_provider& operator= (BOOST_RV_REF(random_provider) that) BOOST_NOEXCEPT | |
57 | { | |
58 | static_cast< detail::random_provider_base& >(*this) = boost::move(static_cast< detail::random_provider_base& >(that)); | |
59 | return *this; | |
60 | } | |
61 | ||
11fdf7f2 TL |
62 | //! Leverage the provider as a SeedSeq for |
63 | //! PseudoRandomNumberGeneration seeing. | |
64 | //! \note: See Boost.Random documentation for more details | |
65 | template<class Iter> | |
66 | void generate(Iter first, Iter last) | |
67 | { | |
68 | typedef typename std::iterator_traits<Iter>::value_type value_type; | |
69 | BOOST_STATIC_ASSERT(is_integral<value_type>::value); | |
70 | BOOST_STATIC_ASSERT(is_unsigned<value_type>::value); | |
71 | BOOST_STATIC_ASSERT(sizeof(value_type) * CHAR_BIT >= 32); | |
72 | ||
73 | for (; first != last; ++first) | |
74 | { | |
75 | get_random_bytes(&*first, sizeof(*first)); | |
76 | *first &= (std::numeric_limits<boost::uint32_t>::max)(); | |
77 | } | |
78 | } | |
79 | ||
80 | //! Return the name of the selected provider | |
81 | const char * name() const | |
82 | { | |
83 | return BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(BOOST_UUID_RANDOM_PROVIDER_NAME); | |
84 | } | |
85 | }; | |
86 | ||
87 | } // detail | |
88 | } // uuids | |
89 | } // boost | |
90 | ||
91 | #endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP |