/*============================================================================= Copyright (c) 2011-2016 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef SPROUT_UUID_RANDOM_GENERATOR_HPP #define SPROUT_UUID_RANDOM_GENERATOR_HPP #include #include #include #include #include #include #include #include #include namespace sprout { namespace uuids { // // basic_random_generator // template class basic_random_generator { public: typedef sprout::uuids::uuid result_type; private: typedef UniformRandomNumberGenerator engine_type; typedef sprout::random::uniform_int_distribution distribution_type; typedef typename result_type::value_type value_type; private: distribution_type distribution_; private: SPROUT_CONSTEXPR result_type random_to_uuid_1(std::uint32_t v0, std::uint32_t v1, std::uint32_t v2, std::uint32_t v3) const { return result_type{{ static_cast((v0 >> 24) & 0xFF), static_cast((v0 >> 16) & 0xFF), static_cast((v0 >> 8) & 0xFF), static_cast((v0) & 0xFF), static_cast((v1 >> 24) & 0xFF), static_cast((v1 >> 16) & 0xFF), static_cast(((v1 >> 8) & 0x4F) | 0x40), static_cast((v1) & 0xFF), static_cast(((v2 >> 24) & 0xBF) | 0x80), static_cast((v2 >> 16) & 0xFF), static_cast((v2 >> 8) & 0xFF), static_cast((v2) & 0xFF), static_cast((v3 >> 24) & 0xFF), static_cast((v3 >> 16) & 0xFF), static_cast((v3 >> 8) & 0xFF), static_cast((v3) & 0xFF) }}; } template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) == 3, result_type >::type random_to_uuid(Random const& rnd, Args... args) const { return random_to_uuid_1(args..., sprout::random::result(rnd)); } template SPROUT_CONSTEXPR typename std::enable_if< sizeof...(Args) != 3, result_type >::type random_to_uuid(Random const& rnd, Args... args) const { return random_to_uuid(sprout::random::next(rnd)(), args..., sprout::random::result(rnd)); } public: SPROUT_CONSTEXPR basic_random_generator() : distribution_(sprout::numeric_limits::min(), sprout::numeric_limits::max()) {} template SPROUT_CONSTEXPR typename std::enable_if< std::is_integral::value, result_type >::type operator()(T const& seed) const { return operator()(engine_type(seed)); } template SPROUT_CONSTEXPR typename std::enable_if< !std::is_integral::value, result_type >::type operator()(Engine const& engine) const { return random_to_uuid(sprout::random::combine(engine, distribution_)()); } }; // // random_generator // typedef sprout::uuids::basic_random_generator<> random_generator; // // make_uuid4 // template SPROUT_CONSTEXPR typename std::enable_if< std::is_integral::value, sprout::uuids::uuid >::type make_uuid4(T const& seed) { return sprout::uuids::random_generator()(seed); } template SPROUT_CONSTEXPR typename std::enable_if< !std::is_integral::value, sprout::uuids::uuid >::type make_uuid4(Engine const& engine) { return sprout::uuids::random_generator()(engine); } } // namespace uuids } // namespace sprout #endif // #ifndef SPROUT_UUID_RANDOM_GENERATOR_HPP