// (C) Copyright John Maddock 2005. // Use, modification and distribution are subject to 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) #ifdef TEST_STD_HEADERS #include #else #include #endif #include #include #include "verify_return.hpp" #include template void check_uniform(T*) { typedef typename T::result_type result_type; BOOST_STATIC_ASSERT(::boost::is_arithmetic::value); T t; result_type r = 0; verify_return_type((t.min)(), r); verify_return_type((t.max)(), r); verify_return_type(t(), r); } struct seed_architype { typedef unsigned result_type; unsigned operator()()const { return 0; } }; unsigned seed_proc(); class uniform_random_generator_architype { public: typedef unsigned long result_type; result_type operator()() { return 0; } result_type min BOOST_PREVENT_MACRO_SUBSTITUTION()const { return 0; } result_type max BOOST_PREVENT_MACRO_SUBSTITUTION()const { return 0; } static uniform_random_generator_architype& get() { static uniform_random_generator_architype r; return r; } private: uniform_random_generator_architype(); uniform_random_generator_architype(const uniform_random_generator_architype&); uniform_random_generator_architype& operator=(const uniform_random_generator_architype&); }; class pseudo_random_generator_architype { public: pseudo_random_generator_architype(){} pseudo_random_generator_architype(const pseudo_random_generator_architype&){} pseudo_random_generator_architype& operator=(const pseudo_random_generator_architype&) { return *this; } typedef unsigned long result_type; result_type operator()() { return 0; } result_type min BOOST_PREVENT_MACRO_SUBSTITUTION()const { return 0; } result_type max BOOST_PREVENT_MACRO_SUBSTITUTION()const { return 0; } pseudo_random_generator_architype(unsigned long){} template pseudo_random_generator_architype(Gen&){} void seed(){} void seed(unsigned long){} template void seed(Gen&){} bool operator == (const pseudo_random_generator_architype&)const { return false; } bool operator != (const pseudo_random_generator_architype&)const { return false; } #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template friend std::basic_ostream& operator<<(std::basic_ostream& os, const pseudo_random_generator_architype& lcg) { return os; } template friend std::basic_istream& operator>>(std::basic_istream& is, pseudo_random_generator_architype& lcg) { return is; } #endif }; class random_distribution_architype { public: random_distribution_architype(){} random_distribution_architype(const random_distribution_architype&){} random_distribution_architype& operator=(const random_distribution_architype&) { return *this; } typedef unsigned input_type; typedef double result_type; void reset(){} template result_type operator()(U& u) { return u(); } #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) template friend std::basic_ostream& operator<<(std::basic_ostream& os, const random_distribution_architype& lcg) { return os; } template friend std::basic_istream& operator>>(std::basic_istream& is, random_distribution_architype& lcg) { return is; } #endif }; template void check_pseudo_random(T* p) { typedef typename T::result_type result_type; check_uniform(p); T t1; T t2(t1); t1 = t2; unsigned long s = 0; T t3(s); seed_architype seed; T t4(seed); t1.seed(); t1.seed(s); t1.seed(seed); T t5(seed_proc); t1.seed(seed_proc); const T& x = t1; const T& y = t2; verify_return_type(x == y, true); verify_return_type(x == y, false); #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) std::cout << t1; std::cin >> t1; #endif } template void check_random_distribution(T* pd) { T t1(*pd); t1 = *pd; uniform_random_generator_architype& gen = uniform_random_generator_architype::get(); typedef typename T::input_type input_type; typedef typename T::result_type result_type; t1.reset(); verify_return_type(t1(gen), result_type()); const T& ct = t1; #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551)) std::cout << ct << std::endl; std::cin >> t1 >> std::ws; #endif } template void check_generator(VG* g) { typedef typename VG::engine_type engine_type; typedef typename VG::engine_value_type engine_value_type; typedef typename VG::distribution_type distribution_type; typedef typename distribution_type::input_type input_type; typedef typename VG::result_type result_type; verify_return_type((*g)(), result_type(0)); const VG* cg = g; verify_return_type(&g->engine(), static_cast(0)); verify_return_type(&cg->engine(), static_cast(0)); verify_return_type(&g->distribution(), static_cast(0)); verify_return_type(&cg->distribution(), static_cast(0)); } template void check_generator_extended(VG* g) { typedef typename VG::engine_type engine_type; typedef typename VG::engine_value_type engine_value_type; typedef typename VG::distribution_type distribution_type; typedef typename distribution_type::input_type input_type; typedef typename VG::result_type result_type; //verify_return_type((*g)(input_type(0)), result_type(0)); const VG* cg = g; verify_return_type((cg->min)(), result_type(0)); verify_return_type((cg->max)(), result_type(0)); } int main() { typedef std::tr1::linear_congruential< ::boost::int32_t, 16807, 0, 2147483647> lc_t; lc_t lc; BOOST_STATIC_ASSERT(lc_t::multiplier == 16807); BOOST_STATIC_ASSERT(lc_t::increment == 0); BOOST_STATIC_ASSERT(lc_t::modulus == 2147483647); check_pseudo_random(&lc); typedef std::tr1::mersenne_twister< ::boost::uint32_t,32,351,175,19,0xccab8ee7,11,7,0x31b6ab00,15,0xffe50000,17> mt11213b; mt11213b mt; check_pseudo_random(&mt); typedef std::tr1::subtract_with_carry< ::boost::int32_t, 24, 10, 24> sub_t; sub_t sub; check_pseudo_random(&sub); typedef std::tr1::subtract_with_carry_01 ranlux_base_01; ranlux_base_01 rl1; check_pseudo_random(&rl1); typedef std::tr1::subtract_with_carry_01 ranlux64_base_01; ranlux64_base_01 rl2; check_pseudo_random(&rl2); typedef std::tr1::discard_block< std::tr1::subtract_with_carry< ::boost::int32_t , (1<<24), 10, 24>, 223, 24> ranlux3; ranlux3 rl3; check_pseudo_random(&rl3); std::tr1::xor_combine xorc; check_pseudo_random(&xorc); verify_return_type(xorc.base1(), pseudo_random_generator_architype()); verify_return_type(xorc.base2(), pseudo_random_generator_architype()); #ifndef __SUNPRO_CC // we don't normally allow workarounds in here, but this // class is unsupported on this platform. std::tr1::random_device d; check_uniform(&d); verify_return_type(d.entropy(), double(0)); #endif uniform_random_generator_architype& gen = uniform_random_generator_architype::get(); std::tr1::uniform_int ui; check_random_distribution(&ui); typedef std::tr1::uniform_int::result_type ui_r_t; verify_return_type((ui.min)(), ui_r_t()); verify_return_type((ui.max)(), ui_r_t()); //verify_return_type(ui(gen, ui_r_t()), ui_r_t()); std::tr1::bernoulli_distribution bd; verify_return_type(bd.p(), double(0)); check_random_distribution(&bd); std::tr1::geometric_distribution<> gd; verify_return_type(gd.p(), double(0)); check_random_distribution(&gd); BOOST_STATIC_ASSERT((::boost::is_same::result_type, int>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::geometric_distribution gd2(0.5); verify_return_type(gd2.p(), double(0)); check_random_distribution(&gd2); BOOST_STATIC_ASSERT((::boost::is_same::result_type, long>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::poisson_distribution<> pd; verify_return_type(pd.mean(), double(0)); check_random_distribution(&pd); BOOST_STATIC_ASSERT((::boost::is_same::result_type, int>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::poisson_distribution pd2(0.5); verify_return_type(pd2.mean(), double(0)); check_random_distribution(&pd2); BOOST_STATIC_ASSERT((::boost::is_same::result_type, long>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::binomial_distribution<> bind; verify_return_type(bind.p(), double(0)); verify_return_type(bind.t(), int(0)); check_random_distribution(&bind); BOOST_STATIC_ASSERT((::boost::is_same::result_type, int>::value)); //BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::binomial_distribution bind2(1, 0.5); verify_return_type(bind2.t(), long(0)); check_random_distribution(&bind2); BOOST_STATIC_ASSERT((::boost::is_same::result_type, long>::value)); //BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::uniform_real<> urd; check_random_distribution(&urd); BOOST_STATIC_ASSERT((::boost::is_same::result_type, double>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::uniform_real urd2(0.5L, 1.5L); verify_return_type((urd2.min)(), (long double)(0)); verify_return_type((urd2.max)(), (long double)(0)); check_random_distribution(&urd2); BOOST_STATIC_ASSERT((::boost::is_same::result_type, long double>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, long double>::value)); std::tr1::exponential_distribution<> exd; check_random_distribution(&exd); BOOST_STATIC_ASSERT((::boost::is_same::result_type, double>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::exponential_distribution exd2(0.5L); verify_return_type(exd2.lambda(), (long double)(0)); check_random_distribution(&exd2); BOOST_STATIC_ASSERT((::boost::is_same::result_type, long double>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, long double>::value)); std::tr1::normal_distribution<> normd; check_random_distribution(&normd); BOOST_STATIC_ASSERT((::boost::is_same::result_type, double>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::normal_distribution normd2(0.5L, 0.1L); verify_return_type(normd2.mean(), (long double)(0)); verify_return_type(normd2.sigma(), (long double)(0)); check_random_distribution(&normd2); BOOST_STATIC_ASSERT((::boost::is_same::result_type, long double>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, long double>::value)); std::tr1::gamma_distribution<> gammad; check_random_distribution(&gammad); BOOST_STATIC_ASSERT((::boost::is_same::result_type, double>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, double>::value)); std::tr1::gamma_distribution gammad2(0.5L); verify_return_type(gammad2.alpha(), (long double)(0)); check_random_distribution(&gammad2); BOOST_STATIC_ASSERT((::boost::is_same::result_type, long double>::value)); BOOST_STATIC_ASSERT((::boost::is_same::input_type, long double>::value)); // // variate_generator: // std::tr1::variate_generator vg1(uniform_random_generator_architype::get(), random_distribution_architype()); check_generator(&vg1); std::tr1::variate_generator > vg2(uniform_random_generator_architype::get(), std::tr1::uniform_int<>()); check_generator_extended(&vg2); std::tr1::variate_generator > vg3(&uniform_random_generator_architype::get(), std::tr1::uniform_int<>()); check_generator_extended(&vg3); return 0; }