123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- // (C) Copyright Gennadiy Rozental 2001.
- // 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)
- // See http://www.boost.org/libs/test for the library home page.
- //
- //!@file
- //!@brief Random generator
- // ***************************************************************************
- #ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
- #define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
- // Boost.Test
- #include <boost/test/data/config.hpp>
- #if !defined(BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
- #include <boost/test/data/monomorphic/generate.hpp>
- #include <boost/test/data/monomorphic/generators/keywords.hpp>
- // STL
- #include <random>
- #include <boost/test/detail/suppress_warnings.hpp>
- //____________________________________________________________________________//
- namespace boost {
- namespace unit_test {
- namespace data {
- namespace {
- nfp::keyword<struct seed_t> seed;
- nfp::keyword<struct distribution_t> distribution;
- nfp::keyword<struct engine_t> engine;
- } // local namespace
- namespace monomorphic {
- namespace ds_detail {
- template<typename SampleType>
- struct default_distribution {
- typedef typename mpl::if_<std::is_integral<SampleType>,
- std::uniform_int_distribution<SampleType>,
- std::uniform_real_distribution<SampleType>>::type type;
- };
- } // namespace ds_detail
- // ************************************************************************** //
- // ************** random_t ************** //
- // ************************************************************************** //
- /*!@brief Generator for the random sequences
- *
- * This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing
- * a random number generator.
- */
- template<typename SampleType = double,
- typename DistributionType = typename ds_detail::default_distribution<SampleType>::type,
- typename EngineType = std::default_random_engine>
- class random_t {
- public:
- typedef SampleType sample;
- typedef DistributionType distr_type;
- typedef EngineType engine_type;
- random_t()
- : m_distribution()
- , m_engine( std::random_device()() )
- {}
- explicit random_t( distr_type&& d )
- : m_distribution( std::forward<distr_type>(d) )
- , m_engine( std::random_device()() ){}
- random_t( engine_type&& e, distr_type&& d )
- : m_distribution( std::forward<distr_type>(d) )
- , m_engine( std::forward<engine_type>(e) ){}
- // Generator interface
- data::size_t capacity() const { return BOOST_TEST_DS_INFINITE_SIZE; }
- SampleType next()
- {
- return m_distribution( m_engine );
- }
- void reset() {}
-
- //! Sets the seed of the pseudo-random number engine.
- template<typename SeedType>
- void seed( SeedType&& seed ) { m_engine.seed( std::forward<SeedType>( seed ) ); }
- private:
- // Data members
- DistributionType m_distribution;
- EngineType m_engine;
- };
- //____________________________________________________________________________//
- } // namespace monomorphic
- //! @brief Returns an infinite sequence of random numbers.
- //!
- //! The following overloads are available:
- //! @code
- //! auto d = random();
- //! auto d = random(begin, end);
- //! auto d = random(params);
- //! @endcode
- //!
- //!
- //! - The first overload uses the default distribution, which is uniform and which elements
- //! are @c double type (the values are in [0, 1) ).
- //! - The second overload generates numbers in the given interval. The distribution is uniform (in [begin, end)
- //! for real numbers, and in [begin, end] for integers). The type of the distribution is deduced from the type
- //! of the @c begin and @c end parameters.
- //! - The third overload generates numbers using the named parameter inside @c params , which are:
- //! - @c distribution: the distribution used. In this overload, since the type of the samples cannot be deduced,
- //! the samples are of type @c double and the distribution is uniform real in [0, 1).
- //! - @c seed: the seed for generating the values
- //! - @c engine: the random number generator engine
- //!
- //! The function returns an object that implements the dataset API.
- //! @note This function is available only for C++11 capable compilers.
- inline monomorphic::generated_by< monomorphic::random_t<>> random()
- {
- return monomorphic::generated_by<monomorphic::random_t<>>( monomorphic::random_t<>() );
- }
- //____________________________________________________________________________//
- /// @overload boost::unit_test::data::random()
- template<typename SampleType>
- inline monomorphic::generated_by< monomorphic::random_t<SampleType>>
- random( SampleType begin, SampleType end )
- {
- typedef monomorphic::random_t<SampleType> Gen;
- typedef typename Gen::distr_type distr_type;
- return monomorphic::generated_by<Gen>( Gen( distr_type(begin,end) ) );
- }
- //____________________________________________________________________________//
- namespace ds_detail {
- template<typename Params>
- struct random_gen_type {
- typedef typename nfp::param_type<Params,decltype(distribution),std::uniform_real_distribution<>>::type distr_type;
- typedef typename nfp::param_type<Params,decltype(engine),std::default_random_engine>::type engine_type;
- typedef typename distr_type::result_type sample_type;
- typedef monomorphic::random_t<sample_type,distr_type,engine_type> type;
- };
- }
- /// @overload boost::unit_test::data::random()
- template<typename Params>
- inline monomorphic::generated_by<typename ds_detail::random_gen_type<Params>::type>
- random( Params const& params )
- {
- typedef typename ds_detail::random_gen_type<Params>::type Gen;
- typedef typename Gen::distr_type distr_type;
- typedef typename Gen::engine_type engine_type;
- std::random_device rd;
- engine_type E;
- // engine_type E( rd );
- if( params.has(engine) )
- E = params[engine];
- distr_type D;
- if( params.has(distribution) )
- D = params[distribution];
- Gen G( std::move(E), std::move(D) );
- if( params.has(seed) )
- G.seed( params[seed] );
- return monomorphic::generated_by<Gen>( std::move(G) );
- }
- } // namespace data
- } // namespace unit_test
- } // namespace boost
- #include <boost/test/detail/enable_warnings.hpp>
- #endif // BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE
- #endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
|