blob: e911c1552544dcff55d5bae79c1280126cdec438 [file] [log] [blame]
// (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 <random>
#else
#include <boost/tr1/random.hpp>
#endif
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include "verify_return.hpp"
#include <iostream>
template <class T>
void check_uniform(T*)
{
typedef typename T::result_type result_type;
BOOST_STATIC_ASSERT(::boost::is_arithmetic<result_type>::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 <class Gen> pseudo_random_generator_architype(Gen&){}
void seed(){}
void seed(unsigned long){}
template <class Gen> 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<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const pseudo_random_generator_architype& lcg)
{
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& 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 <class U>
result_type operator()(U& u)
{
return u();
}
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<class CharT, class Traits>
friend std::basic_ostream<CharT,Traits>&
operator<<(std::basic_ostream<CharT,Traits>& os,
const random_distribution_architype& lcg)
{
return os;
}
template<class CharT, class Traits>
friend std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& is,
random_distribution_architype& lcg)
{
return is;
}
#endif
};
template <class T>
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 <class T>
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 <class VG>
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<engine_value_type*>(0));
verify_return_type(&cg->engine(), static_cast<const engine_value_type*>(0));
verify_return_type(&g->distribution(), static_cast<distribution_type*>(0));
verify_return_type(&cg->distribution(), static_cast<const distribution_type*>(0));
}
template <class VG>
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<float, 24, 10, 24> ranlux_base_01;
ranlux_base_01 rl1;
check_pseudo_random(&rl1);
typedef std::tr1::subtract_with_carry_01<double, 48, 10, 24> 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<pseudo_random_generator_architype, 0, pseudo_random_generator_architype, 1> 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<unsigned long> ui;
check_random_distribution(&ui);
typedef std::tr1::uniform_int<unsigned long>::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<std::tr1::geometric_distribution<>::result_type, int>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::geometric_distribution<>::input_type, double>::value));
std::tr1::geometric_distribution<long, double> gd2(0.5);
verify_return_type(gd2.p(), double(0));
check_random_distribution(&gd2);
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::geometric_distribution<long, double>::result_type, long>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::geometric_distribution<long, double>::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<std::tr1::poisson_distribution<>::result_type, int>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::poisson_distribution<>::input_type, double>::value));
std::tr1::poisson_distribution<long, double> pd2(0.5);
verify_return_type(pd2.mean(), double(0));
check_random_distribution(&pd2);
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::poisson_distribution<long, double>::result_type, long>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::poisson_distribution<long, double>::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<std::tr1::binomial_distribution<>::result_type, int>::value));
//BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::binomial_distribution<>::input_type, double>::value));
std::tr1::binomial_distribution<long, double> bind2(1, 0.5);
verify_return_type(bind2.t(), long(0));
check_random_distribution(&bind2);
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::binomial_distribution<long, double>::result_type, long>::value));
//BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::binomial_distribution<long, double>::input_type, double>::value));
std::tr1::uniform_real<> urd;
check_random_distribution(&urd);
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::uniform_real<>::result_type, double>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::uniform_real<>::input_type, double>::value));
std::tr1::uniform_real<long double> 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<std::tr1::uniform_real<long double>::result_type, long double>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::uniform_real<long double>::input_type, long double>::value));
std::tr1::exponential_distribution<> exd;
check_random_distribution(&exd);
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::exponential_distribution<>::result_type, double>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::exponential_distribution<>::input_type, double>::value));
std::tr1::exponential_distribution<long double> exd2(0.5L);
verify_return_type(exd2.lambda(), (long double)(0));
check_random_distribution(&exd2);
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::exponential_distribution<long double>::result_type, long double>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::exponential_distribution<long double>::input_type, long double>::value));
std::tr1::normal_distribution<> normd;
check_random_distribution(&normd);
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::normal_distribution<>::result_type, double>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::normal_distribution<>::input_type, double>::value));
std::tr1::normal_distribution<long double> 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<std::tr1::normal_distribution<long double>::result_type, long double>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::normal_distribution<long double>::input_type, long double>::value));
std::tr1::gamma_distribution<> gammad;
check_random_distribution(&gammad);
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::gamma_distribution<>::result_type, double>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::gamma_distribution<>::input_type, double>::value));
std::tr1::gamma_distribution<long double> gammad2(0.5L);
verify_return_type(gammad2.alpha(), (long double)(0));
check_random_distribution(&gammad2);
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::gamma_distribution<long double>::result_type, long double>::value));
BOOST_STATIC_ASSERT((::boost::is_same<std::tr1::gamma_distribution<long double>::input_type, long double>::value));
//
// variate_generator:
//
std::tr1::variate_generator<uniform_random_generator_architype&, random_distribution_architype> vg1(uniform_random_generator_architype::get(), random_distribution_architype());
check_generator(&vg1);
std::tr1::variate_generator<uniform_random_generator_architype&, std::tr1::uniform_int<> > vg2(uniform_random_generator_architype::get(), std::tr1::uniform_int<>());
check_generator_extended(&vg2);
std::tr1::variate_generator<uniform_random_generator_architype*, std::tr1::uniform_int<> > vg3(&uniform_random_generator_architype::get(), std::tr1::uniform_int<>());
check_generator_extended(&vg3);
return 0;
}