Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:49

0001 //  (C) Copyright Gennadiy Rozental 2001.
0002 //  Distributed under the Boost Software License, Version 1.0.
0003 //  (See accompanying file LICENSE_1_0.txt or copy at 
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 //  See http://www.boost.org/libs/test for the library home page.
0007 //
0008 //!@file
0009 //!@brief Random generator
0010 // ***************************************************************************
0011 
0012 #ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
0013 #define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
0014 
0015 // Boost.Test
0016 #include <boost/test/data/config.hpp>
0017 
0018 
0019 
0020 
0021 #if !defined(BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
0022 
0023 #include <boost/test/data/monomorphic/generate.hpp>
0024 #include <boost/test/data/monomorphic/generators/keywords.hpp>
0025 
0026 // STL
0027 #include <random>
0028 
0029 #include <boost/test/detail/suppress_warnings.hpp>
0030 
0031 //____________________________________________________________________________//
0032 
0033 namespace boost {
0034 namespace unit_test {
0035 namespace data {
0036 
0037 namespace {
0038 nfp::keyword<struct seed_t>         seed;
0039 nfp::keyword<struct distribution_t> distribution;
0040 nfp::keyword<struct engine_t>       engine;
0041 } // local namespace
0042 
0043 namespace monomorphic {
0044 
0045 namespace ds_detail {
0046 template<typename SampleType>
0047 struct default_distribution {
0048     typedef typename mpl::if_<std::is_integral<SampleType>,
0049                               std::uniform_int_distribution<SampleType>,
0050                               std::uniform_real_distribution<SampleType>>::type type;
0051 };
0052 
0053 } // namespace ds_detail
0054 
0055 // ************************************************************************** //
0056 // **************                   random_t                   ************** //
0057 // ************************************************************************** //
0058 
0059 /*!@brief Generator for the random sequences
0060  *
0061  * This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing
0062  * a random number generator.
0063  */
0064 template<typename SampleType        = double, 
0065          typename DistributionType  = typename ds_detail::default_distribution<SampleType>::type,
0066          typename EngineType        = std::default_random_engine>
0067 class random_t {
0068 public:
0069     typedef SampleType          sample;
0070     typedef DistributionType    distr_type;
0071     typedef EngineType          engine_type;
0072 
0073     random_t()
0074     : m_distribution()
0075     , m_engine( std::random_device()() )
0076     {}
0077     explicit random_t( distr_type&& d )
0078     : m_distribution( std::forward<distr_type>(d) )
0079     , m_engine( std::random_device()() ){}
0080     random_t( engine_type&& e, distr_type&& d )
0081     : m_distribution( std::forward<distr_type>(d) )
0082     , m_engine( std::forward<engine_type>(e) ){}
0083 
0084     // Generator interface
0085     data::size_t        capacity() const    { return BOOST_TEST_DS_INFINITE_SIZE; }
0086     SampleType          next() 
0087     {
0088         return m_distribution( m_engine );
0089     }
0090     void                reset()             {}
0091     
0092     //! Sets the seed of the pseudo-random number engine.
0093     template<typename SeedType>
0094     void seed( SeedType&& seed )            { m_engine.seed( std::forward<SeedType>( seed ) ); }
0095 
0096 private:
0097     // Data members
0098     DistributionType    m_distribution;
0099     EngineType          m_engine;
0100 };
0101 
0102 //____________________________________________________________________________//
0103 
0104 } // namespace monomorphic
0105 
0106 
0107 //! @brief Returns an infinite sequence of random numbers. 
0108 //!
0109 //! The following overloads are available:
0110 //! @code
0111 //! auto d = random();
0112 //! auto d = random(begin, end);
0113 //! auto d = random(params);
0114 //! @endcode
0115 //! 
0116 //!   
0117 //! - The first overload uses the default distribution, which is uniform and which elements 
0118 //!   are @c double type (the values are in [0, 1) ). 
0119 //! - The second overload generates numbers in the given interval. The distribution is uniform (in [begin, end) 
0120 //!   for real numbers, and in [begin, end] for integers). The type of the distribution is deduced from the type
0121 //!   of the @c begin and @c end parameters.
0122 //! - The third overload generates numbers using the named parameter inside @c params , which are:
0123 //!   - @c distribution: the distribution used. In this overload, since the type of the samples cannot be deduced, 
0124 //!     the samples are of type @c double and the distribution is uniform real in [0, 1).
0125 //!   - @c seed: the seed for generating the values
0126 //!   - @c engine: the random number generator engine
0127 //!
0128 //! The function returns an object that implements the dataset API.
0129 //! @note This function is available only for C++11 capable compilers.
0130 inline monomorphic::generated_by< monomorphic::random_t<>> random()
0131 {
0132     return monomorphic::generated_by<monomorphic::random_t<>>( monomorphic::random_t<>() );
0133 }
0134 
0135 //____________________________________________________________________________//
0136 
0137 /// @overload boost::unit_test::data::random()
0138 template<typename SampleType>
0139 inline monomorphic::generated_by< monomorphic::random_t<SampleType>>
0140 random( SampleType begin, SampleType end )
0141 {
0142     typedef monomorphic::random_t<SampleType> Gen;
0143     typedef typename Gen::distr_type distr_type;
0144     return monomorphic::generated_by<Gen>( Gen( distr_type(begin,end) ) );
0145 }
0146 
0147 //____________________________________________________________________________//
0148 
0149 namespace ds_detail {
0150 template<typename Params>
0151 struct random_gen_type {
0152     typedef typename nfp::param_type<Params,decltype(distribution),std::uniform_real_distribution<>>::type distr_type;
0153     typedef typename nfp::param_type<Params,decltype(engine),std::default_random_engine>::type engine_type;
0154     typedef typename distr_type::result_type sample_type;
0155 
0156     typedef monomorphic::random_t<sample_type,distr_type,engine_type> type;
0157 };
0158 
0159 }
0160 
0161 
0162 /// @overload boost::unit_test::data::random()
0163 template<typename Params>
0164 inline monomorphic::generated_by<typename ds_detail::random_gen_type<Params>::type>
0165 random( Params const& params )
0166 {
0167     typedef typename ds_detail::random_gen_type<Params>::type Gen;
0168     typedef typename Gen::distr_type distr_type;
0169     typedef typename Gen::engine_type engine_type;
0170 
0171     std::random_device rd;
0172     engine_type E;
0173 //    engine_type E( rd );
0174     if( params.has(engine) )
0175         E = params[engine];
0176 
0177     distr_type D;
0178     if( params.has(distribution) )
0179         D = params[distribution];
0180 
0181     Gen G( std::move(E), std::move(D) );
0182 
0183     if( params.has(seed) )
0184         G.seed( params[seed] );
0185 
0186     return monomorphic::generated_by<Gen>( std::move(G) );
0187 }
0188 
0189 } // namespace data
0190 } // namespace unit_test
0191 } // namespace boost
0192 
0193 #include <boost/test/detail/enable_warnings.hpp>
0194 
0195 #endif // BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE
0196 
0197 
0198 #endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER