From f3a704125090af794eca0bbab60b812e407b2bfb Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 13 Oct 2011 05:28:33 +0900 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=A1=8C=E3=82=B3=E3=83=BC=E3=83=89?= =?UTF-8?q?=E7=B5=B1=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sprout/functional/hash.hpp | 16 +- sprout/functional/hash/array.hpp | 34 +- sprout/functional/hash/hash.hpp | 454 +++---- sprout/functional/hash/hash_fwd.hpp | 60 +- sprout/functional/hash/sscrisk/cel/array.hpp | 34 +- .../functional/hash/sscrisk/cel/utility.hpp | 32 +- sprout/functional/hash/string.hpp | 34 +- sprout/functional/hash/sub_array.hpp | 34 +- sprout/functional/hash_fwd.hpp | 16 +- sprout/preprocessor/stringize.hpp | 28 +- sprout/preprocessor/unique_string.hpp | 26 +- sprout/random.hpp | 34 +- sprout/random/bernoulli_distribution.hpp | 284 ++--- sprout/random/binomial_distribution.hpp | 850 ++++++------- sprout/random/detail/const_mod.hpp | 264 ++--- sprout/random/detail/ptr_helper.hpp | 146 +-- .../random/detail/signed_unsigned_tools.hpp | 126 +- sprout/random/detail/uniform_int_float.hpp | 148 +-- sprout/random/linear_congruential.hpp | 432 +++---- sprout/random/mersenne_twister.hpp | 936 +++++++-------- sprout/random/random_iterator.hpp | 652 +++++----- sprout/random/random_result.hpp | 526 ++++---- sprout/random/uniform_01.hpp | 184 +-- sprout/random/uniform_int_distribution.hpp | 1054 ++++++++--------- sprout/random/uniform_real_distribution.hpp | 638 +++++----- sprout/random/uniform_smallint.hpp | 510 ++++---- sprout/random/unique_seed.hpp | 28 +- sprout/random/variate_generator.hpp | 168 +-- sprout/utility/value_holder.hpp | 320 ++--- 29 files changed, 4034 insertions(+), 4034 deletions(-) diff --git a/sprout/functional/hash.hpp b/sprout/functional/hash.hpp index f41084ae..15e78c93 100644 --- a/sprout/functional/hash.hpp +++ b/sprout/functional/hash.hpp @@ -1,8 +1,8 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_HPP -#define SPROUT_FUNCTIONAL_HASH_HPP - -#include -#include - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP - +#ifndef SPROUT_FUNCTIONAL_HASH_HPP +#define SPROUT_FUNCTIONAL_HASH_HPP + +#include +#include + +#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP + diff --git a/sprout/functional/hash/array.hpp b/sprout/functional/hash/array.hpp index 0221183a..17455476 100644 --- a/sprout/functional/hash/array.hpp +++ b/sprout/functional/hash/array.hpp @@ -1,17 +1,17 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP -#define SPROUT_FUNCTIONAL_HASH_ARRAY_HPP - -#include -#include -#include -#include - -namespace sprout { - template - SPROUT_CONSTEXPR std::size_t hash_value(sprout::array const& v) { - return sprout::hash_range(v.begin(), v.end()); - } -} // namespace sprout - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP - +#ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP +#define SPROUT_FUNCTIONAL_HASH_ARRAY_HPP + +#include +#include +#include +#include + +namespace sprout { + template + SPROUT_CONSTEXPR std::size_t hash_value(sprout::array const& v) { + return sprout::hash_range(v.begin(), v.end()); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP + diff --git a/sprout/functional/hash/hash.hpp b/sprout/functional/hash/hash.hpp index e56a9bba..85f5ccd2 100644 --- a/sprout/functional/hash/hash.hpp +++ b/sprout/functional/hash/hash.hpp @@ -1,227 +1,227 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_HPP -#define SPROUT_FUNCTIONAL_HASH_HPP - -#include -#include -#include -#include -#include - -namespace sprout { - // - // hash_value - // - SPROUT_CONSTEXPR inline std::size_t hash_value(bool v); - SPROUT_CONSTEXPR inline std::size_t hash_value(char v); - SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v); - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v); - SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v); - SPROUT_CONSTEXPR inline std::size_t hash_value(short v); - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v); - SPROUT_CONSTEXPR inline std::size_t hash_value(int v); - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v); - SPROUT_CONSTEXPR inline std::size_t hash_value(long v); - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v); - SPROUT_CONSTEXPR inline std::size_t hash_value(long long v); - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v); - //SPROUT_CONSTEXPR std::size_t inline hash_value(float v); - //SPROUT_CONSTEXPR std::size_t inline hash_value(double v); - //SPROUT_CONSTEXPR std::size_t inline hash_value(long double v); - template - SPROUT_CONSTEXPR std::size_t hash_value(T*); - template - SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]); - - namespace hash_detail { - template - SPROUT_CONSTEXPR std::size_t hash_value_signed_2(T val, int length, std::size_t seed, T positive, std::size_t i) { - return i > 0 - ? hash_value_signed_2( - val, - length, - seed ^ static_cast((positive >> i) + (seed << 6) + (seed >> 2)), - positive, - i - std::numeric_limits::digits - ) - : seed ^ static_cast(val + (seed << 6) + (seed >> 2)) - ; - } - template - SPROUT_CONSTEXPR std::size_t hash_value_signed_1(T val, int length, std::size_t seed, T positive) { - return hash_value_signed_2(val, length, seed, positive, length * std::numeric_limits::digits); - } - template - SPROUT_CONSTEXPR std::size_t hash_value_signed(T val) { - return sprout::hash_detail::hash_value_signed_1( - val, - (std::numeric_limits::digits - 1) / std::numeric_limits::digits, - 0, - val < 0 ? -1 - val : val - ); - } - - template - SPROUT_CONSTEXPR std::size_t hash_value_unsigned_2(T val, int length, std::size_t seed, std::size_t i) { - return i > 0 - ? hash_value_unsigned_2( - val, - length, - seed ^ static_cast((val >> i) + (seed << 6) + (seed >> 2)), - i - std::numeric_limits::digits - ) - : seed ^ static_cast(val + (seed << 6) + (seed >> 2)) - ; - } - template - SPROUT_CONSTEXPR std::size_t hash_value_unsigned_1(T val, int length, std::size_t seed) { - return hash_value_unsigned_2(val, length, seed, length * std::numeric_limits::digits); - } - template - SPROUT_CONSTEXPR std::size_t hash_value_unsigned(T val) { - return sprout::hash_detail::hash_value_unsigned_1( - val, - (std::numeric_limits::digits - 1) / std::numeric_limits::digits, - 0 - ); - } - - SPROUT_CONSTEXPR inline std::size_t hash_value_pointer_1(std::size_t x) { - return x + (x >> 3); - } - template - SPROUT_CONSTEXPR std::size_t hash_value_pointer(T* v) { - return sprout::hash_detail::hash_value_pointer_1(static_cast(reinterpret_cast(v))); - } - } // namespace hash_detail - - // - // hash_value - // - SPROUT_CONSTEXPR inline std::size_t hash_value(bool v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(char v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(short v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(int v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(long v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v) { - return static_cast(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(long long v) { - return sprout::hash_detail::hash_value_signed(v); - } - SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v) { - return sprout::hash_detail::hash_value_unsigned(v); - } - template - SPROUT_CONSTEXPR std::size_t hash_value(T* v) { - return sprout::hash_detail::hash_value_pointer(v); - } - template - SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]) { - return sprout::hash_range(&v[0], &v[0] + N); - } - - // - // hash_combine - // - template - SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v) { - return seed ^ (sprout::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); - } - - // - // hash_range - // - template - SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last) { - return sprout::hash_range(0, first, last); - } - template - SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last) { - return first != last - ? sprout::hash_range(sprout::hash_combine(seed, *first), sprout::next(first), last) - : seed - ; - } - -#define SPROUT_HASH_SPECIALIZE(type) \ - template<> \ - struct hash { \ - public: \ - typedef type argument_type; \ - typedef std::size_t result_type; \ - public: \ - SPROUT_CONSTEXPR std::size_t operator()(type v) const { \ - return sprout::hash_value(v); \ - } \ - } -#define SPROUT_HASH_SPECIALIZE_REF(type) \ - template<> \ - struct hash { \ - public: \ - typedef type argument_type; \ - typedef std::size_t result_type; \ - public: \ - SPROUT_CONSTEXPR std::size_t operator()(type const& v) const { \ - return sprout::hash_value(v); \ - } \ - } - - // - // hash - // - SPROUT_HASH_SPECIALIZE(bool); - SPROUT_HASH_SPECIALIZE(char); - SPROUT_HASH_SPECIALIZE(wchar_t); - SPROUT_HASH_SPECIALIZE(signed char); - SPROUT_HASH_SPECIALIZE(unsigned char); - SPROUT_HASH_SPECIALIZE(short); - SPROUT_HASH_SPECIALIZE(unsigned short); - SPROUT_HASH_SPECIALIZE(int); - SPROUT_HASH_SPECIALIZE(unsigned int); - SPROUT_HASH_SPECIALIZE(long); - SPROUT_HASH_SPECIALIZE(unsigned long); - SPROUT_HASH_SPECIALIZE(long long); - SPROUT_HASH_SPECIALIZE(unsigned long long); - -#undef SPROUT_HASH_SPECIALIZE -#undef SPROUT_HASH_SPECIALIZE_REF - - template - struct hash { - public: - typedef T* argument_type; - typedef std::size_t result_type; - public: \ - SPROUT_CONSTEXPR std::size_t operator()(T* v) const { - return sprout::hash_value(v); - } - }; -} //namespace sprout - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP - +#ifndef SPROUT_FUNCTIONAL_HASH_HPP +#define SPROUT_FUNCTIONAL_HASH_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + // + // hash_value + // + SPROUT_CONSTEXPR inline std::size_t hash_value(bool v); + SPROUT_CONSTEXPR inline std::size_t hash_value(char v); + SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v); + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v); + SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v); + SPROUT_CONSTEXPR inline std::size_t hash_value(short v); + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v); + SPROUT_CONSTEXPR inline std::size_t hash_value(int v); + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v); + SPROUT_CONSTEXPR inline std::size_t hash_value(long v); + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v); + SPROUT_CONSTEXPR inline std::size_t hash_value(long long v); + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v); + //SPROUT_CONSTEXPR std::size_t inline hash_value(float v); + //SPROUT_CONSTEXPR std::size_t inline hash_value(double v); + //SPROUT_CONSTEXPR std::size_t inline hash_value(long double v); + template + SPROUT_CONSTEXPR std::size_t hash_value(T*); + template + SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]); + + namespace hash_detail { + template + SPROUT_CONSTEXPR std::size_t hash_value_signed_2(T val, int length, std::size_t seed, T positive, std::size_t i) { + return i > 0 + ? hash_value_signed_2( + val, + length, + seed ^ static_cast((positive >> i) + (seed << 6) + (seed >> 2)), + positive, + i - std::numeric_limits::digits + ) + : seed ^ static_cast(val + (seed << 6) + (seed >> 2)) + ; + } + template + SPROUT_CONSTEXPR std::size_t hash_value_signed_1(T val, int length, std::size_t seed, T positive) { + return hash_value_signed_2(val, length, seed, positive, length * std::numeric_limits::digits); + } + template + SPROUT_CONSTEXPR std::size_t hash_value_signed(T val) { + return sprout::hash_detail::hash_value_signed_1( + val, + (std::numeric_limits::digits - 1) / std::numeric_limits::digits, + 0, + val < 0 ? -1 - val : val + ); + } + + template + SPROUT_CONSTEXPR std::size_t hash_value_unsigned_2(T val, int length, std::size_t seed, std::size_t i) { + return i > 0 + ? hash_value_unsigned_2( + val, + length, + seed ^ static_cast((val >> i) + (seed << 6) + (seed >> 2)), + i - std::numeric_limits::digits + ) + : seed ^ static_cast(val + (seed << 6) + (seed >> 2)) + ; + } + template + SPROUT_CONSTEXPR std::size_t hash_value_unsigned_1(T val, int length, std::size_t seed) { + return hash_value_unsigned_2(val, length, seed, length * std::numeric_limits::digits); + } + template + SPROUT_CONSTEXPR std::size_t hash_value_unsigned(T val) { + return sprout::hash_detail::hash_value_unsigned_1( + val, + (std::numeric_limits::digits - 1) / std::numeric_limits::digits, + 0 + ); + } + + SPROUT_CONSTEXPR inline std::size_t hash_value_pointer_1(std::size_t x) { + return x + (x >> 3); + } + template + SPROUT_CONSTEXPR std::size_t hash_value_pointer(T* v) { + return sprout::hash_detail::hash_value_pointer_1(static_cast(reinterpret_cast(v))); + } + } // namespace hash_detail + + // + // hash_value + // + SPROUT_CONSTEXPR inline std::size_t hash_value(bool v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(char v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(short v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(int v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(long v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v) { + return static_cast(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(long long v) { + return sprout::hash_detail::hash_value_signed(v); + } + SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v) { + return sprout::hash_detail::hash_value_unsigned(v); + } + template + SPROUT_CONSTEXPR std::size_t hash_value(T* v) { + return sprout::hash_detail::hash_value_pointer(v); + } + template + SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]) { + return sprout::hash_range(&v[0], &v[0] + N); + } + + // + // hash_combine + // + template + SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v) { + return seed ^ (sprout::hash()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); + } + + // + // hash_range + // + template + SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last) { + return sprout::hash_range(0, first, last); + } + template + SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last) { + return first != last + ? sprout::hash_range(sprout::hash_combine(seed, *first), sprout::next(first), last) + : seed + ; + } + +#define SPROUT_HASH_SPECIALIZE(type) \ + template<> \ + struct hash { \ + public: \ + typedef type argument_type; \ + typedef std::size_t result_type; \ + public: \ + SPROUT_CONSTEXPR std::size_t operator()(type v) const { \ + return sprout::hash_value(v); \ + } \ + } +#define SPROUT_HASH_SPECIALIZE_REF(type) \ + template<> \ + struct hash { \ + public: \ + typedef type argument_type; \ + typedef std::size_t result_type; \ + public: \ + SPROUT_CONSTEXPR std::size_t operator()(type const& v) const { \ + return sprout::hash_value(v); \ + } \ + } + + // + // hash + // + SPROUT_HASH_SPECIALIZE(bool); + SPROUT_HASH_SPECIALIZE(char); + SPROUT_HASH_SPECIALIZE(wchar_t); + SPROUT_HASH_SPECIALIZE(signed char); + SPROUT_HASH_SPECIALIZE(unsigned char); + SPROUT_HASH_SPECIALIZE(short); + SPROUT_HASH_SPECIALIZE(unsigned short); + SPROUT_HASH_SPECIALIZE(int); + SPROUT_HASH_SPECIALIZE(unsigned int); + SPROUT_HASH_SPECIALIZE(long); + SPROUT_HASH_SPECIALIZE(unsigned long); + SPROUT_HASH_SPECIALIZE(long long); + SPROUT_HASH_SPECIALIZE(unsigned long long); + +#undef SPROUT_HASH_SPECIALIZE +#undef SPROUT_HASH_SPECIALIZE_REF + + template + struct hash { + public: + typedef T* argument_type; + typedef std::size_t result_type; + public: \ + SPROUT_CONSTEXPR std::size_t operator()(T* v) const { + return sprout::hash_value(v); + } + }; +} //namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP + diff --git a/sprout/functional/hash/hash_fwd.hpp b/sprout/functional/hash/hash_fwd.hpp index f43691b3..c442c436 100644 --- a/sprout/functional/hash/hash_fwd.hpp +++ b/sprout/functional/hash/hash_fwd.hpp @@ -1,30 +1,30 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP -#define SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP - -#include -#include - -namespace sprout { - // - // hash - // - template - struct hash; - - // - // hash_combine - // - template - SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v); - - // - // hash_range - // - template - SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last); - template - SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last); -} // namespace sprout - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP - +#ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP +#define SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP + +#include +#include + +namespace sprout { + // + // hash + // + template + struct hash; + + // + // hash_combine + // + template + SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v); + + // + // hash_range + // + template + SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last); + template + SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last); +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP + diff --git a/sprout/functional/hash/sscrisk/cel/array.hpp b/sprout/functional/hash/sscrisk/cel/array.hpp index c99ce6a1..f311c9c2 100644 --- a/sprout/functional/hash/sscrisk/cel/array.hpp +++ b/sprout/functional/hash/sscrisk/cel/array.hpp @@ -1,17 +1,17 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP -#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP - -#include -#include -#include -#include - -namespace sprout { - template - SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::array const& v) { - return sprout::hash_range(v.begin(), v.end()); - } -} // namespace sprout - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP - +#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP +#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP + +#include +#include +#include +#include + +namespace sprout { + template + SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::array const& v) { + return sprout::hash_range(v.begin(), v.end()); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP + diff --git a/sprout/functional/hash/sscrisk/cel/utility.hpp b/sprout/functional/hash/sscrisk/cel/utility.hpp index 3fe729b5..d1d206ed 100644 --- a/sprout/functional/hash/sscrisk/cel/utility.hpp +++ b/sprout/functional/hash/sscrisk/cel/utility.hpp @@ -1,16 +1,16 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP -#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP - -#include -#include -#include -#include - -namespace sprout { - template - SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::pair const& v) { - return sprout::hash_combine(sprout::hash_combine(0, v.first), v.second); - } -} // namespace sprout - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP +#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP +#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP + +#include +#include +#include +#include + +namespace sprout { + template + SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::pair const& v) { + return sprout::hash_combine(sprout::hash_combine(0, v.first), v.second); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP diff --git a/sprout/functional/hash/string.hpp b/sprout/functional/hash/string.hpp index 63a3b357..84cdea1b 100644 --- a/sprout/functional/hash/string.hpp +++ b/sprout/functional/hash/string.hpp @@ -1,17 +1,17 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP -#define SPROUT_FUNCTIONAL_HASH_STRING_HPP - -#include -#include -#include -#include - -namespace sprout { - template > - SPROUT_CONSTEXPR std::size_t hash_value(sprout::basic_string const& v) { - return sprout::hash_range(v.begin(), v.end()); - } -} // namespace sprout - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP - +#ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP +#define SPROUT_FUNCTIONAL_HASH_STRING_HPP + +#include +#include +#include +#include + +namespace sprout { + template > + SPROUT_CONSTEXPR std::size_t hash_value(sprout::basic_string const& v) { + return sprout::hash_range(v.begin(), v.end()); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP + diff --git a/sprout/functional/hash/sub_array.hpp b/sprout/functional/hash/sub_array.hpp index 8f7646ad..9ab3ac86 100644 --- a/sprout/functional/hash/sub_array.hpp +++ b/sprout/functional/hash/sub_array.hpp @@ -1,17 +1,17 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP -#define SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP - -#include -#include -#include -#include - -namespace sprout { - template - SPROUT_CONSTEXPR std::size_t hash_value(sprout::sub_array const& v) { - return sprout::hash_range(v.begin(), v.end()); - } -} // namespace sprout - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP - +#ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP +#define SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP + +#include +#include +#include +#include + +namespace sprout { + template + SPROUT_CONSTEXPR std::size_t hash_value(sprout::sub_array const& v) { + return sprout::hash_range(v.begin(), v.end()); + } +} // namespace sprout + +#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP + diff --git a/sprout/functional/hash_fwd.hpp b/sprout/functional/hash_fwd.hpp index ed65fdae..904d7dd2 100644 --- a/sprout/functional/hash_fwd.hpp +++ b/sprout/functional/hash_fwd.hpp @@ -1,8 +1,8 @@ -#ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP -#define SPROUT_FUNCTIONAL_HASH_FWD_HPP - -#include -#include - -#endif // #ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP - +#ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP +#define SPROUT_FUNCTIONAL_HASH_FWD_HPP + +#include +#include + +#endif // #ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP + diff --git a/sprout/preprocessor/stringize.hpp b/sprout/preprocessor/stringize.hpp index 374440a3..c65d4e5e 100644 --- a/sprout/preprocessor/stringize.hpp +++ b/sprout/preprocessor/stringize.hpp @@ -1,14 +1,14 @@ -#ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP -#define SPROUT_PREPROCESSOR_STRINGIZE_HPP - -#include - -#define SPROUT_PP_STRINGIZE_I(text) #text - -// -// SPROUT_PP_STRINGIZE -// -#define SPROUT_PP_STRINGIZE(text) SPROUT_PP_STRINGIZE_I(text) - -#endif // #ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP - +#ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP +#define SPROUT_PREPROCESSOR_STRINGIZE_HPP + +#include + +#define SPROUT_PP_STRINGIZE_I(text) #text + +// +// SPROUT_PP_STRINGIZE +// +#define SPROUT_PP_STRINGIZE(text) SPROUT_PP_STRINGIZE_I(text) + +#endif // #ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP + diff --git a/sprout/preprocessor/unique_string.hpp b/sprout/preprocessor/unique_string.hpp index ecf18d38..77dabca3 100644 --- a/sprout/preprocessor/unique_string.hpp +++ b/sprout/preprocessor/unique_string.hpp @@ -1,13 +1,13 @@ -#ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP -#define SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP - -#include -#include - -// -// SPROUT_PP_UNIQUE_STRING -// -#define SPROUT_PP_UNIQUE_STRING __DATE__ " " __TIME__ " : " __FILE__ "(" SPROUT_PP_STRINGIZE(__LINE__) ")" - -#endif // #ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP - +#ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP +#define SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP + +#include +#include + +// +// SPROUT_PP_UNIQUE_STRING +// +#define SPROUT_PP_UNIQUE_STRING __DATE__ " " __TIME__ " : " __FILE__ "(" SPROUT_PP_STRINGIZE(__LINE__) ")" + +#endif // #ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP + diff --git a/sprout/random.hpp b/sprout/random.hpp index 4e2a1375..390727cf 100644 --- a/sprout/random.hpp +++ b/sprout/random.hpp @@ -1,17 +1,17 @@ -#ifndef SPROUT_RANDOM_HPP -#define SPROUT_RANDOM_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#endif // #ifndef SPROUT_RANDOM_HPP +#ifndef SPROUT_RANDOM_HPP +#define SPROUT_RANDOM_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // #ifndef SPROUT_RANDOM_HPP diff --git a/sprout/random/bernoulli_distribution.hpp b/sprout/random/bernoulli_distribution.hpp index c94a7d09..bedaa84d 100644 --- a/sprout/random/bernoulli_distribution.hpp +++ b/sprout/random/bernoulli_distribution.hpp @@ -1,142 +1,142 @@ -#ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP -#define SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP - -#include -#include -#include - -namespace sprout { - namespace random { - // - // bernoulli_distribution - // - template - class bernoulli_distribution { - public: - typedef int input_type; - typedef bool result_type; - private: - static SPROUT_CONSTEXPR RealType arg_check(RealType p_arg) { - return p_arg >= 0 && p_arg <= 1 - ? p_arg - : throw "assert(p_arg >= 0 && p_arg <= 1)" - ; - } - public: - // - // param_type - // - class param_type { - public: - typedef bernoulli_distribution distribution_type; - private: - RealType p_; - public: - SPROUT_CONSTEXPR param_type() - : p_(RealType(0.5)) - {} - SPROUT_CONSTEXPR explicit param_type(RealType p_arg = RealType(0.5)) - : p_(arg_check(p_arg)) - {} - SPROUT_CONSTEXPR RealType p() const { - return p_; - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - param_type const& rhs - ) - { - return lhs >> rhs.p_; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - param_type const& rhs - ) - { - return lhs << rhs.p_; - } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { - return lhs.p_ == rhs.p_; - } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { - return !(lhs == rhs); - } - }; - private: - RealType p_; - private: - template - SPROUT_CONSTEXPR sprout::random::random_result generate( - sprout::random::random_result const& rnd - ) const - { - return sprout::random::random_result( - RealType(rnd.result() - rnd.engine().min()) <= p_ * RealType(rnd.engine().max() - rnd.engine().min()), - rnd.engine(), - *this - ); - } - public: - SPROUT_CONSTEXPR bernoulli_distribution() - : p_(RealType(0.5)) - {} - SPROUT_CONSTEXPR explicit bernoulli_distribution(RealType p_arg = RealType(0.5)) - : p_(arg_check(p_arg)) - {} - SPROUT_CONSTEXPR RealType p() const { - return p_; - } - SPROUT_CONSTEXPR result_type min() const { - return false; - } - SPROUT_CONSTEXPR result_type max() const { - return true; - } - SPROUT_CONSTEXPR param_type param() const { - return param_type(p_); - } - void param(param_type const& parm) { - p_ = parm.p(); - } - template - SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { - return p_ == RealType(0) - ? sprout::random::random_result(false, eng, *this) - : generate(eng()) - ; - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - bernoulli_distribution const& rhs - ) - { - param_type parm; - return lhs >> parm; - param(parm); - return lhs; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - bernoulli_distribution const& rhs - ) - { - return lhs << param(); - } - SPROUT_CONSTEXPR friend bool operator==(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { - return lhs.param() == rhs.param(); - } - SPROUT_CONSTEXPR friend bool operator!=(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { - return !(lhs == rhs); - } - }; - } // namespace random - - using sprout::random::bernoulli_distribution; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP - +#ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP +#define SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP + +#include +#include +#include + +namespace sprout { + namespace random { + // + // bernoulli_distribution + // + template + class bernoulli_distribution { + public: + typedef int input_type; + typedef bool result_type; + private: + static SPROUT_CONSTEXPR RealType arg_check(RealType p_arg) { + return p_arg >= 0 && p_arg <= 1 + ? p_arg + : throw "assert(p_arg >= 0 && p_arg <= 1)" + ; + } + public: + // + // param_type + // + class param_type { + public: + typedef bernoulli_distribution distribution_type; + private: + RealType p_; + public: + SPROUT_CONSTEXPR param_type() + : p_(RealType(0.5)) + {} + SPROUT_CONSTEXPR explicit param_type(RealType p_arg = RealType(0.5)) + : p_(arg_check(p_arg)) + {} + SPROUT_CONSTEXPR RealType p() const { + return p_; + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + param_type const& rhs + ) + { + return lhs >> rhs.p_; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + param_type const& rhs + ) + { + return lhs << rhs.p_; + } + SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + return lhs.p_ == rhs.p_; + } + SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + return !(lhs == rhs); + } + }; + private: + RealType p_; + private: + template + SPROUT_CONSTEXPR sprout::random::random_result generate( + sprout::random::random_result const& rnd + ) const + { + return sprout::random::random_result( + RealType(rnd.result() - rnd.engine().min()) <= p_ * RealType(rnd.engine().max() - rnd.engine().min()), + rnd.engine(), + *this + ); + } + public: + SPROUT_CONSTEXPR bernoulli_distribution() + : p_(RealType(0.5)) + {} + SPROUT_CONSTEXPR explicit bernoulli_distribution(RealType p_arg = RealType(0.5)) + : p_(arg_check(p_arg)) + {} + SPROUT_CONSTEXPR RealType p() const { + return p_; + } + SPROUT_CONSTEXPR result_type min() const { + return false; + } + SPROUT_CONSTEXPR result_type max() const { + return true; + } + SPROUT_CONSTEXPR param_type param() const { + return param_type(p_); + } + void param(param_type const& parm) { + p_ = parm.p(); + } + template + SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { + return p_ == RealType(0) + ? sprout::random::random_result(false, eng, *this) + : generate(eng()) + ; + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + bernoulli_distribution const& rhs + ) + { + param_type parm; + return lhs >> parm; + param(parm); + return lhs; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + bernoulli_distribution const& rhs + ) + { + return lhs << param(); + } + SPROUT_CONSTEXPR friend bool operator==(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { + return lhs.param() == rhs.param(); + } + SPROUT_CONSTEXPR friend bool operator!=(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { + return !(lhs == rhs); + } + }; + } // namespace random + + using sprout::random::bernoulli_distribution; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP + diff --git a/sprout/random/binomial_distribution.hpp b/sprout/random/binomial_distribution.hpp index 009d4d28..610d78d9 100644 --- a/sprout/random/binomial_distribution.hpp +++ b/sprout/random/binomial_distribution.hpp @@ -1,425 +1,425 @@ -#ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP -#define SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP - -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - namespace detail { - template - struct binomial_table { - public: - SPROUT_STATIC_CONSTEXPR sprout::array table = sprout::array{{ - 0.08106146679532726, - 0.04134069595540929, - 0.02767792568499834, - 0.02079067210376509, - 0.01664469118982119, - 0.01387612882307075, - 0.01189670994589177, - 0.01041126526197209, - 0.009255462182712733, - 0.008330563433362871 - }}; - }; - template - SPROUT_CONSTEXPR sprout::array sprout::random::detail::binomial_table::table; - } // namespace detail - // - // binomial_distribution - // - template - class binomial_distribution { - public: - typedef RealType input_type; - typedef IntType result_type; - private: - struct btrd_type { - public: - RealType r; - RealType nr; - RealType npq; - RealType b; - RealType a; - RealType c; - RealType alpha; - RealType v_r; - RealType u_rv_r; - }; - private: - static SPROUT_CONSTEXPR IntType arg_check(IntType t_arg, RealType p_arg) { - return t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1) - ? t_arg - : throw "assert(t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1))" - ; - } - public: - // - // param_type - // - class param_type { - public: - typedef binomial_distribution distribution_type; - private: - IntType t_; - RealType p_; - public: - SPROUT_CONSTEXPR param_type() - : t_(1) - , p_(0.5) - {} - SPROUT_CONSTEXPR explicit param_type(IntType t_arg, RealType p_arg = RealType(0.5)) - : t_(arg_check(t_arg, p_arg)) - , p_(p_arg) - {} - SPROUT_CONSTEXPR IntType t() const { - return t_; - } - SPROUT_CONSTEXPR RealType p() const { - return p_; - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - param_type const& rhs - ) - { - return lhs >> rhs.t_ >> std::ws >> rhs.p_; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - param_type const& rhs - ) - { - return lhs << rhs.t_ << " " << rhs.p_; - } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { - return lhs.t_ == rhs.t_ && lhs.p_ == rhs.p_; - } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { - return !(lhs == rhs); - } - }; - private: - static SPROUT_CONSTEXPR IntType init_t(IntType t) { - return t; - } - static SPROUT_CONSTEXPR RealType init_p(RealType p) { - return RealType(0.5) < p ? 1 - p : p; - } - static SPROUT_CONSTEXPR IntType init_m(IntType t, RealType p) { - return static_cast((init_t(t) + 1) * init_p(p)); - } - static SPROUT_CONSTEXPR btrd_type init_btrd_6(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType b, RealType a, RealType c, RealType alpha, RealType v_r) { - return btrd_type { - r, - nr, - npq, - b, - a, - c, - alpha, - v_r, - RealType(0.86) * v_r - }; - } - static SPROUT_CONSTEXPR btrd_type init_btrd_5(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType sqrt_npq, RealType b) { - return init_btrd_6(t, p, r, nr, npq, b, RealType(-0.0873) + RealType(0.0248) * b + RealType(0.01) * p, t * p + RealType(0.5), (RealType(2.83) + RealType(5.1) / b) * sqrt_npq, RealType(0.92) - RealType(4.2) / b); - } - static SPROUT_CONSTEXPR btrd_type init_btrd_4(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType sqrt_npq) { - return init_btrd_5(t, p, r, nr, npq, sqrt_npq, RealType(1.15) + RealType(2.53) * sqrt_npq); - } - static SPROUT_CONSTEXPR btrd_type init_btrd_3(IntType t, RealType p, RealType r, RealType nr, RealType npq) { - using std::sqrt; - return init_btrd_4(t, p, r, nr, npq, sqrt(npq)); - } - static SPROUT_CONSTEXPR btrd_type init_btrd_2(IntType t, RealType p, RealType r) { - return init_btrd_3(t, p, r, (t + 1) * r, t * p * (1 - p)); - } - static SPROUT_CONSTEXPR btrd_type init_btrd_1(IntType t, RealType p) { - return init_btrd_2(t, p, p / (1 - p)); - } - static SPROUT_CONSTEXPR btrd_type init_btrd(IntType t, RealType p) { - return init_btrd_1(init_t(t), init_p(p)); - } - static SPROUT_CONSTEXPR RealType init_q_n(IntType t, RealType p) { - using std::pow; - return pow(1 - init_p(p), static_cast(init_t(t))); - } - static SPROUT_CONSTEXPR bool init_use_inversion(IntType t, RealType p) { - return init_m(t, p) < 11; - } - static SPROUT_CONSTEXPR RealType fc_1(RealType ikp1) { - return (RealType(1) / 12 - (RealType(1) / 360 - (RealType(1) / 1260) * (ikp1 * ikp1)) * (ikp1 * ikp1)) * ikp1; - } - static SPROUT_CONSTEXPR RealType fc(IntType k) { - return k < 10 - ? sprout::random::detail::binomial_table::table[k] - : fc_1(RealType(1) / (k + 1)) - ; - } - private: - IntType t_; - RealType p_; - IntType m_; - btrd_type btrd_; - RealType q_n_; - private: - SPROUT_CONSTEXPR bool use_inversion() const { - return m_ < 11; - } - template - SPROUT_CONSTEXPR sprout::random::random_result invert_4(Engine const& eng, RealType u, RealType q, RealType s, RealType a, RealType r, IntType x = 0) const { - return u > r - ? invert_4(eng, u - r, q, s, a, ((a / (x + 1)) - s) * r, x + 1) - : sprout::random::random_result(x, eng, *this) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result invert_3(IntType t, Engine const& eng, RealType u, RealType q, RealType s) const { - return invert_4(eng, u, q, s, (t + 1) * s, q_n_); - } - template - SPROUT_CONSTEXPR sprout::random::random_result invert_2(IntType t, RealType p, Engine const& eng, RealType u, RealType q) const { - return invert_3(t, eng, u, q, p / q); - } - template - SPROUT_CONSTEXPR sprout::random::random_result invert_1(IntType t, RealType p, Engine const& eng, RealType u) const { - return invert_2(t, p, eng, u, 1 - p); - } - template - SPROUT_CONSTEXPR sprout::random::random_result invert_0(IntType t, RealType p, Random const& rnd) const { - return invert_1(t, p, rnd.engine(), rnd.result()); - } - template - SPROUT_CONSTEXPR sprout::random::random_result invert(IntType t, RealType p, Engine const& eng) const { - return invert_0(t, p, sprout::random::uniform_01()(eng)); - } - template - SPROUT_CONSTEXPR sprout::random::random_result invert2_0(IntType t, sprout::random::random_result const& rnd) const { - return sprout::random::random_result(t - rnd.result(), rnd.engine(), rnd.distribution()); - } - template - SPROUT_CONSTEXPR sprout::random::random_result invert2(IntType t, RealType p, Engine const& eng) const { - return invert2_0(t, invert(t, p, eng)); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_10(Engine const& eng, RealType v, IntType k, IntType nm, RealType h, IntType nk) const { - using std::log; - return v <= h + (t_ + 1) * log(static_cast(nm) / nk) + (k + RealType(0.5)) * log(nk * btrd_.r / (k + 1))- fc(k)- fc(t_ - k) - ? sprout::random::random_result(k, eng, *this) - : generate(eng) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_9(Engine const& eng, RealType v, IntType k, IntType nm) const { - using std::log; - return generate_10(eng, v, k, nm, (m_ + RealType(0.5)) * log((m_ + 1) / (btrd_.r * nm)) + fc(m_) + fc(t_ - m_), t_ - k + 1); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_8(Engine const& eng, RealType v, IntType k, RealType rho, RealType t) const { - return v < t - rho ? sprout::random::random_result(k, eng, *this) - : v > t + rho ? generate(eng) - : generate_9(eng, v, k, t_ - m_ + 1) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_7_3(Engine const& eng, RealType v, IntType k, RealType f) const { - return v <= f - ? sprout::random::random_result(k, eng, *this) - : generate(eng) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_7_2(Engine const& eng, RealType v, IntType k, RealType f, IntType i) const { - return i != k - ? generate_7_2(eng, v * (btrd_.nr / (i + 1) - btrd_.r), k, f, i + 1) - : generate_7_3(eng, v, k, f) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_7_1(Engine const& eng, RealType v, IntType k, RealType f, IntType i) const { - return i != k - ? generate_7_1(eng, v, k, f * (btrd_.nr / (i + 1) - btrd_.r), i + 1) - : generate_7_3(eng, v, k, f) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_7(Engine const& eng, RealType v, IntType k, RealType f = RealType(1)) const { - return m_ < k ? generate_7_1(eng, v, k, f * (btrd_.nr / (m_ + 1) - btrd_.r), m_ + 1) - : m_ > k ? generate_7_2(eng, v * (btrd_.nr / (k + 1) - btrd_.r), k, f, k + 1) - : generate_7_3(eng, v, k, f) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_6(Engine const& eng, RealType v, IntType k, RealType km) const { - using std::log; - return km <= 15 - ? generate_7(eng, v, k) - : generate_8(eng, log(v), k, (km / btrd_.npq) * (((km / RealType(3.0) + RealType(0.625)) * km + RealType(1.0) / 6) / btrd_.npq + RealType(0.5)), -km * km / (2 * btrd_.npq)) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_5(Engine const& eng, RealType v, RealType u, RealType us, IntType k) const { - using std::abs; - return k < 0 || k > t_ - ? generate(eng) - : generate_6(eng, v * btrd_.alpha / (btrd_.a / (us * us) + btrd_.b), k, abs(k - m_)) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_4(Engine const& eng, RealType v, RealType u, RealType us) const { - using std::floor; - return generate_5(eng, v, u, us, static_cast(floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c))); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_3(Engine const& eng, RealType v, RealType u) const { - using std::abs; - return generate_4(eng, v, u, 0.5 - abs(u)); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_2(Random const& rnd, RealType v) const { - return v >= btrd_.v_r - ? generate_3( - rnd.engine(), - v, - rnd.result() - RealType(0.5) - ) - : generate_3( - rnd.engine(), - rnd.result() * btrd_.v_r, - ((v / btrd_.v_r - RealType(0.93)) < 0 ? RealType(-0.5) : RealType(0.5)) - (v / btrd_.v_r - RealType(0.93)) - ) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_1_1(Engine const& eng, RealType u) const { - using std::floor; - using std::abs; - return sprout::random::random_result( - static_cast(floor((2 * btrd_.a / (RealType(0.5) - abs(u)) + btrd_.b) * u + btrd_.c)), - eng, - *this - ); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_1(Engine const& eng, RealType v) const { - return v <= btrd_.u_rv_r - ? generate_1_1(eng, v / btrd_.v_r - RealType(0.43)) - : generate_2(sprout::random::uniform_01()(eng), v) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_0(Random const& rnd) const { - return generate_1(rnd.engine(), rnd.result()); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate(Engine const& eng) const { - return generate_0(sprout::random::uniform_01()(eng)); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate2_0(IntType t, sprout::random::random_result const& rnd) const { - return sprout::random::random_result(t - rnd.result(), rnd.engine(), rnd.distribution()); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate2(IntType t, Engine const& eng) const { - return generate2_0(t, generate(eng)); - } - void init() { - m_ = init_m(t_, p_); - if (use_inversion()) { - q_n_ = init_q_n(t_, p_); - } else { - btrd_ = init_btrd(t_, p_); - } - } - public: - SPROUT_CONSTEXPR binomial_distribution() - : t_(1) - , p_(RealType(0.5)) - , m_(init_m(1, RealType(0.5))) - , btrd_(!init_use_inversion(1, RealType(0.5)) ? init_btrd(1, RealType(0.5)) : btrd_type()) - , q_n_(init_use_inversion(1, RealType(0.5)) ? init_q_n(1, RealType(0.5)) : RealType()) - {} - SPROUT_CONSTEXPR explicit binomial_distribution(IntType t_arg, RealType p_arg = RealType(0.5)) - : t_(arg_check(t_arg, p_arg)) - , p_(p_arg) - , m_(init_m(t_arg, p_arg)) - , btrd_(!init_use_inversion(t_arg, p_arg) ? init_btrd(t_arg, p_arg) : btrd_type()) - , q_n_(init_use_inversion(t_arg, p_arg) ? init_q_n(t_arg, p_arg) : RealType()) - {} - SPROUT_CONSTEXPR explicit binomial_distribution(param_type const& parm) - : t_(parm.t()) - , p_(parm.p()) - , m_(init_m(parm.t(), parm.p())) - , btrd_(!init_use_inversion(parm.t(), parm.p()) ? init_btrd(parm.t(), parm.p()) : btrd_type()) - , q_n_(init_use_inversion(parm.t(), parm.p()) ? init_q_n(parm.t(), parm.p()) : RealType()) - {} - SPROUT_CONSTEXPR result_type t() const { - return t_; - } - SPROUT_CONSTEXPR result_type p() const { - return p_; - } - SPROUT_CONSTEXPR result_type min() const { - return 0; - } - SPROUT_CONSTEXPR result_type max() const { - return t_; - } - SPROUT_CONSTEXPR param_type param() const { - return param_type(t_, p_); - } - void param(param_type const& parm) { - t_ = parm.a(); - p_ = parm.b(); - init(); - } - template - SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { - return use_inversion() ? RealType(0.5) < p_ - ? invert2(t_, 1 - p_, eng) - : invert(t_, p_, eng) - : RealType(0.5) < p_ ? generate2(t_, eng) - : generate(eng) - ; - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - binomial_distribution const& rhs - ) - { - param_type parm; - return lhs >> parm; - param(parm); - return lhs; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - binomial_distribution const& rhs - ) - { - return lhs << param(); - } - SPROUT_CONSTEXPR friend bool operator==(binomial_distribution const& lhs, binomial_distribution const& rhs) { - return lhs.param() == rhs.param(); - } - SPROUT_CONSTEXPR friend bool operator!=(binomial_distribution const& lhs, binomial_distribution const& rhs) { - return !(lhs == rhs); - } - }; - } // namespace random - - using sprout::random::binomial_distribution; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP - +#ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP +#define SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + namespace detail { + template + struct binomial_table { + public: + SPROUT_STATIC_CONSTEXPR sprout::array table = sprout::array{{ + 0.08106146679532726, + 0.04134069595540929, + 0.02767792568499834, + 0.02079067210376509, + 0.01664469118982119, + 0.01387612882307075, + 0.01189670994589177, + 0.01041126526197209, + 0.009255462182712733, + 0.008330563433362871 + }}; + }; + template + SPROUT_CONSTEXPR sprout::array sprout::random::detail::binomial_table::table; + } // namespace detail + // + // binomial_distribution + // + template + class binomial_distribution { + public: + typedef RealType input_type; + typedef IntType result_type; + private: + struct btrd_type { + public: + RealType r; + RealType nr; + RealType npq; + RealType b; + RealType a; + RealType c; + RealType alpha; + RealType v_r; + RealType u_rv_r; + }; + private: + static SPROUT_CONSTEXPR IntType arg_check(IntType t_arg, RealType p_arg) { + return t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1) + ? t_arg + : throw "assert(t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1))" + ; + } + public: + // + // param_type + // + class param_type { + public: + typedef binomial_distribution distribution_type; + private: + IntType t_; + RealType p_; + public: + SPROUT_CONSTEXPR param_type() + : t_(1) + , p_(0.5) + {} + SPROUT_CONSTEXPR explicit param_type(IntType t_arg, RealType p_arg = RealType(0.5)) + : t_(arg_check(t_arg, p_arg)) + , p_(p_arg) + {} + SPROUT_CONSTEXPR IntType t() const { + return t_; + } + SPROUT_CONSTEXPR RealType p() const { + return p_; + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + param_type const& rhs + ) + { + return lhs >> rhs.t_ >> std::ws >> rhs.p_; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + param_type const& rhs + ) + { + return lhs << rhs.t_ << " " << rhs.p_; + } + SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + return lhs.t_ == rhs.t_ && lhs.p_ == rhs.p_; + } + SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + return !(lhs == rhs); + } + }; + private: + static SPROUT_CONSTEXPR IntType init_t(IntType t) { + return t; + } + static SPROUT_CONSTEXPR RealType init_p(RealType p) { + return RealType(0.5) < p ? 1 - p : p; + } + static SPROUT_CONSTEXPR IntType init_m(IntType t, RealType p) { + return static_cast((init_t(t) + 1) * init_p(p)); + } + static SPROUT_CONSTEXPR btrd_type init_btrd_6(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType b, RealType a, RealType c, RealType alpha, RealType v_r) { + return btrd_type { + r, + nr, + npq, + b, + a, + c, + alpha, + v_r, + RealType(0.86) * v_r + }; + } + static SPROUT_CONSTEXPR btrd_type init_btrd_5(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType sqrt_npq, RealType b) { + return init_btrd_6(t, p, r, nr, npq, b, RealType(-0.0873) + RealType(0.0248) * b + RealType(0.01) * p, t * p + RealType(0.5), (RealType(2.83) + RealType(5.1) / b) * sqrt_npq, RealType(0.92) - RealType(4.2) / b); + } + static SPROUT_CONSTEXPR btrd_type init_btrd_4(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType sqrt_npq) { + return init_btrd_5(t, p, r, nr, npq, sqrt_npq, RealType(1.15) + RealType(2.53) * sqrt_npq); + } + static SPROUT_CONSTEXPR btrd_type init_btrd_3(IntType t, RealType p, RealType r, RealType nr, RealType npq) { + using std::sqrt; + return init_btrd_4(t, p, r, nr, npq, sqrt(npq)); + } + static SPROUT_CONSTEXPR btrd_type init_btrd_2(IntType t, RealType p, RealType r) { + return init_btrd_3(t, p, r, (t + 1) * r, t * p * (1 - p)); + } + static SPROUT_CONSTEXPR btrd_type init_btrd_1(IntType t, RealType p) { + return init_btrd_2(t, p, p / (1 - p)); + } + static SPROUT_CONSTEXPR btrd_type init_btrd(IntType t, RealType p) { + return init_btrd_1(init_t(t), init_p(p)); + } + static SPROUT_CONSTEXPR RealType init_q_n(IntType t, RealType p) { + using std::pow; + return pow(1 - init_p(p), static_cast(init_t(t))); + } + static SPROUT_CONSTEXPR bool init_use_inversion(IntType t, RealType p) { + return init_m(t, p) < 11; + } + static SPROUT_CONSTEXPR RealType fc_1(RealType ikp1) { + return (RealType(1) / 12 - (RealType(1) / 360 - (RealType(1) / 1260) * (ikp1 * ikp1)) * (ikp1 * ikp1)) * ikp1; + } + static SPROUT_CONSTEXPR RealType fc(IntType k) { + return k < 10 + ? sprout::random::detail::binomial_table::table[k] + : fc_1(RealType(1) / (k + 1)) + ; + } + private: + IntType t_; + RealType p_; + IntType m_; + btrd_type btrd_; + RealType q_n_; + private: + SPROUT_CONSTEXPR bool use_inversion() const { + return m_ < 11; + } + template + SPROUT_CONSTEXPR sprout::random::random_result invert_4(Engine const& eng, RealType u, RealType q, RealType s, RealType a, RealType r, IntType x = 0) const { + return u > r + ? invert_4(eng, u - r, q, s, a, ((a / (x + 1)) - s) * r, x + 1) + : sprout::random::random_result(x, eng, *this) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result invert_3(IntType t, Engine const& eng, RealType u, RealType q, RealType s) const { + return invert_4(eng, u, q, s, (t + 1) * s, q_n_); + } + template + SPROUT_CONSTEXPR sprout::random::random_result invert_2(IntType t, RealType p, Engine const& eng, RealType u, RealType q) const { + return invert_3(t, eng, u, q, p / q); + } + template + SPROUT_CONSTEXPR sprout::random::random_result invert_1(IntType t, RealType p, Engine const& eng, RealType u) const { + return invert_2(t, p, eng, u, 1 - p); + } + template + SPROUT_CONSTEXPR sprout::random::random_result invert_0(IntType t, RealType p, Random const& rnd) const { + return invert_1(t, p, rnd.engine(), rnd.result()); + } + template + SPROUT_CONSTEXPR sprout::random::random_result invert(IntType t, RealType p, Engine const& eng) const { + return invert_0(t, p, sprout::random::uniform_01()(eng)); + } + template + SPROUT_CONSTEXPR sprout::random::random_result invert2_0(IntType t, sprout::random::random_result const& rnd) const { + return sprout::random::random_result(t - rnd.result(), rnd.engine(), rnd.distribution()); + } + template + SPROUT_CONSTEXPR sprout::random::random_result invert2(IntType t, RealType p, Engine const& eng) const { + return invert2_0(t, invert(t, p, eng)); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_10(Engine const& eng, RealType v, IntType k, IntType nm, RealType h, IntType nk) const { + using std::log; + return v <= h + (t_ + 1) * log(static_cast(nm) / nk) + (k + RealType(0.5)) * log(nk * btrd_.r / (k + 1))- fc(k)- fc(t_ - k) + ? sprout::random::random_result(k, eng, *this) + : generate(eng) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_9(Engine const& eng, RealType v, IntType k, IntType nm) const { + using std::log; + return generate_10(eng, v, k, nm, (m_ + RealType(0.5)) * log((m_ + 1) / (btrd_.r * nm)) + fc(m_) + fc(t_ - m_), t_ - k + 1); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_8(Engine const& eng, RealType v, IntType k, RealType rho, RealType t) const { + return v < t - rho ? sprout::random::random_result(k, eng, *this) + : v > t + rho ? generate(eng) + : generate_9(eng, v, k, t_ - m_ + 1) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_7_3(Engine const& eng, RealType v, IntType k, RealType f) const { + return v <= f + ? sprout::random::random_result(k, eng, *this) + : generate(eng) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_7_2(Engine const& eng, RealType v, IntType k, RealType f, IntType i) const { + return i != k + ? generate_7_2(eng, v * (btrd_.nr / (i + 1) - btrd_.r), k, f, i + 1) + : generate_7_3(eng, v, k, f) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_7_1(Engine const& eng, RealType v, IntType k, RealType f, IntType i) const { + return i != k + ? generate_7_1(eng, v, k, f * (btrd_.nr / (i + 1) - btrd_.r), i + 1) + : generate_7_3(eng, v, k, f) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_7(Engine const& eng, RealType v, IntType k, RealType f = RealType(1)) const { + return m_ < k ? generate_7_1(eng, v, k, f * (btrd_.nr / (m_ + 1) - btrd_.r), m_ + 1) + : m_ > k ? generate_7_2(eng, v * (btrd_.nr / (k + 1) - btrd_.r), k, f, k + 1) + : generate_7_3(eng, v, k, f) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_6(Engine const& eng, RealType v, IntType k, RealType km) const { + using std::log; + return km <= 15 + ? generate_7(eng, v, k) + : generate_8(eng, log(v), k, (km / btrd_.npq) * (((km / RealType(3.0) + RealType(0.625)) * km + RealType(1.0) / 6) / btrd_.npq + RealType(0.5)), -km * km / (2 * btrd_.npq)) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_5(Engine const& eng, RealType v, RealType u, RealType us, IntType k) const { + using std::abs; + return k < 0 || k > t_ + ? generate(eng) + : generate_6(eng, v * btrd_.alpha / (btrd_.a / (us * us) + btrd_.b), k, abs(k - m_)) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_4(Engine const& eng, RealType v, RealType u, RealType us) const { + using std::floor; + return generate_5(eng, v, u, us, static_cast(floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c))); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_3(Engine const& eng, RealType v, RealType u) const { + using std::abs; + return generate_4(eng, v, u, 0.5 - abs(u)); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_2(Random const& rnd, RealType v) const { + return v >= btrd_.v_r + ? generate_3( + rnd.engine(), + v, + rnd.result() - RealType(0.5) + ) + : generate_3( + rnd.engine(), + rnd.result() * btrd_.v_r, + ((v / btrd_.v_r - RealType(0.93)) < 0 ? RealType(-0.5) : RealType(0.5)) - (v / btrd_.v_r - RealType(0.93)) + ) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_1_1(Engine const& eng, RealType u) const { + using std::floor; + using std::abs; + return sprout::random::random_result( + static_cast(floor((2 * btrd_.a / (RealType(0.5) - abs(u)) + btrd_.b) * u + btrd_.c)), + eng, + *this + ); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_1(Engine const& eng, RealType v) const { + return v <= btrd_.u_rv_r + ? generate_1_1(eng, v / btrd_.v_r - RealType(0.43)) + : generate_2(sprout::random::uniform_01()(eng), v) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_0(Random const& rnd) const { + return generate_1(rnd.engine(), rnd.result()); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate(Engine const& eng) const { + return generate_0(sprout::random::uniform_01()(eng)); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate2_0(IntType t, sprout::random::random_result const& rnd) const { + return sprout::random::random_result(t - rnd.result(), rnd.engine(), rnd.distribution()); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate2(IntType t, Engine const& eng) const { + return generate2_0(t, generate(eng)); + } + void init() { + m_ = init_m(t_, p_); + if (use_inversion()) { + q_n_ = init_q_n(t_, p_); + } else { + btrd_ = init_btrd(t_, p_); + } + } + public: + SPROUT_CONSTEXPR binomial_distribution() + : t_(1) + , p_(RealType(0.5)) + , m_(init_m(1, RealType(0.5))) + , btrd_(!init_use_inversion(1, RealType(0.5)) ? init_btrd(1, RealType(0.5)) : btrd_type()) + , q_n_(init_use_inversion(1, RealType(0.5)) ? init_q_n(1, RealType(0.5)) : RealType()) + {} + SPROUT_CONSTEXPR explicit binomial_distribution(IntType t_arg, RealType p_arg = RealType(0.5)) + : t_(arg_check(t_arg, p_arg)) + , p_(p_arg) + , m_(init_m(t_arg, p_arg)) + , btrd_(!init_use_inversion(t_arg, p_arg) ? init_btrd(t_arg, p_arg) : btrd_type()) + , q_n_(init_use_inversion(t_arg, p_arg) ? init_q_n(t_arg, p_arg) : RealType()) + {} + SPROUT_CONSTEXPR explicit binomial_distribution(param_type const& parm) + : t_(parm.t()) + , p_(parm.p()) + , m_(init_m(parm.t(), parm.p())) + , btrd_(!init_use_inversion(parm.t(), parm.p()) ? init_btrd(parm.t(), parm.p()) : btrd_type()) + , q_n_(init_use_inversion(parm.t(), parm.p()) ? init_q_n(parm.t(), parm.p()) : RealType()) + {} + SPROUT_CONSTEXPR result_type t() const { + return t_; + } + SPROUT_CONSTEXPR result_type p() const { + return p_; + } + SPROUT_CONSTEXPR result_type min() const { + return 0; + } + SPROUT_CONSTEXPR result_type max() const { + return t_; + } + SPROUT_CONSTEXPR param_type param() const { + return param_type(t_, p_); + } + void param(param_type const& parm) { + t_ = parm.a(); + p_ = parm.b(); + init(); + } + template + SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { + return use_inversion() ? RealType(0.5) < p_ + ? invert2(t_, 1 - p_, eng) + : invert(t_, p_, eng) + : RealType(0.5) < p_ ? generate2(t_, eng) + : generate(eng) + ; + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + binomial_distribution const& rhs + ) + { + param_type parm; + return lhs >> parm; + param(parm); + return lhs; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + binomial_distribution const& rhs + ) + { + return lhs << param(); + } + SPROUT_CONSTEXPR friend bool operator==(binomial_distribution const& lhs, binomial_distribution const& rhs) { + return lhs.param() == rhs.param(); + } + SPROUT_CONSTEXPR friend bool operator!=(binomial_distribution const& lhs, binomial_distribution const& rhs) { + return !(lhs == rhs); + } + }; + } // namespace random + + using sprout::random::binomial_distribution; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP + diff --git a/sprout/random/detail/const_mod.hpp b/sprout/random/detail/const_mod.hpp index 2bcc2bb9..a36b6ce0 100644 --- a/sprout/random/detail/const_mod.hpp +++ b/sprout/random/detail/const_mod.hpp @@ -1,132 +1,132 @@ -#ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP -#define SPROUT_RANDOM_DETAIL_CONST_MOD_HPP - -#include -#include -#include - -namespace sprout { - namespace random { - namespace detail { - template - class const_mod { - private: - typedef typename std::make_unsigned::type unsigned_type; - private: - SPROUT_STATIC_CONSTEXPR IntType suppress_warnings = m == 0; - SPROUT_STATIC_CONSTEXPR IntType modulus = m + suppress_warnings; - private: - static_assert(suppress_warnings == 0, "suppress_warnings == 0"); - static_assert(modulus == m, "modulus == m"); - private: - static SPROUT_CONSTEXPR IntType pow_1(IntType a, std::uintmax_t exponent, IntType result = 1) { - return exponent != 0 - ? pow_1(mult(a, a), exponent / 2, exponent % 2 == 1 ? mult(result, a) : result) - : result - ; - } - static SPROUT_CONSTEXPR IntType mult_small(IntType a, IntType x) { - return a * x % (m + suppress_warnings); - } - static SPROUT_CONSTEXPR IntType mult_schrage_1(IntType a, IntType value, IntType q, IntType r) { - return r < q - ? sub(a * (value % q), r * (value / q)) - : throw "assert(r < q)" - ; - } - static SPROUT_CONSTEXPR IntType mult_schrage(IntType a, IntType value) { - return mult_schrage_1(a, value, m / a, m % a); - } - static SPROUT_CONSTEXPR IntType mult_general(IntType a, IntType b) { - return std::uintmax_t(modulus) <= std::numeric_limits::max() / modulus - ? static_cast(std::uintmax_t(a) * b % modulus) - : /*static_cast(sprout::random::detail::mulmod(a, b, modulus))*/throw "Sorry, not implemented." - ; - } - static SPROUT_CONSTEXPR IntType sub(IntType a, IntType b) { - return a < b ? m - (b - a) : a - b; - } - static SPROUT_CONSTEXPR unsigned_type unsigned_m() { - return m == 0 ? unsigned_type((std::numeric_limits::max)()) + 1 : unsigned_type(m); - } - static SPROUT_CONSTEXPR IntType invert_euclidian_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { - return n == 0 ? m - l1 : invert_euclidian_1(c, l1, l2, n, p); - } - static SPROUT_CONSTEXPR IntType invert_euclidian_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) { - return p == 0 ? l2 : invert_euclidian_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p); - } - static SPROUT_CONSTEXPR IntType invert_euclidian_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) { - return invert_euclidian_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n); - } - static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) { - return c > 0 - ? c == 1 ? 1 : invert_euclidian_1(c, 0, 1, c, m) - : throw "assert(c > 0)" - ; - } - static SPROUT_CONSTEXPR IntType invert_euclidian0_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { - return n == 0 ? m - l1 : invert_euclidian0_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n); - } - static SPROUT_CONSTEXPR IntType invert_euclidian0_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) { - return p == 0 ? l2 : invert_euclidian0_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p); - } - static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) { - return std::numeric_limits::max() % n != n - 1 - ? invert_euclidian0_2(c, l1 + (std::numeric_limits::max() / n) * l2, l2, n, std::numeric_limits::max() - (std::numeric_limits::max() / n) * n + 1) - : throw "assert(std::numeric_limits::max() % n != n - 1)" - ; - } - static SPROUT_CONSTEXPR IntType invert_euclidian0(IntType c) { - return c > 0 - ? c == 1 ? 1 : invert_euclidian0_1(c, 0, 1, c, m) - : throw "assert(c > 0)" - ; - } - public: - static SPROUT_CONSTEXPR IntType apply(IntType x) { - return ((unsigned_m() - 1) & unsigned_m()) == 0 - ? (unsigned_type(x)) & (unsigned_m() - 1) - : x % (m + suppress_warnings) - ; - } - static SPROUT_CONSTEXPR IntType add(IntType x, IntType c) { - return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1) - : c == 0 ? x - : x < m - c ? x + c - : x - (m - c) - ; - } - static SPROUT_CONSTEXPR IntType mult(IntType a, IntType x) { - return ((unsigned_m() - 1) & unsigned_m()) == 0 ? unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1) - : a == 0 ? 0 - : a == 1 ? x - : m <= std::numeric_limits::max() / a ? mult_small(a, x) - : std::numeric_limits::is_signed && (m % a < m / a) ? mult_schrage(a, x) - : mult_general(a, x) - ; - } - static SPROUT_CONSTEXPR IntType mult_add(IntType a, IntType x, IntType c) { - return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1) - : a == 0 ? c - : m <= (std::numeric_limits::max() - c) / a ? (a * x + c) % (m + suppress_warnings) - : add(mult(a, x), c) - ; - } - static SPROUT_CONSTEXPR IntType pow(IntType a, std::uintmax_t exponent) { - return pow_1(a, exponent); - } - static SPROUT_CONSTEXPR IntType invert(IntType x) { - return x == 0 ? 0 - : m == 0 ? invert_euclidian0(x) - : invert_euclidian(x) - ; - } - private: - const_mod() = delete; - }; - } // namespace detail - } // namespace random -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP - +#ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP +#define SPROUT_RANDOM_DETAIL_CONST_MOD_HPP + +#include +#include +#include + +namespace sprout { + namespace random { + namespace detail { + template + class const_mod { + private: + typedef typename std::make_unsigned::type unsigned_type; + private: + SPROUT_STATIC_CONSTEXPR IntType suppress_warnings = m == 0; + SPROUT_STATIC_CONSTEXPR IntType modulus = m + suppress_warnings; + private: + static_assert(suppress_warnings == 0, "suppress_warnings == 0"); + static_assert(modulus == m, "modulus == m"); + private: + static SPROUT_CONSTEXPR IntType pow_1(IntType a, std::uintmax_t exponent, IntType result = 1) { + return exponent != 0 + ? pow_1(mult(a, a), exponent / 2, exponent % 2 == 1 ? mult(result, a) : result) + : result + ; + } + static SPROUT_CONSTEXPR IntType mult_small(IntType a, IntType x) { + return a * x % (m + suppress_warnings); + } + static SPROUT_CONSTEXPR IntType mult_schrage_1(IntType a, IntType value, IntType q, IntType r) { + return r < q + ? sub(a * (value % q), r * (value / q)) + : throw "assert(r < q)" + ; + } + static SPROUT_CONSTEXPR IntType mult_schrage(IntType a, IntType value) { + return mult_schrage_1(a, value, m / a, m % a); + } + static SPROUT_CONSTEXPR IntType mult_general(IntType a, IntType b) { + return std::uintmax_t(modulus) <= std::numeric_limits::max() / modulus + ? static_cast(std::uintmax_t(a) * b % modulus) + : /*static_cast(sprout::random::detail::mulmod(a, b, modulus))*/throw "Sorry, not implemented." + ; + } + static SPROUT_CONSTEXPR IntType sub(IntType a, IntType b) { + return a < b ? m - (b - a) : a - b; + } + static SPROUT_CONSTEXPR unsigned_type unsigned_m() { + return m == 0 ? unsigned_type((std::numeric_limits::max)()) + 1 : unsigned_type(m); + } + static SPROUT_CONSTEXPR IntType invert_euclidian_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return n == 0 ? m - l1 : invert_euclidian_1(c, l1, l2, n, p); + } + static SPROUT_CONSTEXPR IntType invert_euclidian_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return p == 0 ? l2 : invert_euclidian_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p); + } + static SPROUT_CONSTEXPR IntType invert_euclidian_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return invert_euclidian_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n); + } + static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) { + return c > 0 + ? c == 1 ? 1 : invert_euclidian_1(c, 0, 1, c, m) + : throw "assert(c > 0)" + ; + } + static SPROUT_CONSTEXPR IntType invert_euclidian0_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return n == 0 ? m - l1 : invert_euclidian0_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n); + } + static SPROUT_CONSTEXPR IntType invert_euclidian0_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return p == 0 ? l2 : invert_euclidian0_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p); + } + static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) { + return std::numeric_limits::max() % n != n - 1 + ? invert_euclidian0_2(c, l1 + (std::numeric_limits::max() / n) * l2, l2, n, std::numeric_limits::max() - (std::numeric_limits::max() / n) * n + 1) + : throw "assert(std::numeric_limits::max() % n != n - 1)" + ; + } + static SPROUT_CONSTEXPR IntType invert_euclidian0(IntType c) { + return c > 0 + ? c == 1 ? 1 : invert_euclidian0_1(c, 0, 1, c, m) + : throw "assert(c > 0)" + ; + } + public: + static SPROUT_CONSTEXPR IntType apply(IntType x) { + return ((unsigned_m() - 1) & unsigned_m()) == 0 + ? (unsigned_type(x)) & (unsigned_m() - 1) + : x % (m + suppress_warnings) + ; + } + static SPROUT_CONSTEXPR IntType add(IntType x, IntType c) { + return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1) + : c == 0 ? x + : x < m - c ? x + c + : x - (m - c) + ; + } + static SPROUT_CONSTEXPR IntType mult(IntType a, IntType x) { + return ((unsigned_m() - 1) & unsigned_m()) == 0 ? unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1) + : a == 0 ? 0 + : a == 1 ? x + : m <= std::numeric_limits::max() / a ? mult_small(a, x) + : std::numeric_limits::is_signed && (m % a < m / a) ? mult_schrage(a, x) + : mult_general(a, x) + ; + } + static SPROUT_CONSTEXPR IntType mult_add(IntType a, IntType x, IntType c) { + return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1) + : a == 0 ? c + : m <= (std::numeric_limits::max() - c) / a ? (a * x + c) % (m + suppress_warnings) + : add(mult(a, x), c) + ; + } + static SPROUT_CONSTEXPR IntType pow(IntType a, std::uintmax_t exponent) { + return pow_1(a, exponent); + } + static SPROUT_CONSTEXPR IntType invert(IntType x) { + return x == 0 ? 0 + : m == 0 ? invert_euclidian0(x) + : invert_euclidian(x) + ; + } + private: + const_mod() = delete; + }; + } // namespace detail + } // namespace random +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP + diff --git a/sprout/random/detail/ptr_helper.hpp b/sprout/random/detail/ptr_helper.hpp index bfc9469b..16436bb9 100644 --- a/sprout/random/detail/ptr_helper.hpp +++ b/sprout/random/detail/ptr_helper.hpp @@ -1,73 +1,73 @@ -#ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP -#define SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP - -#include - -namespace sprout { - namespace random { - namespace detail { - template - struct ptr_helper { - typedef T value_type; - typedef T& reference_type; - typedef T const& const_reference_type; - typedef T const& rvalue_type; - static reference_type ref(T& r) { - return r; - } - static SPROUT_CONSTEXPR const_reference_type ref(T const& r) { - return r; - } - }; - template - struct ptr_helper { - typedef T value_type; - typedef T& reference_type; - typedef T const& const_reference_type; - typedef T& rvalue_type; - static reference_type ref(T& r) { - return r; - } - static SPROUT_CONSTEXPR const_reference_type ref(T const& r) { - return r; - } - }; - template - struct ptr_helper { - typedef T value_type; - typedef T const& reference_type; - typedef T const& const_reference_type; - typedef T const& rvalue_type; - static SPROUT_CONSTEXPR const_reference_type ref(T const& r) { - return r; - } - }; - template - struct ptr_helper { - typedef T value_type; - typedef T& reference_type; - typedef T const& const_reference_type; - typedef T* rvalue_type; - static reference_type ref(T* p) { - return *p; - } - static SPROUT_CONSTEXPR const_reference_type ref(T const* p) { - return *p; - } - }; - template - struct ptr_helper { - typedef T value_type; - typedef T const& reference_type; - typedef T const& const_reference_type; - typedef T const* rvalue_type; - static SPROUT_CONSTEXPR const_reference_type ref(T const* p) { - return *p; - } - }; - } // namespace detail - } // namespace random -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP - +#ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP +#define SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP + +#include + +namespace sprout { + namespace random { + namespace detail { + template + struct ptr_helper { + typedef T value_type; + typedef T& reference_type; + typedef T const& const_reference_type; + typedef T const& rvalue_type; + static reference_type ref(T& r) { + return r; + } + static SPROUT_CONSTEXPR const_reference_type ref(T const& r) { + return r; + } + }; + template + struct ptr_helper { + typedef T value_type; + typedef T& reference_type; + typedef T const& const_reference_type; + typedef T& rvalue_type; + static reference_type ref(T& r) { + return r; + } + static SPROUT_CONSTEXPR const_reference_type ref(T const& r) { + return r; + } + }; + template + struct ptr_helper { + typedef T value_type; + typedef T const& reference_type; + typedef T const& const_reference_type; + typedef T const& rvalue_type; + static SPROUT_CONSTEXPR const_reference_type ref(T const& r) { + return r; + } + }; + template + struct ptr_helper { + typedef T value_type; + typedef T& reference_type; + typedef T const& const_reference_type; + typedef T* rvalue_type; + static reference_type ref(T* p) { + return *p; + } + static SPROUT_CONSTEXPR const_reference_type ref(T const* p) { + return *p; + } + }; + template + struct ptr_helper { + typedef T value_type; + typedef T const& reference_type; + typedef T const& const_reference_type; + typedef T const* rvalue_type; + static SPROUT_CONSTEXPR const_reference_type ref(T const* p) { + return *p; + } + }; + } // namespace detail + } // namespace random +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP + diff --git a/sprout/random/detail/signed_unsigned_tools.hpp b/sprout/random/detail/signed_unsigned_tools.hpp index cd8eeb96..85b16f7d 100644 --- a/sprout/random/detail/signed_unsigned_tools.hpp +++ b/sprout/random/detail/signed_unsigned_tools.hpp @@ -1,63 +1,63 @@ -#ifndef SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP -#define SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP - -#include -#include -#include - -namespace sprout { - namespace random { - namespace detail { - template::is_signed> - struct subtract {}; - template - struct subtract { - public: - typedef T result_type; - public: - SPROUT_CONSTEXPR result_type operator()(T x, T y) const { - return x - y; - } - }; - template - struct subtract { - public: - typedef typename std::make_unsigned::type result_type; - public: - SPROUT_CONSTEXPR result_type operator()(T x, T y) const { - return y >= 0 ? result_type(x) - result_type(y) - : x >= 0 ? result_type(x) + result_type(-(y + 1)) + 1 - : result_type(x - y) - ; - } - }; - - template::is_signed> - struct add {}; - template - struct add { - public: - typedef T2 result_type; - public: - SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const { - return T2(x) + y; - } - }; - template - struct add { - public: - typedef T2 result_type; - public: - SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const { - return y >= 0 ? T2(x) + y - : x >= T1(-(y + 1)) ? T2(x - T1(-(y + 1)) - 1) - : T2(x) + y - ; - } - }; - } // namespace detail - } // namespace random -} // namespace sprout - -#endif // SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP - +#ifndef SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP +#define SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP + +#include +#include +#include + +namespace sprout { + namespace random { + namespace detail { + template::is_signed> + struct subtract {}; + template + struct subtract { + public: + typedef T result_type; + public: + SPROUT_CONSTEXPR result_type operator()(T x, T y) const { + return x - y; + } + }; + template + struct subtract { + public: + typedef typename std::make_unsigned::type result_type; + public: + SPROUT_CONSTEXPR result_type operator()(T x, T y) const { + return y >= 0 ? result_type(x) - result_type(y) + : x >= 0 ? result_type(x) + result_type(-(y + 1)) + 1 + : result_type(x - y) + ; + } + }; + + template::is_signed> + struct add {}; + template + struct add { + public: + typedef T2 result_type; + public: + SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const { + return T2(x) + y; + } + }; + template + struct add { + public: + typedef T2 result_type; + public: + SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const { + return y >= 0 ? T2(x) + y + : x >= T1(-(y + 1)) ? T2(x - T1(-(y + 1)) - 1) + : T2(x) + y + ; + } + }; + } // namespace detail + } // namespace random +} // namespace sprout + +#endif // SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP + diff --git a/sprout/random/detail/uniform_int_float.hpp b/sprout/random/detail/uniform_int_float.hpp index dfb456eb..6a49ba1e 100644 --- a/sprout/random/detail/uniform_int_float.hpp +++ b/sprout/random/detail/uniform_int_float.hpp @@ -1,74 +1,74 @@ -#ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP -#define SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP - -#include -#include -#include -#include -#include -#include -#include -#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT_DETAIL - -namespace sprout { - namespace random { - namespace detail { - template - class uniform_int_float { - public: - typedef URNG base_type; - typedef typename base_type::result_type base_result; - typedef typename sprout::detail::uint_t< - (std::numeric_limits::digits < std::numeric_limits::digits) - ? std::numeric_limits::digits - : std::numeric_limits::digits - >::fast result_type; - private: - base_type rng_; - public: - //uniform_int_float = default; // ??? - SPROUT_CONSTEXPR uniform_int_float() - : rng_() - {} - SPROUT_CONSTEXPR explicit uniform_int_float(base_type const& rng) - : rng_(rng) - {} - SPROUT_CONSTEXPR result_type min() const { - return 0; - } - SPROUT_CONSTEXPR result_type max() const { - return ( - result_type(2) << ( - NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min( - std::numeric_limits::digits, - sprout::random::detail::generator_bits::value() - ) - 1 - ) - ) - 1 - ; - } - base_type& base() { - return rng_; - } - SPROUT_CONSTEXPR base_type const& base() const { - return rng_; - } - SPROUT_CONSTEXPR sprout::random::random_result generate( - sprout::random::random_result const& rnd - ) const - { - return sprout::random::random_result( - static_cast(rnd.result() * (static_cast(max()) + 1)), - uniform_int_float(rnd.engine()) - ); - } - SPROUT_CONSTEXPR sprout::random::random_result operator()() const { - return generate(rng_()); - } - }; - } // namespace detail - } // namespace random -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP - +#ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP +#define SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT_DETAIL + +namespace sprout { + namespace random { + namespace detail { + template + class uniform_int_float { + public: + typedef URNG base_type; + typedef typename base_type::result_type base_result; + typedef typename sprout::detail::uint_t< + (std::numeric_limits::digits < std::numeric_limits::digits) + ? std::numeric_limits::digits + : std::numeric_limits::digits + >::fast result_type; + private: + base_type rng_; + public: + //uniform_int_float = default; // ??? + SPROUT_CONSTEXPR uniform_int_float() + : rng_() + {} + SPROUT_CONSTEXPR explicit uniform_int_float(base_type const& rng) + : rng_(rng) + {} + SPROUT_CONSTEXPR result_type min() const { + return 0; + } + SPROUT_CONSTEXPR result_type max() const { + return ( + result_type(2) << ( + NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min( + std::numeric_limits::digits, + sprout::random::detail::generator_bits::value() + ) - 1 + ) + ) - 1 + ; + } + base_type& base() { + return rng_; + } + SPROUT_CONSTEXPR base_type const& base() const { + return rng_; + } + SPROUT_CONSTEXPR sprout::random::random_result generate( + sprout::random::random_result const& rnd + ) const + { + return sprout::random::random_result( + static_cast(rnd.result() * (static_cast(max()) + 1)), + uniform_int_float(rnd.engine()) + ); + } + SPROUT_CONSTEXPR sprout::random::random_result operator()() const { + return generate(rng_()); + } + }; + } // namespace detail + } // namespace random +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP + diff --git a/sprout/random/linear_congruential.hpp b/sprout/random/linear_congruential.hpp index 794f247e..a6a00385 100644 --- a/sprout/random/linear_congruential.hpp +++ b/sprout/random/linear_congruential.hpp @@ -1,216 +1,216 @@ -#ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP -#define SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP - -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - // - // linear_congruential_engine - // - template - class linear_congruential_engine { - public: - typedef IntType result_type; - private: - struct private_constructor_tag {}; - public: - SPROUT_STATIC_CONSTEXPR IntType multiplier = a; - SPROUT_STATIC_CONSTEXPR IntType increment = c; - SPROUT_STATIC_CONSTEXPR IntType modulus = m; - SPROUT_STATIC_CONSTEXPR IntType default_seed = 1; - public: - static_assert(std::numeric_limits::is_integer, "std::numeric_limits::is_integer"); - static_assert(m == 0 || a < m, "m == 0 || a < m"); - static_assert(m == 0 || c < m, "m == 0 || c < m"); - private: - static SPROUT_CONSTEXPR IntType init_seed_3(IntType const& x0) { - return x0 >= static_min() && x0 <= static_max() - ? x0 - : throw "assert(x0 >= static_min() && x0 <= static_max())" - ; - } - static SPROUT_CONSTEXPR IntType init_seed_2(IntType const& x0) { - return init_seed_3(increment == 0 && x0 == 0 ? 1 : x0); - } - static SPROUT_CONSTEXPR IntType init_seed_1(IntType const& x0) { - return init_seed_2(x0 <= 0 && x0 != 0 ? x0 + modulus : x0); - } - static SPROUT_CONSTEXPR IntType init_seed(IntType const& x0) { - return init_seed_1(modulus == 0 ? x0 : x0 % modulus); - } - public: - static SPROUT_CONSTEXPR result_type static_min() { - return c == 0 ? 1 : 0; - } - static SPROUT_CONSTEXPR result_type static_max() { - return modulus - 1; - } - private: - IntType x_; - private: - SPROUT_CONSTEXPR linear_congruential_engine(IntType const& x, private_constructor_tag) - : x_(x) - {} - SPROUT_CONSTEXPR sprout::random::random_result generate(result_type result) const { - return sprout::random::random_result( - result, - linear_congruential_engine(result, private_constructor_tag()) - ); - } - public: - SPROUT_CONSTEXPR linear_congruential_engine() - : x_(init_seed(default_seed)) - {} - SPROUT_CONSTEXPR explicit linear_congruential_engine(IntType const& x0) - : x_(init_seed(x0)) - {} - SPROUT_CONSTEXPR result_type min() const { - return static_min(); - } - SPROUT_CONSTEXPR result_type max() const { - return static_max(); - } - SPROUT_CONSTEXPR sprout::random::random_result operator()() const { - return generate(sprout::random::detail::const_mod::mult_add(a, x_, c)); - } - friend SPROUT_CONSTEXPR bool operator==(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) { - return lhs.x_ == rhs.x_; - } - friend SPROUT_CONSTEXPR bool operator!=(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) { - return !(lhs == rhs); - } - template - friend std::basic_istream& operator>>( - std::basic_istream& lhs, - linear_congruential_engine const& rhs - ) - { - IntType x; - if(lhs >> x) { - if(x >= min() && x <= max()) { - rhs.x_ = x; - } else { - lhs.setstate(std::ios_base::failbit); - } - } - return lhs; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - linear_congruential_engine const& rhs - ) - { - return lhs << rhs.x_; - } - }; - template - SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine::multiplier; - template - SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine::increment; - template - SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine::modulus; - template - SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine::default_seed; - - // - // minstd_rand0 - // - typedef sprout::random::linear_congruential_engine minstd_rand0; - // - // minstd_rand - // - typedef sprout::random::linear_congruential_engine minstd_rand; - - // - // rand48 - // - class rand48 { - public: - typedef std::uint32_t result_type; - private: - struct private_constructor_tag {}; - typedef sprout::random::linear_congruential_engine< - std::uint64_t, - std::uint64_t(0xDEECE66DUL) | (std::uint64_t(0x5) << 32), - 0xB, - std::uint64_t(1) << 48 - > lcf_type; - public: - static SPROUT_CONSTEXPR result_type static_min() { - return 0; - } - static SPROUT_CONSTEXPR result_type static_max() { - return 0x7FFFFFFF; - } - static SPROUT_CONSTEXPR std::uint64_t cnv(std::uint32_t x) { - return (static_cast(x) << 16) | 0x330e; - } - private: - lcf_type lcf_; - private: - SPROUT_CONSTEXPR rand48(lcf_type const& lcf, private_constructor_tag) - : lcf_(lcf) - {} - SPROUT_CONSTEXPR sprout::random::random_result generate( - sprout::random::random_result const& lcf_result - ) const - { - return sprout::random::random_result( - lcf_result.result() >> 17, - rand48(lcf_result.engine(), private_constructor_tag()) - ); - } - public: - SPROUT_CONSTEXPR rand48() - : lcf_(cnv(static_cast(1))) - {} - SPROUT_CONSTEXPR explicit rand48(result_type const& x0) - : lcf_(cnv(x0)) - {} - SPROUT_CONSTEXPR result_type min() const { - return static_min(); - } - SPROUT_CONSTEXPR result_type max() const { - return static_max(); - } - SPROUT_CONSTEXPR sprout::random::random_result operator()() const { - return generate(lcf_()); - } - friend SPROUT_CONSTEXPR bool operator==(rand48 const& lhs, rand48 const& rhs) { - return lhs.lcf_ == rhs.lcf_; - } - friend SPROUT_CONSTEXPR bool operator!=(rand48 const& lhs, rand48 const& rhs) { - return !(lhs == rhs); - } - template - friend std::basic_istream& operator>>( - std::basic_istream& lhs, - rand48 const& rhs - ) - { - return lhs >> rhs.lcf_; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - rand48 const& rhs - ) - { - return lhs << rhs.lcf_; - } - }; - } // namespace random - - using sprout::random::minstd_rand0; - using sprout::random::minstd_rand; - using sprout::random::rand48; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP +#ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP +#define SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // linear_congruential_engine + // + template + class linear_congruential_engine { + public: + typedef IntType result_type; + private: + struct private_constructor_tag {}; + public: + SPROUT_STATIC_CONSTEXPR IntType multiplier = a; + SPROUT_STATIC_CONSTEXPR IntType increment = c; + SPROUT_STATIC_CONSTEXPR IntType modulus = m; + SPROUT_STATIC_CONSTEXPR IntType default_seed = 1; + public: + static_assert(std::numeric_limits::is_integer, "std::numeric_limits::is_integer"); + static_assert(m == 0 || a < m, "m == 0 || a < m"); + static_assert(m == 0 || c < m, "m == 0 || c < m"); + private: + static SPROUT_CONSTEXPR IntType init_seed_3(IntType const& x0) { + return x0 >= static_min() && x0 <= static_max() + ? x0 + : throw "assert(x0 >= static_min() && x0 <= static_max())" + ; + } + static SPROUT_CONSTEXPR IntType init_seed_2(IntType const& x0) { + return init_seed_3(increment == 0 && x0 == 0 ? 1 : x0); + } + static SPROUT_CONSTEXPR IntType init_seed_1(IntType const& x0) { + return init_seed_2(x0 <= 0 && x0 != 0 ? x0 + modulus : x0); + } + static SPROUT_CONSTEXPR IntType init_seed(IntType const& x0) { + return init_seed_1(modulus == 0 ? x0 : x0 % modulus); + } + public: + static SPROUT_CONSTEXPR result_type static_min() { + return c == 0 ? 1 : 0; + } + static SPROUT_CONSTEXPR result_type static_max() { + return modulus - 1; + } + private: + IntType x_; + private: + SPROUT_CONSTEXPR linear_congruential_engine(IntType const& x, private_constructor_tag) + : x_(x) + {} + SPROUT_CONSTEXPR sprout::random::random_result generate(result_type result) const { + return sprout::random::random_result( + result, + linear_congruential_engine(result, private_constructor_tag()) + ); + } + public: + SPROUT_CONSTEXPR linear_congruential_engine() + : x_(init_seed(default_seed)) + {} + SPROUT_CONSTEXPR explicit linear_congruential_engine(IntType const& x0) + : x_(init_seed(x0)) + {} + SPROUT_CONSTEXPR result_type min() const { + return static_min(); + } + SPROUT_CONSTEXPR result_type max() const { + return static_max(); + } + SPROUT_CONSTEXPR sprout::random::random_result operator()() const { + return generate(sprout::random::detail::const_mod::mult_add(a, x_, c)); + } + friend SPROUT_CONSTEXPR bool operator==(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) { + return lhs.x_ == rhs.x_; + } + friend SPROUT_CONSTEXPR bool operator!=(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) { + return !(lhs == rhs); + } + template + friend std::basic_istream& operator>>( + std::basic_istream& lhs, + linear_congruential_engine const& rhs + ) + { + IntType x; + if(lhs >> x) { + if(x >= min() && x <= max()) { + rhs.x_ = x; + } else { + lhs.setstate(std::ios_base::failbit); + } + } + return lhs; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + linear_congruential_engine const& rhs + ) + { + return lhs << rhs.x_; + } + }; + template + SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine::multiplier; + template + SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine::increment; + template + SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine::modulus; + template + SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine::default_seed; + + // + // minstd_rand0 + // + typedef sprout::random::linear_congruential_engine minstd_rand0; + // + // minstd_rand + // + typedef sprout::random::linear_congruential_engine minstd_rand; + + // + // rand48 + // + class rand48 { + public: + typedef std::uint32_t result_type; + private: + struct private_constructor_tag {}; + typedef sprout::random::linear_congruential_engine< + std::uint64_t, + std::uint64_t(0xDEECE66DUL) | (std::uint64_t(0x5) << 32), + 0xB, + std::uint64_t(1) << 48 + > lcf_type; + public: + static SPROUT_CONSTEXPR result_type static_min() { + return 0; + } + static SPROUT_CONSTEXPR result_type static_max() { + return 0x7FFFFFFF; + } + static SPROUT_CONSTEXPR std::uint64_t cnv(std::uint32_t x) { + return (static_cast(x) << 16) | 0x330e; + } + private: + lcf_type lcf_; + private: + SPROUT_CONSTEXPR rand48(lcf_type const& lcf, private_constructor_tag) + : lcf_(lcf) + {} + SPROUT_CONSTEXPR sprout::random::random_result generate( + sprout::random::random_result const& lcf_result + ) const + { + return sprout::random::random_result( + lcf_result.result() >> 17, + rand48(lcf_result.engine(), private_constructor_tag()) + ); + } + public: + SPROUT_CONSTEXPR rand48() + : lcf_(cnv(static_cast(1))) + {} + SPROUT_CONSTEXPR explicit rand48(result_type const& x0) + : lcf_(cnv(x0)) + {} + SPROUT_CONSTEXPR result_type min() const { + return static_min(); + } + SPROUT_CONSTEXPR result_type max() const { + return static_max(); + } + SPROUT_CONSTEXPR sprout::random::random_result operator()() const { + return generate(lcf_()); + } + friend SPROUT_CONSTEXPR bool operator==(rand48 const& lhs, rand48 const& rhs) { + return lhs.lcf_ == rhs.lcf_; + } + friend SPROUT_CONSTEXPR bool operator!=(rand48 const& lhs, rand48 const& rhs) { + return !(lhs == rhs); + } + template + friend std::basic_istream& operator>>( + std::basic_istream& lhs, + rand48 const& rhs + ) + { + return lhs >> rhs.lcf_; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + rand48 const& rhs + ) + { + return lhs << rhs.lcf_; + } + }; + } // namespace random + + using sprout::random::minstd_rand0; + using sprout::random::minstd_rand; + using sprout::random::rand48; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP diff --git a/sprout/random/mersenne_twister.hpp b/sprout/random/mersenne_twister.hpp index 11927330..61381c65 100644 --- a/sprout/random/mersenne_twister.hpp +++ b/sprout/random/mersenne_twister.hpp @@ -1,468 +1,468 @@ -#ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP -#define SPROUT_RANDOM_MERSENNE_TWISTER_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - // - // mersenne_twister_engine - // - template - class mersenne_twister_engine { - public: - typedef UIntType result_type; - private: - struct private_constructor_tag {}; - public: - SPROUT_STATIC_CONSTEXPR std::size_t word_size = w; - SPROUT_STATIC_CONSTEXPR std::size_t state_size = n; - SPROUT_STATIC_CONSTEXPR std::size_t shift_size = m; - SPROUT_STATIC_CONSTEXPR std::size_t mask_bits = r; - SPROUT_STATIC_CONSTEXPR UIntType xor_mask = a; - SPROUT_STATIC_CONSTEXPR std::size_t tempering_u = u; - SPROUT_STATIC_CONSTEXPR UIntType tempering_d = d; - SPROUT_STATIC_CONSTEXPR std::size_t tempering_s = s; - SPROUT_STATIC_CONSTEXPR UIntType tempering_b = b; - SPROUT_STATIC_CONSTEXPR std::size_t tempering_t = t; - SPROUT_STATIC_CONSTEXPR UIntType tempering_c = c; - SPROUT_STATIC_CONSTEXPR std::size_t tempering_l = l; - SPROUT_STATIC_CONSTEXPR UIntType initialization_multiplier = f; - SPROUT_STATIC_CONSTEXPR UIntType default_seed = 5489u; - private: - SPROUT_STATIC_CONSTEXPR UIntType upper_mask = (~static_cast(0)) << r; - SPROUT_STATIC_CONSTEXPR UIntType lower_mask = ~upper_mask; - SPROUT_STATIC_CONSTEXPR std::size_t unroll_factor = 6; - SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra1 = (n - m) % unroll_factor; - SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra2 = (m - 1) % unroll_factor; - private: - template - static SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) + 1 == n, - sprout::array - >::type init_seed_1(UIntType const& value, Args const&... args) { - return sprout::array{{args..., value}}; - } - template - static SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) + 1 < n, - sprout::array - >::type init_seed_1(UIntType const& value, Args const&... args) { - return init_seed_1( - (f * (value ^ (value >> (w - 2))) + (sizeof...(Args) + 1)) & static_max(), - args..., - value - ); - } - static SPROUT_CONSTEXPR sprout::array init_seed(UIntType const& value) { - return init_seed_1(value & static_max()); - } - public: - static SPROUT_CONSTEXPR result_type static_min() { - return 0; - } - static SPROUT_CONSTEXPR result_type static_max() { - return sprout::detail::low_bits_mask_t::sig_bits; - } - private: - sprout::array x_; - std::size_t i_; - private: - SPROUT_CONSTEXPR mersenne_twister_engine(sprout::array const& x, std::size_t i, private_constructor_tag) - : x_(x) - , i_(i) - {} - SPROUT_CONSTEXPR UIntType rewind_find_1(UIntType const* last, std::size_t size, std::size_t index) const { - return index < n - size - ? x_[index] - : *(last - (n - 1 - index)) - ; - } - SPROUT_CONSTEXPR UIntType rewind_find(UIntType const* last, std::size_t size, std::size_t i) const { - return rewind_find_1(last, size, (i + n - size + n - 1) % n); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == n, - sprout::array - >::type rewind_finish_1(sprout::array const& data, Args const&... args) const { - return sprout::array{{args...}}; - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < n, - sprout::array - >::type rewind_finish_1(sprout::array const& data, Args const&... args) const { - return rewind_finish_1(data, args..., data[sizeof...(args)]); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == n, - sprout::array - >::type rewind_finish(sprout::array const& data, UIntType const* last, std::size_t z, std::size_t i, Args const&... args) const { - return sprout::array{{args...}}; - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < n, - sprout::array - >::type rewind_finish(sprout::array const& data, UIntType const* last, std::size_t z, std::size_t i, Args const&... args) const { - return &data[0] + i == last - z - ? rewind_finish_1(data, data[i], args...) - : rewind_finish(data, last, z, i + 1, data[i], args...) - ; - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == n, - sprout::array - >::type rewind_4(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { - return sprout::array{{args...}}; - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < n, - sprout::array - >::type rewind_4(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { - return rewind_2( - data, - last, - z, - y1, - i, - (y0 & upper_mask) | (y1 & lower_mask), - args... - ); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == n, - sprout::array - >::type rewind_3(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { - return sprout::array{{args...}}; - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < n, - sprout::array - >::type rewind_3(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { - return rewind_4( - data, - last, - z, - y0, - y1 & (static_cast(1) << (w - 1)) - ? ((y1 ^ a) << 1) | 1 - : y1 << 1 - , - i, - args... - ); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == n, - sprout::array - >::type rewind_2(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, std::size_t i, Args const&... args) const { - return sprout::array{{args...}}; - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < n, - sprout::array - >::type rewind_2(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, std::size_t i, Args const&... args) const { - return i < z - ? rewind_3(data, last, z, y0, rewind_find(last, i, m - 1) ^ rewind_find(last, i, n - 1), i, args...) - : rewind_finish(data, last, z, 0, args...) - ; - } - SPROUT_CONSTEXPR sprout::array rewind_1(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0) const { - return rewind_2( - data, - last, - z, - y0 & (static_cast(1) << (w - 1)) - ? ((y0 ^ a) << 1) | 1 - : y0 << 1 - , - 0 - ); - } - SPROUT_CONSTEXPR sprout::array rewind(sprout::array const& data, UIntType const* last, std::size_t z) const { - return rewind_1(data, last, z, x_[m - 1] ^ x_[n - 1]); - } - SPROUT_CONSTEXPR bool equal_impl_2(mersenne_twister_engine const& other, sprout::array back, std::size_t offset, std::size_t i = 0) const { - return i < offset - ? back[i + n - offset] != other.x_[i] - ? false - : equal_impl_2(other, back, offset, i + 1) - : true - ; - } - SPROUT_CONSTEXPR bool equal_impl_1(mersenne_twister_engine const& other, sprout::array back, std::size_t offset, std::size_t i = 0) const { - return i + offset < n - ? x_[i] != other.x_[i + offset] - ? false - : equal_impl_1(other, back, offset, i + 1) - : equal_impl_2(other, rewind(back, &back[n - 1], offset), offset) - ; - } - SPROUT_CONSTEXPR bool equal_impl(mersenne_twister_engine const& other) const { - return equal_impl_1(other, sprout::array(), other.i_ - i_); - } - SPROUT_CONSTEXPR UIntType generate_impl_4(UIntType z) const { - return z ^ (z >> l); - } - SPROUT_CONSTEXPR UIntType generate_impl_3(UIntType z) const { - return z ^ generate_impl_4((z << t) & c); - } - SPROUT_CONSTEXPR UIntType generate_impl_2(UIntType z) const { - return z ^ generate_impl_3((z << s) & b); - } - SPROUT_CONSTEXPR UIntType generate_impl_1(UIntType z) const { - return z ^ generate_impl_2((z >> u) & d); - } - SPROUT_CONSTEXPR UIntType generate_impl() const { - return generate_impl_1(x_[i_]); - } - SPROUT_CONSTEXPR sprout::random::random_result generate() const { - return sprout::random::random_result( - generate_impl(), - mersenne_twister_engine( - x_, - i_ + 1, - private_constructor_tag() - ) - ); - } - template - SPROUT_CONSTEXPR mersenne_twister_engine twist_5(Args const&... args) const { - return mersenne_twister_engine( - sprout::array{{args..., x_[m - 1] ^ ((x_[n - 1] & upper_mask) | (x_[0] & lower_mask) >> 1) ^ ((x_[0] & 1) * a)}}, - 0, - private_constructor_tag() - ); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == n - 1, - mersenne_twister_engine - >::type twist_4(std::size_t i, Args const&... args) const { - return twist_5(args...); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < n - 1, - mersenne_twister_engine - >::type twist_4(std::size_t i, Args const&... args) const { - return twist_4(i + 1, args..., x_[i - (n - m)] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a)); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == n - 1 - unroll_extra2, - mersenne_twister_engine - >::type twist_3(std::size_t i, Args const&... args) const { - return twist_4(n - 1 - unroll_extra2, args...); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < n - 1 - unroll_extra2, - mersenne_twister_engine - >::type twist_3(std::size_t i, Args const&... args) const { - return twist_3(i + 1, args..., x_[i - (n - m)] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a)); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == n - m, - mersenne_twister_engine - >::type twist_2(std::size_t i, Args const&... args) const { - return twist_3(n - m, args...); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < n - m, - mersenne_twister_engine - >::type twist_2(std::size_t i, Args const&... args) const { - return twist_2(i + 1, args..., x_[i + m] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a)); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) == n - m - unroll_extra1, - mersenne_twister_engine - >::type twist_1(std::size_t i, Args const&... args) const { - return twist_2(n - m - unroll_extra1, args...); - } - template - SPROUT_CONSTEXPR typename std::enable_if< - sizeof...(Args) < n - m - unroll_extra1, - mersenne_twister_engine - >::type twist_1(std::size_t i, Args const&... args) const { - return twist_1(i + 1, args..., x_[i + m] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a)); - } - SPROUT_CONSTEXPR mersenne_twister_engine twist() const { - return twist_1(0); - } - public: - SPROUT_CONSTEXPR mersenne_twister_engine() - : x_(init_seed(default_seed)) - , i_(n) - {} - SPROUT_CONSTEXPR explicit mersenne_twister_engine(UIntType const& value) - : x_(init_seed(value)) - , i_(n) - {} - SPROUT_CONSTEXPR result_type min() const { - return static_min(); - } - SPROUT_CONSTEXPR result_type max() const { - return static_max(); - } - SPROUT_CONSTEXPR sprout::random::random_result operator()() const { - return i_ == n - ? twist().generate() - : generate() - ; - } - friend SPROUT_CONSTEXPR bool operator==(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) { - return lhs.i_ < lhs.i_ - ? lhs.equal_impl(rhs) - : rhs.equal_impl(lhs) - ; - } - friend SPROUT_CONSTEXPR bool operator!=(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) { - return !(lhs == rhs); - } - template - friend std::basic_istream& operator>>( - std::basic_istream& lhs, - mersenne_twister_engine const& rhs - ) - { - sprout::array data; - for(std::size_t i = 0; i < rhs.i_; ++i) { - data[i + n - rhs.i_] = rhs.x_[i]; - } - if (rhs.i_ != n) { - data = rhs.rewind(data, &data[n - rhs.i_ - 1], n - rhs.i_); - } - lhs << data[0]; - for (std::size_t i = 0; i < rhs.i_; ++i) { - lhs << ' ' << data[i]; - } - return lhs; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - mersenne_twister_engine const& rhs - ) - { - for (std::size_t i = 0; i < state_size; ++i) { - lhs >> rhs.x_[i] >> std::ws; - } - rhs.i_ = state_size; - return lhs; - } - }; - template - SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::word_size; - template - SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::state_size; - template - SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::shift_size; - template - SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::mask_bits; - template - SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::xor_mask; - template - SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::tempering_u; - template - SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::tempering_d; - template - SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::tempering_s; - template - SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::tempering_b; - template - SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::tempering_t; - template - SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::tempering_c; - template - SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::tempering_l; - template - SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::initialization_multiplier; - template - SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::default_seed; - - // - // mt11213b - // - typedef sprout::random::mersenne_twister_engine< - std::uint32_t, - 32, - 351, - 175, - 19, - 0xccab8ee7, - 11, - 0xffffffff, - 7, - 0x31b6ab00, - 15, - 0xffe50000, - 17, - 1812433253 - > mt11213b; - // - // mt19937 - // - typedef sprout::random::mersenne_twister_engine< - std::uint32_t, - 32, - 624, - 397, - 31, - 0x9908b0df, - 11, - 0xffffffff, - 7, - 0x9d2c5680, - 15, - 0xefc60000, - 18, - 1812433253 - > mt19937; - // - // mt19937_64 - // - typedef sprout::random::mersenne_twister_engine< - std::uint64_t, - 64, - 312, - 156, - 31, - UINT64_C(0xb5026f5aa96619e9), - 29, - UINT64_C(0x5555555555555555), - 17, - UINT64_C(0x71d67fffeda60000), - 37, - UINT64_C(0xfff7eee000000000), - 43, - UINT64_C(6364136223846793005) - > mt19937_64; - } // namespace random - - using sprout::random::mt11213b; - using sprout::random::mt19937; - using sprout::random::mt19937_64; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP - +#ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP +#define SPROUT_RANDOM_MERSENNE_TWISTER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // mersenne_twister_engine + // + template + class mersenne_twister_engine { + public: + typedef UIntType result_type; + private: + struct private_constructor_tag {}; + public: + SPROUT_STATIC_CONSTEXPR std::size_t word_size = w; + SPROUT_STATIC_CONSTEXPR std::size_t state_size = n; + SPROUT_STATIC_CONSTEXPR std::size_t shift_size = m; + SPROUT_STATIC_CONSTEXPR std::size_t mask_bits = r; + SPROUT_STATIC_CONSTEXPR UIntType xor_mask = a; + SPROUT_STATIC_CONSTEXPR std::size_t tempering_u = u; + SPROUT_STATIC_CONSTEXPR UIntType tempering_d = d; + SPROUT_STATIC_CONSTEXPR std::size_t tempering_s = s; + SPROUT_STATIC_CONSTEXPR UIntType tempering_b = b; + SPROUT_STATIC_CONSTEXPR std::size_t tempering_t = t; + SPROUT_STATIC_CONSTEXPR UIntType tempering_c = c; + SPROUT_STATIC_CONSTEXPR std::size_t tempering_l = l; + SPROUT_STATIC_CONSTEXPR UIntType initialization_multiplier = f; + SPROUT_STATIC_CONSTEXPR UIntType default_seed = 5489u; + private: + SPROUT_STATIC_CONSTEXPR UIntType upper_mask = (~static_cast(0)) << r; + SPROUT_STATIC_CONSTEXPR UIntType lower_mask = ~upper_mask; + SPROUT_STATIC_CONSTEXPR std::size_t unroll_factor = 6; + SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra1 = (n - m) % unroll_factor; + SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra2 = (m - 1) % unroll_factor; + private: + template + static SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) + 1 == n, + sprout::array + >::type init_seed_1(UIntType const& value, Args const&... args) { + return sprout::array{{args..., value}}; + } + template + static SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) + 1 < n, + sprout::array + >::type init_seed_1(UIntType const& value, Args const&... args) { + return init_seed_1( + (f * (value ^ (value >> (w - 2))) + (sizeof...(Args) + 1)) & static_max(), + args..., + value + ); + } + static SPROUT_CONSTEXPR sprout::array init_seed(UIntType const& value) { + return init_seed_1(value & static_max()); + } + public: + static SPROUT_CONSTEXPR result_type static_min() { + return 0; + } + static SPROUT_CONSTEXPR result_type static_max() { + return sprout::detail::low_bits_mask_t::sig_bits; + } + private: + sprout::array x_; + std::size_t i_; + private: + SPROUT_CONSTEXPR mersenne_twister_engine(sprout::array const& x, std::size_t i, private_constructor_tag) + : x_(x) + , i_(i) + {} + SPROUT_CONSTEXPR UIntType rewind_find_1(UIntType const* last, std::size_t size, std::size_t index) const { + return index < n - size + ? x_[index] + : *(last - (n - 1 - index)) + ; + } + SPROUT_CONSTEXPR UIntType rewind_find(UIntType const* last, std::size_t size, std::size_t i) const { + return rewind_find_1(last, size, (i + n - size + n - 1) % n); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) == n, + sprout::array + >::type rewind_finish_1(sprout::array const& data, Args const&... args) const { + return sprout::array{{args...}}; + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) < n, + sprout::array + >::type rewind_finish_1(sprout::array const& data, Args const&... args) const { + return rewind_finish_1(data, args..., data[sizeof...(args)]); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) == n, + sprout::array + >::type rewind_finish(sprout::array const& data, UIntType const* last, std::size_t z, std::size_t i, Args const&... args) const { + return sprout::array{{args...}}; + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) < n, + sprout::array + >::type rewind_finish(sprout::array const& data, UIntType const* last, std::size_t z, std::size_t i, Args const&... args) const { + return &data[0] + i == last - z + ? rewind_finish_1(data, data[i], args...) + : rewind_finish(data, last, z, i + 1, data[i], args...) + ; + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) == n, + sprout::array + >::type rewind_4(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { + return sprout::array{{args...}}; + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) < n, + sprout::array + >::type rewind_4(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { + return rewind_2( + data, + last, + z, + y1, + i, + (y0 & upper_mask) | (y1 & lower_mask), + args... + ); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) == n, + sprout::array + >::type rewind_3(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { + return sprout::array{{args...}}; + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) < n, + sprout::array + >::type rewind_3(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { + return rewind_4( + data, + last, + z, + y0, + y1 & (static_cast(1) << (w - 1)) + ? ((y1 ^ a) << 1) | 1 + : y1 << 1 + , + i, + args... + ); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) == n, + sprout::array + >::type rewind_2(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, std::size_t i, Args const&... args) const { + return sprout::array{{args...}}; + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) < n, + sprout::array + >::type rewind_2(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0, std::size_t i, Args const&... args) const { + return i < z + ? rewind_3(data, last, z, y0, rewind_find(last, i, m - 1) ^ rewind_find(last, i, n - 1), i, args...) + : rewind_finish(data, last, z, 0, args...) + ; + } + SPROUT_CONSTEXPR sprout::array rewind_1(sprout::array const& data, UIntType const* last, std::size_t z, UIntType y0) const { + return rewind_2( + data, + last, + z, + y0 & (static_cast(1) << (w - 1)) + ? ((y0 ^ a) << 1) | 1 + : y0 << 1 + , + 0 + ); + } + SPROUT_CONSTEXPR sprout::array rewind(sprout::array const& data, UIntType const* last, std::size_t z) const { + return rewind_1(data, last, z, x_[m - 1] ^ x_[n - 1]); + } + SPROUT_CONSTEXPR bool equal_impl_2(mersenne_twister_engine const& other, sprout::array back, std::size_t offset, std::size_t i = 0) const { + return i < offset + ? back[i + n - offset] != other.x_[i] + ? false + : equal_impl_2(other, back, offset, i + 1) + : true + ; + } + SPROUT_CONSTEXPR bool equal_impl_1(mersenne_twister_engine const& other, sprout::array back, std::size_t offset, std::size_t i = 0) const { + return i + offset < n + ? x_[i] != other.x_[i + offset] + ? false + : equal_impl_1(other, back, offset, i + 1) + : equal_impl_2(other, rewind(back, &back[n - 1], offset), offset) + ; + } + SPROUT_CONSTEXPR bool equal_impl(mersenne_twister_engine const& other) const { + return equal_impl_1(other, sprout::array(), other.i_ - i_); + } + SPROUT_CONSTEXPR UIntType generate_impl_4(UIntType z) const { + return z ^ (z >> l); + } + SPROUT_CONSTEXPR UIntType generate_impl_3(UIntType z) const { + return z ^ generate_impl_4((z << t) & c); + } + SPROUT_CONSTEXPR UIntType generate_impl_2(UIntType z) const { + return z ^ generate_impl_3((z << s) & b); + } + SPROUT_CONSTEXPR UIntType generate_impl_1(UIntType z) const { + return z ^ generate_impl_2((z >> u) & d); + } + SPROUT_CONSTEXPR UIntType generate_impl() const { + return generate_impl_1(x_[i_]); + } + SPROUT_CONSTEXPR sprout::random::random_result generate() const { + return sprout::random::random_result( + generate_impl(), + mersenne_twister_engine( + x_, + i_ + 1, + private_constructor_tag() + ) + ); + } + template + SPROUT_CONSTEXPR mersenne_twister_engine twist_5(Args const&... args) const { + return mersenne_twister_engine( + sprout::array{{args..., x_[m - 1] ^ ((x_[n - 1] & upper_mask) | (x_[0] & lower_mask) >> 1) ^ ((x_[0] & 1) * a)}}, + 0, + private_constructor_tag() + ); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) == n - 1, + mersenne_twister_engine + >::type twist_4(std::size_t i, Args const&... args) const { + return twist_5(args...); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) < n - 1, + mersenne_twister_engine + >::type twist_4(std::size_t i, Args const&... args) const { + return twist_4(i + 1, args..., x_[i - (n - m)] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) == n - 1 - unroll_extra2, + mersenne_twister_engine + >::type twist_3(std::size_t i, Args const&... args) const { + return twist_4(n - 1 - unroll_extra2, args...); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) < n - 1 - unroll_extra2, + mersenne_twister_engine + >::type twist_3(std::size_t i, Args const&... args) const { + return twist_3(i + 1, args..., x_[i - (n - m)] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) == n - m, + mersenne_twister_engine + >::type twist_2(std::size_t i, Args const&... args) const { + return twist_3(n - m, args...); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) < n - m, + mersenne_twister_engine + >::type twist_2(std::size_t i, Args const&... args) const { + return twist_2(i + 1, args..., x_[i + m] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a)); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) == n - m - unroll_extra1, + mersenne_twister_engine + >::type twist_1(std::size_t i, Args const&... args) const { + return twist_2(n - m - unroll_extra1, args...); + } + template + SPROUT_CONSTEXPR typename std::enable_if< + sizeof...(Args) < n - m - unroll_extra1, + mersenne_twister_engine + >::type twist_1(std::size_t i, Args const&... args) const { + return twist_1(i + 1, args..., x_[i + m] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a)); + } + SPROUT_CONSTEXPR mersenne_twister_engine twist() const { + return twist_1(0); + } + public: + SPROUT_CONSTEXPR mersenne_twister_engine() + : x_(init_seed(default_seed)) + , i_(n) + {} + SPROUT_CONSTEXPR explicit mersenne_twister_engine(UIntType const& value) + : x_(init_seed(value)) + , i_(n) + {} + SPROUT_CONSTEXPR result_type min() const { + return static_min(); + } + SPROUT_CONSTEXPR result_type max() const { + return static_max(); + } + SPROUT_CONSTEXPR sprout::random::random_result operator()() const { + return i_ == n + ? twist().generate() + : generate() + ; + } + friend SPROUT_CONSTEXPR bool operator==(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) { + return lhs.i_ < lhs.i_ + ? lhs.equal_impl(rhs) + : rhs.equal_impl(lhs) + ; + } + friend SPROUT_CONSTEXPR bool operator!=(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) { + return !(lhs == rhs); + } + template + friend std::basic_istream& operator>>( + std::basic_istream& lhs, + mersenne_twister_engine const& rhs + ) + { + sprout::array data; + for(std::size_t i = 0; i < rhs.i_; ++i) { + data[i + n - rhs.i_] = rhs.x_[i]; + } + if (rhs.i_ != n) { + data = rhs.rewind(data, &data[n - rhs.i_ - 1], n - rhs.i_); + } + lhs << data[0]; + for (std::size_t i = 0; i < rhs.i_; ++i) { + lhs << ' ' << data[i]; + } + return lhs; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + mersenne_twister_engine const& rhs + ) + { + for (std::size_t i = 0; i < state_size; ++i) { + lhs >> rhs.x_[i] >> std::ws; + } + rhs.i_ = state_size; + return lhs; + } + }; + template + SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::word_size; + template + SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::state_size; + template + SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::shift_size; + template + SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::mask_bits; + template + SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::xor_mask; + template + SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::tempering_u; + template + SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::tempering_d; + template + SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::tempering_s; + template + SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::tempering_b; + template + SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::tempering_t; + template + SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::tempering_c; + template + SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine::tempering_l; + template + SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::initialization_multiplier; + template + SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine::default_seed; + + // + // mt11213b + // + typedef sprout::random::mersenne_twister_engine< + std::uint32_t, + 32, + 351, + 175, + 19, + 0xccab8ee7, + 11, + 0xffffffff, + 7, + 0x31b6ab00, + 15, + 0xffe50000, + 17, + 1812433253 + > mt11213b; + // + // mt19937 + // + typedef sprout::random::mersenne_twister_engine< + std::uint32_t, + 32, + 624, + 397, + 31, + 0x9908b0df, + 11, + 0xffffffff, + 7, + 0x9d2c5680, + 15, + 0xefc60000, + 18, + 1812433253 + > mt19937; + // + // mt19937_64 + // + typedef sprout::random::mersenne_twister_engine< + std::uint64_t, + 64, + 312, + 156, + 31, + UINT64_C(0xb5026f5aa96619e9), + 29, + UINT64_C(0x5555555555555555), + 17, + UINT64_C(0x71d67fffeda60000), + 37, + UINT64_C(0xfff7eee000000000), + 43, + UINT64_C(6364136223846793005) + > mt19937_64; + } // namespace random + + using sprout::random::mt11213b; + using sprout::random::mt19937; + using sprout::random::mt19937_64; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP + diff --git a/sprout/random/random_iterator.hpp b/sprout/random/random_iterator.hpp index 766bf102..bb04c823 100644 --- a/sprout/random/random_iterator.hpp +++ b/sprout/random/random_iterator.hpp @@ -1,326 +1,326 @@ -#ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP -#define SPROUT_RANDOM_RANDOM_ITERATOR_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - // - // random_iterator - // - template - class random_iterator; - - template - class random_iterator< - Engine, - Distribution, - typename std::enable_if::value>::type - > - : public std::iterator< - typename std::iterator_traits >::iterator_category, - typename std::iterator_traits >::value_type, - typename std::iterator_traits >::difference_type, - typename std::iterator_traits >::pointer, - typename std::iterator_traits >::reference - > - { - public: - typedef sprout::random::random_result random_result_type; - typedef typename random_result_type::engine_type engine_type; - typedef typename random_result_type::distribution_type distribution_type; - typedef typename random_result_type::result_type result_type; - typedef typename std::iterator_traits::iterator_category iterator_category; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::difference_type difference_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - private: - random_result_type random_; - difference_type count_; - public: - //random_iterator() = default; // ??? - SPROUT_CONSTEXPR random_iterator() - : random_() - , count_() - {} - SPROUT_CONSTEXPR random_iterator( - engine_type const& engine, - distribution_type const& distribution, - difference_type count = -1 - ) - : random_(distribution(engine)) - , count_(count) - {} - SPROUT_CONSTEXPR explicit random_iterator( - random_result_type const& random, - difference_type count = -1 - ) - : random_(random) - , count_(count) - {} - SPROUT_CONSTEXPR random_iterator operator()() const { - return count_ != 0 - ? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_) - : throw "assert(count_ != 0)" - ; - } - random_result_type& random_result() { - return random_; - } - SPROUT_CONSTEXPR random_result_type const& random_result() const { - return random_; - } - result_type& result() { - return random_.result(); - } - SPROUT_CONSTEXPR result_type const& result() const { - return random_.result(); - } - engine_type& engine() { - return random_.engine(); - } - SPROUT_CONSTEXPR engine_type const& engine() const { - return random_.engine(); - } - distribution_type& distribution() { - return random_.distribution(); - } - SPROUT_CONSTEXPR distribution_type const& distribution() const { - return random_.distribution(); - } - SPROUT_CONSTEXPR result_type min() const { - return random_.min(); - } - SPROUT_CONSTEXPR result_type max() const { - return random_.max(); - } - SPROUT_CONSTEXPR result_type count() const { - return count_; - } - void swap(random_iterator& other) { - using std::swap; - swap(random_, other.random_); - swap(count_, other.count_); - } - friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) { - return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_); - } - friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) { - return !(lhs == rhs); - } - SPROUT_CONSTEXPR reference operator*() const { - return count_ != 0 - ? random_.result() - : (throw "assert(count_ != 0)", random_.result()) - ; - } - SPROUT_CONSTEXPR pointer operator->() const { - return count_ != 0 - ? &random_.result() - : throw "assert(count_ != 0)" - ; - } - random_iterator& operator++() { - random_iterator temp((*this)()); - temp.swap(*this); - return *this; - } - random_iterator operator++(int) { - random_iterator result(*this); - ++*this; - return result; - } - }; - template - class random_iterator< - Engine, - Distribution, - typename std::enable_if::value>::type - > - : public std::iterator< - typename std::iterator_traits >::iterator_category, - typename std::iterator_traits >::value_type, - typename std::iterator_traits >::difference_type, - typename std::iterator_traits >::pointer, - typename std::iterator_traits >::reference - > - { - public: - typedef sprout::random::random_result random_result_type; - typedef typename random_result_type::engine_type engine_type; - typedef typename random_result_type::result_type result_type; - typedef typename std::iterator_traits::iterator_category iterator_category; - typedef typename std::iterator_traits::value_type value_type; - typedef typename std::iterator_traits::difference_type difference_type; - typedef typename std::iterator_traits::pointer pointer; - typedef typename std::iterator_traits::reference reference; - private: - random_result_type random_; - difference_type count_; - public: - //random_iterator() = default; // ??? - SPROUT_CONSTEXPR random_iterator() - : random_() - , count_() - {} - SPROUT_CONSTEXPR random_iterator( - engine_type const& engine, - difference_type count = -1 - ) - : random_(engine()) - , count_(count) - {} - SPROUT_CONSTEXPR explicit random_iterator( - random_result_type const& random, - difference_type count = -1 - ) - : random_(random) - , count_(count) - {} - SPROUT_CONSTEXPR random_iterator operator()() const { - return count_ != 0 - ? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_) - : throw "assert(count_ != 0)" - ; - } - random_result_type& random_result() { - return random_; - } - SPROUT_CONSTEXPR random_result_type const& random_result() const { - return random_; - } - result_type& result() { - return random_.result(); - } - SPROUT_CONSTEXPR result_type const& result() const { - return random_.result(); - } - engine_type& engine() { - return random_.engine(); - } - SPROUT_CONSTEXPR engine_type const& engine() const { - return random_.engine(); - } - SPROUT_CONSTEXPR result_type min() const { - return random_.min(); - } - SPROUT_CONSTEXPR result_type max() const { - return random_.max(); - } - SPROUT_CONSTEXPR result_type count() const { - return count_; - } - void swap(random_iterator& other) { - using std::swap; - swap(random_, other.random_); - swap(count_, other.count_); - } - friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) { - return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_); - } - friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) { - return !(lhs == rhs); - } - SPROUT_CONSTEXPR reference operator*() const { - return count_ != 0 - ? random_.result() - : (throw "assert(count_ != 0)", random_.result()) - ; - } - SPROUT_CONSTEXPR pointer operator->() const { - return count_ > 0 - ? &random_.result() - : throw "assert(count_ != 0)" - ; - } - random_iterator& operator++() { - random_iterator temp((*this)()); - temp.swap(*this); - return *this; - } - random_iterator operator++(int) { - random_iterator result(*this); - ++*this; - return result; - } - }; - // - // swap - // - template - void swap( - sprout::random::random_iterator& lhs, - sprout::random::random_iterator& rhs - ) - { - lhs.swap(rhs); - } - - // - // begin - // - template - SPROUT_CONSTEXPR typename std::enable_if< - !std::is_integral::value, - sprout::random::random_iterator - >::type begin( - Engine const& engine, - Distribution const& distribution, - typename sprout::random::random_iterator::difference_type count = -1 - ) - { - return sprout::random::random_iterator(engine, distribution, count); - } - template - SPROUT_CONSTEXPR sprout::random::random_iterator begin( - Engine const& engine, - typename sprout::random::random_iterator::difference_type count = -1 - ) - { - return sprout::random::random_iterator(engine, count); - } - - // - // end - // - template - SPROUT_CONSTEXPR sprout::random::random_iterator end( - Engine const& engine, - Distribution const& distribution - ) - { - return sprout::random::random_iterator(); - } - template - SPROUT_CONSTEXPR sprout::random::random_iterator end( - Engine const& engine - ) - { - return sprout::random::random_iterator(); - } - - // - // next - // - template - SPROUT_CONSTEXPR sprout::random::random_iterator next( - sprout::random::random_iterator const& it - ) - { - return it(); - } - } // namespace random - - using sprout::random::random_iterator; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP - +#ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP +#define SPROUT_RANDOM_RANDOM_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // random_iterator + // + template + class random_iterator; + + template + class random_iterator< + Engine, + Distribution, + typename std::enable_if::value>::type + > + : public std::iterator< + typename std::iterator_traits >::iterator_category, + typename std::iterator_traits >::value_type, + typename std::iterator_traits >::difference_type, + typename std::iterator_traits >::pointer, + typename std::iterator_traits >::reference + > + { + public: + typedef sprout::random::random_result random_result_type; + typedef typename random_result_type::engine_type engine_type; + typedef typename random_result_type::distribution_type distribution_type; + typedef typename random_result_type::result_type result_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::reference reference; + private: + random_result_type random_; + difference_type count_; + public: + //random_iterator() = default; // ??? + SPROUT_CONSTEXPR random_iterator() + : random_() + , count_() + {} + SPROUT_CONSTEXPR random_iterator( + engine_type const& engine, + distribution_type const& distribution, + difference_type count = -1 + ) + : random_(distribution(engine)) + , count_(count) + {} + SPROUT_CONSTEXPR explicit random_iterator( + random_result_type const& random, + difference_type count = -1 + ) + : random_(random) + , count_(count) + {} + SPROUT_CONSTEXPR random_iterator operator()() const { + return count_ != 0 + ? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_) + : throw "assert(count_ != 0)" + ; + } + random_result_type& random_result() { + return random_; + } + SPROUT_CONSTEXPR random_result_type const& random_result() const { + return random_; + } + result_type& result() { + return random_.result(); + } + SPROUT_CONSTEXPR result_type const& result() const { + return random_.result(); + } + engine_type& engine() { + return random_.engine(); + } + SPROUT_CONSTEXPR engine_type const& engine() const { + return random_.engine(); + } + distribution_type& distribution() { + return random_.distribution(); + } + SPROUT_CONSTEXPR distribution_type const& distribution() const { + return random_.distribution(); + } + SPROUT_CONSTEXPR result_type min() const { + return random_.min(); + } + SPROUT_CONSTEXPR result_type max() const { + return random_.max(); + } + SPROUT_CONSTEXPR result_type count() const { + return count_; + } + void swap(random_iterator& other) { + using std::swap; + swap(random_, other.random_); + swap(count_, other.count_); + } + friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) { + return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_); + } + friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) { + return !(lhs == rhs); + } + SPROUT_CONSTEXPR reference operator*() const { + return count_ != 0 + ? random_.result() + : (throw "assert(count_ != 0)", random_.result()) + ; + } + SPROUT_CONSTEXPR pointer operator->() const { + return count_ != 0 + ? &random_.result() + : throw "assert(count_ != 0)" + ; + } + random_iterator& operator++() { + random_iterator temp((*this)()); + temp.swap(*this); + return *this; + } + random_iterator operator++(int) { + random_iterator result(*this); + ++*this; + return result; + } + }; + template + class random_iterator< + Engine, + Distribution, + typename std::enable_if::value>::type + > + : public std::iterator< + typename std::iterator_traits >::iterator_category, + typename std::iterator_traits >::value_type, + typename std::iterator_traits >::difference_type, + typename std::iterator_traits >::pointer, + typename std::iterator_traits >::reference + > + { + public: + typedef sprout::random::random_result random_result_type; + typedef typename random_result_type::engine_type engine_type; + typedef typename random_result_type::result_type result_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::reference reference; + private: + random_result_type random_; + difference_type count_; + public: + //random_iterator() = default; // ??? + SPROUT_CONSTEXPR random_iterator() + : random_() + , count_() + {} + SPROUT_CONSTEXPR random_iterator( + engine_type const& engine, + difference_type count = -1 + ) + : random_(engine()) + , count_(count) + {} + SPROUT_CONSTEXPR explicit random_iterator( + random_result_type const& random, + difference_type count = -1 + ) + : random_(random) + , count_(count) + {} + SPROUT_CONSTEXPR random_iterator operator()() const { + return count_ != 0 + ? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_) + : throw "assert(count_ != 0)" + ; + } + random_result_type& random_result() { + return random_; + } + SPROUT_CONSTEXPR random_result_type const& random_result() const { + return random_; + } + result_type& result() { + return random_.result(); + } + SPROUT_CONSTEXPR result_type const& result() const { + return random_.result(); + } + engine_type& engine() { + return random_.engine(); + } + SPROUT_CONSTEXPR engine_type const& engine() const { + return random_.engine(); + } + SPROUT_CONSTEXPR result_type min() const { + return random_.min(); + } + SPROUT_CONSTEXPR result_type max() const { + return random_.max(); + } + SPROUT_CONSTEXPR result_type count() const { + return count_; + } + void swap(random_iterator& other) { + using std::swap; + swap(random_, other.random_); + swap(count_, other.count_); + } + friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) { + return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_); + } + friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) { + return !(lhs == rhs); + } + SPROUT_CONSTEXPR reference operator*() const { + return count_ != 0 + ? random_.result() + : (throw "assert(count_ != 0)", random_.result()) + ; + } + SPROUT_CONSTEXPR pointer operator->() const { + return count_ > 0 + ? &random_.result() + : throw "assert(count_ != 0)" + ; + } + random_iterator& operator++() { + random_iterator temp((*this)()); + temp.swap(*this); + return *this; + } + random_iterator operator++(int) { + random_iterator result(*this); + ++*this; + return result; + } + }; + // + // swap + // + template + void swap( + sprout::random::random_iterator& lhs, + sprout::random::random_iterator& rhs + ) + { + lhs.swap(rhs); + } + + // + // begin + // + template + SPROUT_CONSTEXPR typename std::enable_if< + !std::is_integral::value, + sprout::random::random_iterator + >::type begin( + Engine const& engine, + Distribution const& distribution, + typename sprout::random::random_iterator::difference_type count = -1 + ) + { + return sprout::random::random_iterator(engine, distribution, count); + } + template + SPROUT_CONSTEXPR sprout::random::random_iterator begin( + Engine const& engine, + typename sprout::random::random_iterator::difference_type count = -1 + ) + { + return sprout::random::random_iterator(engine, count); + } + + // + // end + // + template + SPROUT_CONSTEXPR sprout::random::random_iterator end( + Engine const& engine, + Distribution const& distribution + ) + { + return sprout::random::random_iterator(); + } + template + SPROUT_CONSTEXPR sprout::random::random_iterator end( + Engine const& engine + ) + { + return sprout::random::random_iterator(); + } + + // + // next + // + template + SPROUT_CONSTEXPR sprout::random::random_iterator next( + sprout::random::random_iterator const& it + ) + { + return it(); + } + } // namespace random + + using sprout::random::random_iterator; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP + diff --git a/sprout/random/random_result.hpp b/sprout/random/random_result.hpp index c24dda70..f2814ae4 100644 --- a/sprout/random/random_result.hpp +++ b/sprout/random/random_result.hpp @@ -1,263 +1,263 @@ -#ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP -#define SPROUT_RANDOM_RANDOM_RESULT_HPP - -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - // - // random_result - // - template - class random_result; - - template - class random_result< - Engine, - Distribution, - typename std::enable_if::value>::type - > - : public std::iterator< - std::input_iterator_tag, - typename Distribution::result_type, - std::ptrdiff_t, - typename Distribution::result_type const*, - typename Distribution::result_type const& - > - { - public: - typedef Engine engine_type; - typedef Distribution distribution_type; - typedef typename distribution_type::result_type result_type; - private: - typedef std::iterator< - std::input_iterator_tag, - result_type, - std::ptrdiff_t, - result_type const*, - result_type const& - > base_type; - public: - typedef typename base_type::iterator_category iterator_category; - typedef typename base_type::value_type value_type; - typedef typename base_type::difference_type difference_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::reference reference; - private: - result_type result_; - engine_type engine_; - distribution_type distribution_; - public: - //random_result() = default; // ??? - SPROUT_CONSTEXPR random_result() - : result_() - , engine_() - , distribution_() - {} - SPROUT_CONSTEXPR random_result( - result_type result, - engine_type const& engine, - distribution_type const& distribution - ) - : result_(result) - , engine_(engine) - , distribution_(distribution) - {} - SPROUT_CONSTEXPR operator result_type() const { - return result_; - } - SPROUT_CONSTEXPR random_result operator()() const { - return distribution_(engine_); - } - result_type& result() { - return result_; - } - SPROUT_CONSTEXPR result_type const& result() const { - return result_; - } - engine_type& engine() { - return engine_; - } - SPROUT_CONSTEXPR engine_type const& engine() const { - return engine_; - } - distribution_type& distribution() { - return distribution_; - } - SPROUT_CONSTEXPR distribution_type const& distribution() const { - return distribution_; - } - SPROUT_CONSTEXPR result_type min() const { - return distribution_.min(); - } - SPROUT_CONSTEXPR result_type max() const { - return distribution_.max(); - } - void swap(random_result& other) { - using std::swap; - swap(result_, other.result_); - swap(engine_, other.engine_); - swap(distribution_, other.distribution_); - } - friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) { - return lhs.result_ == rhs.result_ - && lhs.engine_ == rhs.engine_ - && lhs.distribution_ == rhs.distribution_ - ; - } - friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) { - return !(lhs == rhs); - } - SPROUT_CONSTEXPR reference operator*() const { - return result_; - } - SPROUT_CONSTEXPR pointer operator->() const { - return &result_; - } - random_result& operator++() { - random_result temp((*this)()); - temp.swap(*this); - return *this; - } - random_result operator++(int) { - random_result result(*this); - ++*this; - return result; - } - }; - template - class random_result< - Engine, - Distribution, - typename std::enable_if::value>::type - > - : public std::iterator< - std::input_iterator_tag, - typename Engine::result_type, - std::ptrdiff_t, - typename Engine::result_type const*, - typename Engine::result_type const& - > - { - public: - typedef Engine engine_type; - typedef typename engine_type::result_type result_type; - private: - typedef std::iterator< - std::input_iterator_tag, - result_type, - std::ptrdiff_t, - result_type const*, - result_type const& - > base_type; - public: - typedef typename base_type::iterator_category iterator_category; - typedef typename base_type::value_type value_type; - typedef typename base_type::difference_type difference_type; - typedef typename base_type::pointer pointer; - typedef typename base_type::reference reference; - private: - result_type result_; - engine_type engine_; - public: - //random_result() = default; // ??? - SPROUT_CONSTEXPR random_result() - : result_() - , engine_() - {} - SPROUT_CONSTEXPR random_result( - result_type result, - engine_type const& engine - ) - : result_(result) - , engine_(engine) - {} - SPROUT_CONSTEXPR operator result_type() const { - return result_; - } - SPROUT_CONSTEXPR random_result operator()() const { - return engine_(); - } - result_type& result() { - return result_; - } - SPROUT_CONSTEXPR result_type const& result() const { - return result_; - } - engine_type& engine() { - return engine_; - } - SPROUT_CONSTEXPR engine_type const& engine() const { - return engine_; - } - SPROUT_CONSTEXPR result_type min() const { - return engine_.min(); - } - SPROUT_CONSTEXPR result_type max() const { - return engine_.max(); - } - friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) { - return lhs.result_ == rhs.result_ - && lhs.engine_ == rhs.engine_ - ; - } - friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) { - return !(lhs == rhs); - } - void swap(random_result& other) { - using std::swap; - swap(result_, other.result_); - swap(engine_, other.engine_); - } - SPROUT_CONSTEXPR reference operator*() const { - return result_; - } - SPROUT_CONSTEXPR pointer operator->() const { - return &result_; - } - random_result& operator++() { - random_result temp((*this)()); - temp.swap(*this); - return *this; - } - random_result operator++(int) { - random_result result(*this); - random_result temp((*this)()); - temp.swap(*this); - return result; - } - }; - // - // swap - // - template - void swap( - sprout::random::random_result& lhs, - sprout::random::random_result& rhs - ) - { - lhs.swap(rhs); - } - } // namespace random - - // - // next - // - template - SPROUT_CONSTEXPR sprout::random::random_result next( - sprout::random::random_result const& it - ) - { - return it(); - } - - using sprout::random::random_result; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP - +#ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP +#define SPROUT_RANDOM_RANDOM_RESULT_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // random_result + // + template + class random_result; + + template + class random_result< + Engine, + Distribution, + typename std::enable_if::value>::type + > + : public std::iterator< + std::input_iterator_tag, + typename Distribution::result_type, + std::ptrdiff_t, + typename Distribution::result_type const*, + typename Distribution::result_type const& + > + { + public: + typedef Engine engine_type; + typedef Distribution distribution_type; + typedef typename distribution_type::result_type result_type; + private: + typedef std::iterator< + std::input_iterator_tag, + result_type, + std::ptrdiff_t, + result_type const*, + result_type const& + > base_type; + public: + typedef typename base_type::iterator_category iterator_category; + typedef typename base_type::value_type value_type; + typedef typename base_type::difference_type difference_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::reference reference; + private: + result_type result_; + engine_type engine_; + distribution_type distribution_; + public: + //random_result() = default; // ??? + SPROUT_CONSTEXPR random_result() + : result_() + , engine_() + , distribution_() + {} + SPROUT_CONSTEXPR random_result( + result_type result, + engine_type const& engine, + distribution_type const& distribution + ) + : result_(result) + , engine_(engine) + , distribution_(distribution) + {} + SPROUT_CONSTEXPR operator result_type() const { + return result_; + } + SPROUT_CONSTEXPR random_result operator()() const { + return distribution_(engine_); + } + result_type& result() { + return result_; + } + SPROUT_CONSTEXPR result_type const& result() const { + return result_; + } + engine_type& engine() { + return engine_; + } + SPROUT_CONSTEXPR engine_type const& engine() const { + return engine_; + } + distribution_type& distribution() { + return distribution_; + } + SPROUT_CONSTEXPR distribution_type const& distribution() const { + return distribution_; + } + SPROUT_CONSTEXPR result_type min() const { + return distribution_.min(); + } + SPROUT_CONSTEXPR result_type max() const { + return distribution_.max(); + } + void swap(random_result& other) { + using std::swap; + swap(result_, other.result_); + swap(engine_, other.engine_); + swap(distribution_, other.distribution_); + } + friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) { + return lhs.result_ == rhs.result_ + && lhs.engine_ == rhs.engine_ + && lhs.distribution_ == rhs.distribution_ + ; + } + friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) { + return !(lhs == rhs); + } + SPROUT_CONSTEXPR reference operator*() const { + return result_; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &result_; + } + random_result& operator++() { + random_result temp((*this)()); + temp.swap(*this); + return *this; + } + random_result operator++(int) { + random_result result(*this); + ++*this; + return result; + } + }; + template + class random_result< + Engine, + Distribution, + typename std::enable_if::value>::type + > + : public std::iterator< + std::input_iterator_tag, + typename Engine::result_type, + std::ptrdiff_t, + typename Engine::result_type const*, + typename Engine::result_type const& + > + { + public: + typedef Engine engine_type; + typedef typename engine_type::result_type result_type; + private: + typedef std::iterator< + std::input_iterator_tag, + result_type, + std::ptrdiff_t, + result_type const*, + result_type const& + > base_type; + public: + typedef typename base_type::iterator_category iterator_category; + typedef typename base_type::value_type value_type; + typedef typename base_type::difference_type difference_type; + typedef typename base_type::pointer pointer; + typedef typename base_type::reference reference; + private: + result_type result_; + engine_type engine_; + public: + //random_result() = default; // ??? + SPROUT_CONSTEXPR random_result() + : result_() + , engine_() + {} + SPROUT_CONSTEXPR random_result( + result_type result, + engine_type const& engine + ) + : result_(result) + , engine_(engine) + {} + SPROUT_CONSTEXPR operator result_type() const { + return result_; + } + SPROUT_CONSTEXPR random_result operator()() const { + return engine_(); + } + result_type& result() { + return result_; + } + SPROUT_CONSTEXPR result_type const& result() const { + return result_; + } + engine_type& engine() { + return engine_; + } + SPROUT_CONSTEXPR engine_type const& engine() const { + return engine_; + } + SPROUT_CONSTEXPR result_type min() const { + return engine_.min(); + } + SPROUT_CONSTEXPR result_type max() const { + return engine_.max(); + } + friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) { + return lhs.result_ == rhs.result_ + && lhs.engine_ == rhs.engine_ + ; + } + friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) { + return !(lhs == rhs); + } + void swap(random_result& other) { + using std::swap; + swap(result_, other.result_); + swap(engine_, other.engine_); + } + SPROUT_CONSTEXPR reference operator*() const { + return result_; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &result_; + } + random_result& operator++() { + random_result temp((*this)()); + temp.swap(*this); + return *this; + } + random_result operator++(int) { + random_result result(*this); + random_result temp((*this)()); + temp.swap(*this); + return result; + } + }; + // + // swap + // + template + void swap( + sprout::random::random_result& lhs, + sprout::random::random_result& rhs + ) + { + lhs.swap(rhs); + } + } // namespace random + + // + // next + // + template + SPROUT_CONSTEXPR sprout::random::random_result next( + sprout::random::random_result const& it + ) + { + return it(); + } + + using sprout::random::random_result; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP + diff --git a/sprout/random/uniform_01.hpp b/sprout/random/uniform_01.hpp index 64742980..6ccd2100 100644 --- a/sprout/random/uniform_01.hpp +++ b/sprout/random/uniform_01.hpp @@ -1,92 +1,92 @@ -#ifndef SPROUT_RANDOM_UNIFORM_01_HPP -#define SPROUT_RANDOM_UNIFORM_01_HPP - -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - // - // uniform_01 - // - template - class uniform_01 { - public: - typedef RealType input_type; - typedef RealType result_type; - private: - template - SPROUT_CONSTEXPR sprout::random::random_result generate_1( - Engine const& eng, - sprout::random::random_result const& rnd, - result_type result - ) const - { - return result < result_type(1) - ? sprout::random::random_result(result, rnd.engine(), *this) - : operator()(rnd.engine()) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate( - Engine const& eng, - sprout::random::random_result const& rnd - ) const - { - typedef typename Engine::result_type base_result; - return generate_1( - eng, - rnd, - result_type(rnd.result() - eng.min()) * ( - result_type(1) / ( - result_type(eng.max() - eng.min()) + result_type( - std::numeric_limits::is_integer ? 1 : 0 - ) - ) - ) - ); - } - public: - SPROUT_CONSTEXPR result_type min() const { - return result_type(0); - } - SPROUT_CONSTEXPR result_type max() const { - return result_type(1); - } - template - SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { - return generate(eng, eng()); - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - uniform_01 const& rhs - ) - { - return lhs; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - uniform_01 const& rhs - ) - { - return lhs; - } - SPROUT_CONSTEXPR friend bool operator==(uniform_01 const& lhs, uniform_01 const& rhs) { - return true; - } - SPROUT_CONSTEXPR friend bool operator!=(uniform_01 const& lhs, uniform_01 const& rhs) { - return !(lhs == rhs); - } - }; - } // namespace random - - using sprout::random::uniform_01; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_UNIFORM_01_HPP - +#ifndef SPROUT_RANDOM_UNIFORM_01_HPP +#define SPROUT_RANDOM_UNIFORM_01_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // uniform_01 + // + template + class uniform_01 { + public: + typedef RealType input_type; + typedef RealType result_type; + private: + template + SPROUT_CONSTEXPR sprout::random::random_result generate_1( + Engine const& eng, + sprout::random::random_result const& rnd, + result_type result + ) const + { + return result < result_type(1) + ? sprout::random::random_result(result, rnd.engine(), *this) + : operator()(rnd.engine()) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate( + Engine const& eng, + sprout::random::random_result const& rnd + ) const + { + typedef typename Engine::result_type base_result; + return generate_1( + eng, + rnd, + result_type(rnd.result() - eng.min()) * ( + result_type(1) / ( + result_type(eng.max() - eng.min()) + result_type( + std::numeric_limits::is_integer ? 1 : 0 + ) + ) + ) + ); + } + public: + SPROUT_CONSTEXPR result_type min() const { + return result_type(0); + } + SPROUT_CONSTEXPR result_type max() const { + return result_type(1); + } + template + SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { + return generate(eng, eng()); + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + uniform_01 const& rhs + ) + { + return lhs; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + uniform_01 const& rhs + ) + { + return lhs; + } + SPROUT_CONSTEXPR friend bool operator==(uniform_01 const& lhs, uniform_01 const& rhs) { + return true; + } + SPROUT_CONSTEXPR friend bool operator!=(uniform_01 const& lhs, uniform_01 const& rhs) { + return !(lhs == rhs); + } + }; + } // namespace random + + using sprout::random::uniform_01; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_UNIFORM_01_HPP + diff --git a/sprout/random/uniform_int_distribution.hpp b/sprout/random/uniform_int_distribution.hpp index 35827883..19567520 100644 --- a/sprout/random/uniform_int_distribution.hpp +++ b/sprout/random/uniform_int_distribution.hpp @@ -1,527 +1,527 @@ -#ifndef SPROUT_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP -#define SPROUT_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - namespace detail { - template - struct generate_uniform_int_result { - public: - T result; - Engine engine; - }; - - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int( - Engine const& eng, - T min_value, - T max_value, - std::true_type - ); - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_3_1( - sprout::random::random_result const& rnd, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange, - BaseUnsigned bucket_size - ); - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_3_1_1( - Engine const& eng, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange, - BaseUnsigned bucket_size, - BaseUnsigned result - ) - { - typedef T result_type; - return result <= static_cast(range) - ? sprout::random::detail::generate_uniform_int_result{ - sprout::random::detail::add()(result, min_value), - eng - } - : generate_uniform_int_true_3_1( - eng(), - min_value, - range, - bmin, - brange, - bucket_size - ) - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_3_1( - sprout::random::random_result const& rnd, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange, - BaseUnsigned bucket_size - ) - { - return sprout::random::detail::generate_uniform_int_true_3_1_1( - rnd.engine(), - min_value, - range, - bmin, - brange, - bucket_size, - sprout::random::detail::subtract()(rnd.result(), bmin) / bucket_size - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_3( - Engine const& eng, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange - ) - { - return sprout::random::detail::generate_uniform_int_true_3_1( - eng(), - min_value, - range, - bmin, - brange, - brange == std::numeric_limits::max() - ? brange / (static_cast(range) + 1) + ( - brange % (static_cast(range) + 1) == static_cast(range) ? 1 : 0 - ) - : (brange + 1) / (static_cast(range) + 1) - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2( - Engine const& eng, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange - ); - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_4( - Engine const& eng, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange, - RangeType result, - RangeType result_increment - ) - { - typedef T result_type; - return result < result_increment || result > range - ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) - : sprout::random::detail::generate_uniform_int_result{ - random::detail::add()(result, min_value), - eng - } - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_3( - Engine const& eng, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange, - RangeType result, - RangeType mult, - RangeType result_increment - ) - { - return std::numeric_limits::max() / mult < result_increment - ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) - : generate_uniform_int_true_2_4( - eng, - min_value, - range, - bmin, - brange, - result + (result_increment * mult), - result_increment * mult - ) - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_2( - Engine const& eng, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange, - RangeType result, - RangeType mult, - Result const& result_increment_base - ) - { - return sprout::random::detail::generate_uniform_int_true_2_3( - result_increment_base.engine, - min_value, - range, - bmin, - brange, - result, - mult, - result_increment_base.result - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_1( - Engine const& eng, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange, - RangeType limit, - RangeType result = RangeType(0), - RangeType mult = RangeType(1) - ); - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_1_1( - sprout::random::random_result const& rnd, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange, - RangeType limit, - RangeType result, - RangeType mult - ) - { - return mult * RangeType(brange) == range - mult + 1 - ? sprout::random::detail::generate_uniform_int_result{ - static_cast( - result + static_cast(sprout::random::detail::subtract()(rnd.result(), bmin) * mult) - ), - rnd.engine() - } - : sprout::random::detail::generate_uniform_int_true_2_1( - rnd.engine(), - min_value, - range, - bmin, - brange, - limit, - result + static_cast(sprout::random::detail::subtract()(rnd.result(), bmin) * mult), - mult * (RangeType(brange) + RangeType(1)) - ) - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_1( - Engine const& eng, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange, - RangeType limit, - RangeType result, - RangeType mult - ) - { - return mult <= limit - ? generate_uniform_int_true_2_1_1( - eng(), - min_value, - range, - bmin, - brange, - limit, - result, - mult - ) - : sprout::random::detail::generate_uniform_int_true_2_2( - eng, - min_value, - range, - bmin, - brange, - result, - mult, - sprout::random::detail::generate_uniform_int( - eng, - static_cast(0), - static_cast(range / mult), - std::true_type() - ) - ) - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2( - Engine const& eng, - T min_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange - ) - { - return sprout::random::detail::generate_uniform_int_true_2_1( - eng, - min_value, - range, - bmin, - brange, - range == std::numeric_limits::max() - ? range / (RangeType(brange) + 1) + ( - range % (RangeType(brange) + 1) == RangeType(brange) ? 1 : 0 - ) - : (range + 1) / (RangeType(brange) + 1) - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_1_1( - sprout::random::random_result const& rnd, - T min_value, - BaseResult bmin - ) - { - typedef T result_type; - typedef typename std::make_unsigned::type base_unsigned; - return sprout::random::detail::generate_uniform_int_result{ - sprout::random::detail::add()( - base_unsigned(sprout::random::detail::subtract()(rnd.result(), bmin)), - min_value - ), - rnd.engine() - }; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_1( - Engine const& eng, - T min_value, - T max_value, - RangeType range, - BaseResult bmin, - BaseUnsigned brange - ) - { - return range == 0 ? sprout::random::detail::generate_uniform_int_result{min_value, eng} - : brange == range ? sprout::random::detail::generate_uniform_int_true_1_1(eng(), min_value, bmin) - : brange < range ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) - : sprout::random::detail::generate_uniform_int_true_3(eng, min_value, range, bmin, brange) - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int( - Engine const& eng, - T min_value, - T max_value, - std::true_type - ) - { - typedef T result_type; - typedef typename std::make_unsigned::type range_type; - typedef typename Engine::result_type base_result; - typedef typename std::make_unsigned::type base_unsigned; - return sprout::random::detail::generate_uniform_int_true_1( - eng, - min_value, - max_value, - range_type(sprout::random::detail::subtract()(max_value, min_value)), - base_result(eng.min()), - base_unsigned(sprout::random::detail::subtract()(eng.max(), eng.min())) - ); - }; - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_false_1( - Result const& rnd - ) - { - return sprout::random::detail::generate_uniform_int_result{ - rnd.result, - rnd.engine.base() - }; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int( - Engine const& eng, - T min_value, - T max_value, - std::false_type - ) - { - return generate_uniform_int_false_1( - sprout::random::detail::generate_uniform_int( - sprout::random::detail::uniform_int_float(eng), - min_value, - max_value, - std::true_type() - ) - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int( - Engine const& eng, - T min_value, - T max_value - ) - { - return sprout::random::detail::generate_uniform_int( - eng, - min_value, - max_value, - std::is_integral() - ); - } - } // namespace detail - // - // uniform_int_distribution - // - template - class uniform_int_distribution { - public: - typedef IntType input_type; - typedef IntType result_type; - private: - static SPROUT_CONSTEXPR IntType arg_check(IntType min_arg, IntType max_arg) { - return min_arg <= max_arg - ? min_arg - : throw "assert(min_arg <= max_arg)" - ; - } - public: - // - // param_type - // - class param_type { - public: - typedef uniform_int_distribution distribution_type; - private: - IntType min_; - IntType max_; - public: - SPROUT_CONSTEXPR param_type() - : min_(0) - , max_(9) - {} - SPROUT_CONSTEXPR explicit param_type(IntType min_arg, IntType max_arg = 9) - : min_(arg_check(min_arg, max_arg)) - , max_(max_arg) - {} - SPROUT_CONSTEXPR IntType a() const { - return min_; - } - SPROUT_CONSTEXPR IntType b() const { - return max_; - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - param_type const& rhs - ) - { - return lhs >> rhs.min_ >> std::ws >> rhs.max_; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - param_type const& rhs - ) - { - return lhs << rhs.min_ << " " << rhs.max_; - } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { - return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; - } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { - return !(lhs == rhs); - } - }; - private: - result_type min_; - result_type max_; - private: - template - SPROUT_CONSTEXPR sprout::random::random_result generate(Result const& rnd) const { - return sprout::random::random_result( - rnd.result, - rnd.engine, - *this - ); - } - public: - SPROUT_CONSTEXPR uniform_int_distribution() - : min_(0) - , max_(9) - {} - SPROUT_CONSTEXPR explicit uniform_int_distribution(IntType min_arg, IntType max_arg = 9) - : min_(arg_check(min_arg, max_arg)) - , max_(max_arg) - {} - explicit uniform_int_distribution(param_type const& parm) - : min_(parm.a()) - , max_(parm.b()) - {} - SPROUT_CONSTEXPR result_type a() const { - return min_; - } - SPROUT_CONSTEXPR result_type b() const { - return max_; - } - SPROUT_CONSTEXPR result_type min() const { - return min_; - } - SPROUT_CONSTEXPR result_type max() const { - return max_; - } - SPROUT_CONSTEXPR param_type param() const { - return param_type(min_, max_); - } - void param(param_type const& parm) { - min_ = parm.a(); - max_ = parm.b(); - } - template - SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { - return generate(sprout::random::detail::generate_uniform_int(eng, min_, max_)); - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - uniform_int_distribution const& rhs - ) - { - param_type parm; - return lhs >> parm; - param(parm); - return lhs; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - uniform_int_distribution const& rhs - ) - { - return lhs << param(); - } - SPROUT_CONSTEXPR friend bool operator==(uniform_int_distribution const& lhs, uniform_int_distribution const& rhs) { - return lhs.param() == rhs.param(); - } - SPROUT_CONSTEXPR friend bool operator!=(uniform_int_distribution const& lhs, uniform_int_distribution const& rhs) { - return !(lhs == rhs); - } - }; - } // namespace random - - using sprout::random::uniform_int_distribution; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP - +#ifndef SPROUT_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP +#define SPROUT_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + namespace detail { + template + struct generate_uniform_int_result { + public: + T result; + Engine engine; + }; + + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int( + Engine const& eng, + T min_value, + T max_value, + std::true_type + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_3_1( + sprout::random::random_result const& rnd, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange, + BaseUnsigned bucket_size + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_3_1_1( + Engine const& eng, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange, + BaseUnsigned bucket_size, + BaseUnsigned result + ) + { + typedef T result_type; + return result <= static_cast(range) + ? sprout::random::detail::generate_uniform_int_result{ + sprout::random::detail::add()(result, min_value), + eng + } + : generate_uniform_int_true_3_1( + eng(), + min_value, + range, + bmin, + brange, + bucket_size + ) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_3_1( + sprout::random::random_result const& rnd, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange, + BaseUnsigned bucket_size + ) + { + return sprout::random::detail::generate_uniform_int_true_3_1_1( + rnd.engine(), + min_value, + range, + bmin, + brange, + bucket_size, + sprout::random::detail::subtract()(rnd.result(), bmin) / bucket_size + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_3( + Engine const& eng, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange + ) + { + return sprout::random::detail::generate_uniform_int_true_3_1( + eng(), + min_value, + range, + bmin, + brange, + brange == std::numeric_limits::max() + ? brange / (static_cast(range) + 1) + ( + brange % (static_cast(range) + 1) == static_cast(range) ? 1 : 0 + ) + : (brange + 1) / (static_cast(range) + 1) + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2( + Engine const& eng, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_4( + Engine const& eng, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange, + RangeType result, + RangeType result_increment + ) + { + typedef T result_type; + return result < result_increment || result > range + ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) + : sprout::random::detail::generate_uniform_int_result{ + random::detail::add()(result, min_value), + eng + } + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_3( + Engine const& eng, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange, + RangeType result, + RangeType mult, + RangeType result_increment + ) + { + return std::numeric_limits::max() / mult < result_increment + ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) + : generate_uniform_int_true_2_4( + eng, + min_value, + range, + bmin, + brange, + result + (result_increment * mult), + result_increment * mult + ) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_2( + Engine const& eng, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange, + RangeType result, + RangeType mult, + Result const& result_increment_base + ) + { + return sprout::random::detail::generate_uniform_int_true_2_3( + result_increment_base.engine, + min_value, + range, + bmin, + brange, + result, + mult, + result_increment_base.result + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_1( + Engine const& eng, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange, + RangeType limit, + RangeType result = RangeType(0), + RangeType mult = RangeType(1) + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_1_1( + sprout::random::random_result const& rnd, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange, + RangeType limit, + RangeType result, + RangeType mult + ) + { + return mult * RangeType(brange) == range - mult + 1 + ? sprout::random::detail::generate_uniform_int_result{ + static_cast( + result + static_cast(sprout::random::detail::subtract()(rnd.result(), bmin) * mult) + ), + rnd.engine() + } + : sprout::random::detail::generate_uniform_int_true_2_1( + rnd.engine(), + min_value, + range, + bmin, + brange, + limit, + result + static_cast(sprout::random::detail::subtract()(rnd.result(), bmin) * mult), + mult * (RangeType(brange) + RangeType(1)) + ) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2_1( + Engine const& eng, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange, + RangeType limit, + RangeType result, + RangeType mult + ) + { + return mult <= limit + ? generate_uniform_int_true_2_1_1( + eng(), + min_value, + range, + bmin, + brange, + limit, + result, + mult + ) + : sprout::random::detail::generate_uniform_int_true_2_2( + eng, + min_value, + range, + bmin, + brange, + result, + mult, + sprout::random::detail::generate_uniform_int( + eng, + static_cast(0), + static_cast(range / mult), + std::true_type() + ) + ) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_2( + Engine const& eng, + T min_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange + ) + { + return sprout::random::detail::generate_uniform_int_true_2_1( + eng, + min_value, + range, + bmin, + brange, + range == std::numeric_limits::max() + ? range / (RangeType(brange) + 1) + ( + range % (RangeType(brange) + 1) == RangeType(brange) ? 1 : 0 + ) + : (range + 1) / (RangeType(brange) + 1) + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_1_1( + sprout::random::random_result const& rnd, + T min_value, + BaseResult bmin + ) + { + typedef T result_type; + typedef typename std::make_unsigned::type base_unsigned; + return sprout::random::detail::generate_uniform_int_result{ + sprout::random::detail::add()( + base_unsigned(sprout::random::detail::subtract()(rnd.result(), bmin)), + min_value + ), + rnd.engine() + }; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_true_1( + Engine const& eng, + T min_value, + T max_value, + RangeType range, + BaseResult bmin, + BaseUnsigned brange + ) + { + return range == 0 ? sprout::random::detail::generate_uniform_int_result{min_value, eng} + : brange == range ? sprout::random::detail::generate_uniform_int_true_1_1(eng(), min_value, bmin) + : brange < range ? sprout::random::detail::generate_uniform_int_true_2(eng, min_value, range, bmin, brange) + : sprout::random::detail::generate_uniform_int_true_3(eng, min_value, range, bmin, brange) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int( + Engine const& eng, + T min_value, + T max_value, + std::true_type + ) + { + typedef T result_type; + typedef typename std::make_unsigned::type range_type; + typedef typename Engine::result_type base_result; + typedef typename std::make_unsigned::type base_unsigned; + return sprout::random::detail::generate_uniform_int_true_1( + eng, + min_value, + max_value, + range_type(sprout::random::detail::subtract()(max_value, min_value)), + base_result(eng.min()), + base_unsigned(sprout::random::detail::subtract()(eng.max(), eng.min())) + ); + }; + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int_false_1( + Result const& rnd + ) + { + return sprout::random::detail::generate_uniform_int_result{ + rnd.result, + rnd.engine.base() + }; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int( + Engine const& eng, + T min_value, + T max_value, + std::false_type + ) + { + return generate_uniform_int_false_1( + sprout::random::detail::generate_uniform_int( + sprout::random::detail::uniform_int_float(eng), + min_value, + max_value, + std::true_type() + ) + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_int_result generate_uniform_int( + Engine const& eng, + T min_value, + T max_value + ) + { + return sprout::random::detail::generate_uniform_int( + eng, + min_value, + max_value, + std::is_integral() + ); + } + } // namespace detail + // + // uniform_int_distribution + // + template + class uniform_int_distribution { + public: + typedef IntType input_type; + typedef IntType result_type; + private: + static SPROUT_CONSTEXPR IntType arg_check(IntType min_arg, IntType max_arg) { + return min_arg <= max_arg + ? min_arg + : throw "assert(min_arg <= max_arg)" + ; + } + public: + // + // param_type + // + class param_type { + public: + typedef uniform_int_distribution distribution_type; + private: + IntType min_; + IntType max_; + public: + SPROUT_CONSTEXPR param_type() + : min_(0) + , max_(9) + {} + SPROUT_CONSTEXPR explicit param_type(IntType min_arg, IntType max_arg = 9) + : min_(arg_check(min_arg, max_arg)) + , max_(max_arg) + {} + SPROUT_CONSTEXPR IntType a() const { + return min_; + } + SPROUT_CONSTEXPR IntType b() const { + return max_; + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + param_type const& rhs + ) + { + return lhs >> rhs.min_ >> std::ws >> rhs.max_; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + param_type const& rhs + ) + { + return lhs << rhs.min_ << " " << rhs.max_; + } + SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; + } + SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + return !(lhs == rhs); + } + }; + private: + result_type min_; + result_type max_; + private: + template + SPROUT_CONSTEXPR sprout::random::random_result generate(Result const& rnd) const { + return sprout::random::random_result( + rnd.result, + rnd.engine, + *this + ); + } + public: + SPROUT_CONSTEXPR uniform_int_distribution() + : min_(0) + , max_(9) + {} + SPROUT_CONSTEXPR explicit uniform_int_distribution(IntType min_arg, IntType max_arg = 9) + : min_(arg_check(min_arg, max_arg)) + , max_(max_arg) + {} + explicit uniform_int_distribution(param_type const& parm) + : min_(parm.a()) + , max_(parm.b()) + {} + SPROUT_CONSTEXPR result_type a() const { + return min_; + } + SPROUT_CONSTEXPR result_type b() const { + return max_; + } + SPROUT_CONSTEXPR result_type min() const { + return min_; + } + SPROUT_CONSTEXPR result_type max() const { + return max_; + } + SPROUT_CONSTEXPR param_type param() const { + return param_type(min_, max_); + } + void param(param_type const& parm) { + min_ = parm.a(); + max_ = parm.b(); + } + template + SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { + return generate(sprout::random::detail::generate_uniform_int(eng, min_, max_)); + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + uniform_int_distribution const& rhs + ) + { + param_type parm; + return lhs >> parm; + param(parm); + return lhs; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + uniform_int_distribution const& rhs + ) + { + return lhs << param(); + } + SPROUT_CONSTEXPR friend bool operator==(uniform_int_distribution const& lhs, uniform_int_distribution const& rhs) { + return lhs.param() == rhs.param(); + } + SPROUT_CONSTEXPR friend bool operator!=(uniform_int_distribution const& lhs, uniform_int_distribution const& rhs) { + return !(lhs == rhs); + } + }; + } // namespace random + + using sprout::random::uniform_int_distribution; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_UNIFORM_INT_DISTRIBUTION_HPP + diff --git a/sprout/random/uniform_real_distribution.hpp b/sprout/random/uniform_real_distribution.hpp index 81a1b0de..b6912ff9 100644 --- a/sprout/random/uniform_real_distribution.hpp +++ b/sprout/random/uniform_real_distribution.hpp @@ -1,319 +1,319 @@ -#ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP -#define SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP - -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - namespace detail { - template - struct generate_uniform_real_result { - public: - T result; - Engine engine; - }; - - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_1( - sprout::random::random_result const& rnd, - T min_value, - T max_value - ); - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_3( - Engine const& eng, - T min_value, - T max_value, - T result - ) - { - return result < max_value - ? sprout::random::detail::generate_uniform_real_result{result, eng} - : sprout::random::detail::generate_uniform_real_false_1(eng(), min_value, max_value) - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_2( - Engine const& eng, - T min_value, - T max_value, - T numerator, - T divisor - ) - { - return divisor > 0 - ? numerator >= 0 && numerator <= divisor - ? sprout::random::detail::generate_uniform_real_false_3( - eng, - min_value, - max_value, - numerator / divisor * (max_value - min_value) + min_value - ) - : throw "assert(numerator >= 0 && numerator <= divisor)" - : throw "assert(divisor > 0)" - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_1( - sprout::random::random_result const& rnd, - T min_value, - T max_value - ) - { - return sprout::random::detail::generate_uniform_real_false_2( - rnd.engine(), - min_value, - max_value, - static_cast(rnd.result() - rnd.engine().min()), - static_cast(rnd.engine().max() - rnd.engine().min()) - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real( - Engine const& eng, - T min_value, - T max_value, - std::false_type - ) - { - return sprout::random::detail::generate_uniform_real_false_1( - eng(), - min_value, - max_value - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_1( - sprout::random::random_result const& rnd, - T min_value, - T max_value - ); - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_3( - Engine const& eng, - T min_value, - T max_value, - T result - ) - { - return result < max_value - ? sprout::random::detail::generate_uniform_real_result{result, eng} - : sprout::random::detail::generate_uniform_real_true_1(eng(), min_value, max_value) - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_2( - Engine const& eng, - T min_value, - T max_value, - T numerator, - T divisor - ) - { - return divisor > 0 - ? numerator >= 0 && numerator <= divisor - ? sprout::random::detail::generate_uniform_real_true_3( - eng, - min_value, - max_value, - numerator / divisor * (max_value - min_value) + min_value - ) - : throw "assert(numerator >= 0 && numerator <= divisor)" - : throw "assert(divisor > 0)" - ; - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_1( - sprout::random::random_result const& rnd, - T min_value, - T max_value - ) - { - typedef T result_type; - typedef typename Engine::result_type base_result; - return sprout::random::detail::generate_uniform_real_true_2( - rnd.engine(), - min_value, - max_value, - static_cast(sprout::random::detail::subtract()(rnd.result(), rnd.engine().min())), - static_cast(sprout::random::detail::subtract()(rnd.engine().max(), rnd.engine().min())) + 1 - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real( - Engine const& eng, - T min_value, - T max_value, - std::true_type - ) - { - return sprout::random::detail::generate_uniform_real_true_1( - eng(), - min_value, - max_value - ); - } - template - SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real( - Engine const& eng, - T min_value, - T max_value - ) - { - return sprout::random::detail::generate_uniform_real( - eng, - min_value, - max_value, - std::is_integral() - ); - } - } // namespace detail - // - // uniform_real_distribution - // - template - class uniform_real_distribution { - public: - typedef RealType input_type; - typedef RealType result_type; - private: - static SPROUT_CONSTEXPR RealType arg_check(RealType min_arg, RealType max_arg) { - return min_arg <= max_arg - ? min_arg - : throw "assert(min_arg <= max_arg)" - ; - } - public: - // - // param_type - // - class param_type { - public: - typedef uniform_real_distribution distribution_type; - private: - RealType min_; - RealType max_; - public: - SPROUT_CONSTEXPR param_type() - : min_(RealType(0.0)) - , max_(RealType(1.0)) - {} - SPROUT_CONSTEXPR explicit param_type(RealType min_arg, RealType max_arg = RealType(1.0)) - : min_(arg_check(min_arg, max_arg)) - , max_(max_arg) - {} - SPROUT_CONSTEXPR RealType a() const { - return min_; - } - SPROUT_CONSTEXPR RealType b() const { - return max_; - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - param_type const& rhs - ) - { - return lhs >> rhs.min_ >> std::ws >> rhs.max_; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - param_type const& rhs - ) - { - return lhs << rhs.min_ << " " << rhs.max_; - } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { - return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; - } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { - return !(lhs == rhs); - } - }; - private: - result_type min_; - result_type max_; - private: - template - SPROUT_CONSTEXPR sprout::random::random_result generate(Result const& rnd) const { - return sprout::random::random_result( - rnd.result, - rnd.engine, - *this - ); - } - public: - SPROUT_CONSTEXPR uniform_real_distribution() - : min_(RealType(0.0)) - , max_(RealType(1.0)) - {} - SPROUT_CONSTEXPR explicit uniform_real_distribution(RealType min_arg, RealType max_arg = RealType(1.0)) - : min_(arg_check(min_arg, max_arg)) - , max_(max_arg) - {} - explicit uniform_real_distribution(param_type const& parm) - : min_(parm.a()) - , max_(parm.b()) - {} - SPROUT_CONSTEXPR result_type a() const { - return min_; - } - SPROUT_CONSTEXPR result_type b() const { - return max_; - } - SPROUT_CONSTEXPR result_type min() const { - return min_; - } - SPROUT_CONSTEXPR result_type max() const { - return max_; - } - SPROUT_CONSTEXPR param_type param() const { - return param_type(min_, max_); - } - void param(param_type const& parm) { - min_ = parm.a(); - max_ = parm.b(); - } - template - SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { - return generate(sprout::random::detail::generate_uniform_real(eng, min_, max_)); - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - uniform_real_distribution const& rhs - ) - { - param_type parm; - return lhs >> parm; - param(parm); - return lhs; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - uniform_real_distribution const& rhs - ) - { - return lhs << param(); - } - SPROUT_CONSTEXPR friend bool operator==(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { - return lhs.param() == rhs.param(); - } - SPROUT_CONSTEXPR friend bool operator!=(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { - return !(lhs == rhs); - } - }; - } // namespace random - - using sprout::random::uniform_real_distribution; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP - +#ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP +#define SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + namespace detail { + template + struct generate_uniform_real_result { + public: + T result; + Engine engine; + }; + + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_1( + sprout::random::random_result const& rnd, + T min_value, + T max_value + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_3( + Engine const& eng, + T min_value, + T max_value, + T result + ) + { + return result < max_value + ? sprout::random::detail::generate_uniform_real_result{result, eng} + : sprout::random::detail::generate_uniform_real_false_1(eng(), min_value, max_value) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_2( + Engine const& eng, + T min_value, + T max_value, + T numerator, + T divisor + ) + { + return divisor > 0 + ? numerator >= 0 && numerator <= divisor + ? sprout::random::detail::generate_uniform_real_false_3( + eng, + min_value, + max_value, + numerator / divisor * (max_value - min_value) + min_value + ) + : throw "assert(numerator >= 0 && numerator <= divisor)" + : throw "assert(divisor > 0)" + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_false_1( + sprout::random::random_result const& rnd, + T min_value, + T max_value + ) + { + return sprout::random::detail::generate_uniform_real_false_2( + rnd.engine(), + min_value, + max_value, + static_cast(rnd.result() - rnd.engine().min()), + static_cast(rnd.engine().max() - rnd.engine().min()) + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real( + Engine const& eng, + T min_value, + T max_value, + std::false_type + ) + { + return sprout::random::detail::generate_uniform_real_false_1( + eng(), + min_value, + max_value + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_1( + sprout::random::random_result const& rnd, + T min_value, + T max_value + ); + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_3( + Engine const& eng, + T min_value, + T max_value, + T result + ) + { + return result < max_value + ? sprout::random::detail::generate_uniform_real_result{result, eng} + : sprout::random::detail::generate_uniform_real_true_1(eng(), min_value, max_value) + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_2( + Engine const& eng, + T min_value, + T max_value, + T numerator, + T divisor + ) + { + return divisor > 0 + ? numerator >= 0 && numerator <= divisor + ? sprout::random::detail::generate_uniform_real_true_3( + eng, + min_value, + max_value, + numerator / divisor * (max_value - min_value) + min_value + ) + : throw "assert(numerator >= 0 && numerator <= divisor)" + : throw "assert(divisor > 0)" + ; + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real_true_1( + sprout::random::random_result const& rnd, + T min_value, + T max_value + ) + { + typedef T result_type; + typedef typename Engine::result_type base_result; + return sprout::random::detail::generate_uniform_real_true_2( + rnd.engine(), + min_value, + max_value, + static_cast(sprout::random::detail::subtract()(rnd.result(), rnd.engine().min())), + static_cast(sprout::random::detail::subtract()(rnd.engine().max(), rnd.engine().min())) + 1 + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real( + Engine const& eng, + T min_value, + T max_value, + std::true_type + ) + { + return sprout::random::detail::generate_uniform_real_true_1( + eng(), + min_value, + max_value + ); + } + template + SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result generate_uniform_real( + Engine const& eng, + T min_value, + T max_value + ) + { + return sprout::random::detail::generate_uniform_real( + eng, + min_value, + max_value, + std::is_integral() + ); + } + } // namespace detail + // + // uniform_real_distribution + // + template + class uniform_real_distribution { + public: + typedef RealType input_type; + typedef RealType result_type; + private: + static SPROUT_CONSTEXPR RealType arg_check(RealType min_arg, RealType max_arg) { + return min_arg <= max_arg + ? min_arg + : throw "assert(min_arg <= max_arg)" + ; + } + public: + // + // param_type + // + class param_type { + public: + typedef uniform_real_distribution distribution_type; + private: + RealType min_; + RealType max_; + public: + SPROUT_CONSTEXPR param_type() + : min_(RealType(0.0)) + , max_(RealType(1.0)) + {} + SPROUT_CONSTEXPR explicit param_type(RealType min_arg, RealType max_arg = RealType(1.0)) + : min_(arg_check(min_arg, max_arg)) + , max_(max_arg) + {} + SPROUT_CONSTEXPR RealType a() const { + return min_; + } + SPROUT_CONSTEXPR RealType b() const { + return max_; + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + param_type const& rhs + ) + { + return lhs >> rhs.min_ >> std::ws >> rhs.max_; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + param_type const& rhs + ) + { + return lhs << rhs.min_ << " " << rhs.max_; + } + SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; + } + SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + return !(lhs == rhs); + } + }; + private: + result_type min_; + result_type max_; + private: + template + SPROUT_CONSTEXPR sprout::random::random_result generate(Result const& rnd) const { + return sprout::random::random_result( + rnd.result, + rnd.engine, + *this + ); + } + public: + SPROUT_CONSTEXPR uniform_real_distribution() + : min_(RealType(0.0)) + , max_(RealType(1.0)) + {} + SPROUT_CONSTEXPR explicit uniform_real_distribution(RealType min_arg, RealType max_arg = RealType(1.0)) + : min_(arg_check(min_arg, max_arg)) + , max_(max_arg) + {} + explicit uniform_real_distribution(param_type const& parm) + : min_(parm.a()) + , max_(parm.b()) + {} + SPROUT_CONSTEXPR result_type a() const { + return min_; + } + SPROUT_CONSTEXPR result_type b() const { + return max_; + } + SPROUT_CONSTEXPR result_type min() const { + return min_; + } + SPROUT_CONSTEXPR result_type max() const { + return max_; + } + SPROUT_CONSTEXPR param_type param() const { + return param_type(min_, max_); + } + void param(param_type const& parm) { + min_ = parm.a(); + max_ = parm.b(); + } + template + SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { + return generate(sprout::random::detail::generate_uniform_real(eng, min_, max_)); + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + uniform_real_distribution const& rhs + ) + { + param_type parm; + return lhs >> parm; + param(parm); + return lhs; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + uniform_real_distribution const& rhs + ) + { + return lhs << param(); + } + SPROUT_CONSTEXPR friend bool operator==(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { + return lhs.param() == rhs.param(); + } + SPROUT_CONSTEXPR friend bool operator!=(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { + return !(lhs == rhs); + } + }; + } // namespace random + + using sprout::random::uniform_real_distribution; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP + diff --git a/sprout/random/uniform_smallint.hpp b/sprout/random/uniform_smallint.hpp index cb0817cb..891bb820 100644 --- a/sprout/random/uniform_smallint.hpp +++ b/sprout/random/uniform_smallint.hpp @@ -1,255 +1,255 @@ -#ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP -#define SPROUT_RANDOM_UNIFORM_SMALLINT_HPP - -#include -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - // - // uniform_smallint - // - template - class uniform_smallint { - public: - typedef IntType input_type; - typedef IntType result_type; - private: - static SPROUT_CONSTEXPR IntType arg_check(IntType min_arg, IntType max_arg) { - return min_arg <= max_arg - ? min_arg - : throw "assert(min_arg <= max_arg)" - ; - } - public: - // - // param_type - // - class param_type { - public: - typedef uniform_smallint distribution_type; - private: - IntType min_; - IntType max_; - public: - SPROUT_CONSTEXPR param_type() - : min_(0) - , max_(9) - {} - SPROUT_CONSTEXPR explicit param_type(IntType min_arg, IntType max_arg = 9) - : min_(arg_check(min_arg, max_arg)) - , max_(max_arg) - {} - SPROUT_CONSTEXPR IntType a() const { - return min_; - } - SPROUT_CONSTEXPR IntType b() const { - return max_; - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - param_type const& rhs - ) - { - return lhs >> rhs.min_ >> std::ws >> rhs.max_; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - param_type const& rhs - ) - { - return lhs << rhs.min_ << " " << rhs.max_; - } - SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { - return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; - } - SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { - return !(lhs == rhs); - } - }; - private: - result_type min_; - result_type max_; - private: - template - SPROUT_CONSTEXPR sprout::random::random_result generate_true_2( - Engine const& eng, - sprout::random::random_result const& rnd, - RangeType range, - BaseUnsigned base_range, - BaseUnsigned val - ) const - { - return range >= base_range - ? sprout::random::random_result( - sprout::random::detail::add()(static_cast(val), min_), - rnd.engine(), - *this - ) - : sprout::random::random_result( - sprout::random::detail::add()(static_cast(val % (static_cast(range) + 1)), min_), - rnd.engine(), - *this - ) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_true_1( - Engine const& eng, - sprout::random::random_result const& rnd, - RangeType range, - BaseUnsigned base_range - ) const - { - typedef typename Engine::result_type base_result; - return generate_true_2( - eng, - rnd, - range, - base_range, - BaseUnsigned(sprout::random::detail::subtract()(rnd.result(), eng.min())) - ); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate( - Engine const& eng, - std::true_type - ) const - { - typedef typename Engine::result_type base_result; - typedef typename std::make_unsigned::type base_unsigned; - typedef typename std::make_unsigned::type range_type; - return generate_true_1( - eng, - eng(), - range_type(sprout::random::detail::subtract()(max_, min_)), - base_unsigned(sprout::random::detail::subtract()(eng.max(), eng.min())) - ); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_false_2( - Engine const& eng, - sprout::random::random_result > const& rnd, - RangeType range, - RangeType offset - ) const - { - return offset > range - ? sprout::random::random_result( - max_, - rnd.engine(), - *this - ) - : sprout::random::random_result( - sprout::random::detail::add()(offset , min_), - rnd.engine(), - *this - ) - ; - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate_false_1( - Engine const& eng, - sprout::random::random_result > const& rnd, - RangeType range - ) const - { - typedef typename Engine::result_type base_result; - return generate_false_2( - eng, - rnd, - RangeType(sprout::random::detail::subtract()(max_, min_)), - RangeType(static_cast(rnd.result() * (static_cast(range) + 1))) - ); - } - template - SPROUT_CONSTEXPR sprout::random::random_result generate( - Engine const& eng, - std::false_type - ) const - { - typedef typename Engine::result_type base_result; - typedef typename std::make_unsigned::type range_type; - return generate_false_1( - eng, - sprout::random::uniform_01()(eng), - range_type(sprout::random::detail::subtract()(max_, min_)) - ); - } - public: - SPROUT_CONSTEXPR uniform_smallint() - : min_(0) - , max_(9) - {} - SPROUT_CONSTEXPR explicit uniform_smallint(IntType min_arg, IntType max_arg = 9) - : min_(arg_check(min_arg, max_arg)) - , max_(max_arg) - {} - explicit uniform_smallint(param_type const& parm) - : min_(parm.a()) - , max_(parm.b()) - {} - SPROUT_CONSTEXPR result_type a() const { - return min_; - } - SPROUT_CONSTEXPR result_type b() const { - return max_; - } - SPROUT_CONSTEXPR result_type min() const { - return min_; - } - SPROUT_CONSTEXPR result_type max() const { - return max_; - } - SPROUT_CONSTEXPR param_type param() const { - return param_type(min_, max_); - } - void param(param_type const& parm) { - min_ = parm.a(); - max_ = parm.b(); - } - template - SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { - typedef typename Engine::result_type base_result; - return generate(eng, typename std::is_integral::type()); - } - template - friend std::basic_ostream& operator>>( - std::basic_istream& lhs, - uniform_smallint const& rhs - ) - { - param_type parm; - return lhs >> parm; - param(parm); - return lhs; - } - template - friend std::basic_ostream& operator<<( - std::basic_ostream& lhs, - uniform_smallint const& rhs - ) - { - return lhs << param(); - } - SPROUT_CONSTEXPR friend bool operator==(uniform_smallint const& lhs, uniform_smallint const& rhs) { - return lhs.param() == rhs.param(); - } - SPROUT_CONSTEXPR friend bool operator!=(uniform_smallint const& lhs, uniform_smallint const& rhs) { - return !(lhs == rhs); - } - }; - } // namespace random - - using sprout::random::uniform_smallint; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP - +#ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP +#define SPROUT_RANDOM_UNIFORM_SMALLINT_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // uniform_smallint + // + template + class uniform_smallint { + public: + typedef IntType input_type; + typedef IntType result_type; + private: + static SPROUT_CONSTEXPR IntType arg_check(IntType min_arg, IntType max_arg) { + return min_arg <= max_arg + ? min_arg + : throw "assert(min_arg <= max_arg)" + ; + } + public: + // + // param_type + // + class param_type { + public: + typedef uniform_smallint distribution_type; + private: + IntType min_; + IntType max_; + public: + SPROUT_CONSTEXPR param_type() + : min_(0) + , max_(9) + {} + SPROUT_CONSTEXPR explicit param_type(IntType min_arg, IntType max_arg = 9) + : min_(arg_check(min_arg, max_arg)) + , max_(max_arg) + {} + SPROUT_CONSTEXPR IntType a() const { + return min_; + } + SPROUT_CONSTEXPR IntType b() const { + return max_; + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + param_type const& rhs + ) + { + return lhs >> rhs.min_ >> std::ws >> rhs.max_; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + param_type const& rhs + ) + { + return lhs << rhs.min_ << " " << rhs.max_; + } + SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { + return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; + } + SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { + return !(lhs == rhs); + } + }; + private: + result_type min_; + result_type max_; + private: + template + SPROUT_CONSTEXPR sprout::random::random_result generate_true_2( + Engine const& eng, + sprout::random::random_result const& rnd, + RangeType range, + BaseUnsigned base_range, + BaseUnsigned val + ) const + { + return range >= base_range + ? sprout::random::random_result( + sprout::random::detail::add()(static_cast(val), min_), + rnd.engine(), + *this + ) + : sprout::random::random_result( + sprout::random::detail::add()(static_cast(val % (static_cast(range) + 1)), min_), + rnd.engine(), + *this + ) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_true_1( + Engine const& eng, + sprout::random::random_result const& rnd, + RangeType range, + BaseUnsigned base_range + ) const + { + typedef typename Engine::result_type base_result; + return generate_true_2( + eng, + rnd, + range, + base_range, + BaseUnsigned(sprout::random::detail::subtract()(rnd.result(), eng.min())) + ); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate( + Engine const& eng, + std::true_type + ) const + { + typedef typename Engine::result_type base_result; + typedef typename std::make_unsigned::type base_unsigned; + typedef typename std::make_unsigned::type range_type; + return generate_true_1( + eng, + eng(), + range_type(sprout::random::detail::subtract()(max_, min_)), + base_unsigned(sprout::random::detail::subtract()(eng.max(), eng.min())) + ); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_false_2( + Engine const& eng, + sprout::random::random_result > const& rnd, + RangeType range, + RangeType offset + ) const + { + return offset > range + ? sprout::random::random_result( + max_, + rnd.engine(), + *this + ) + : sprout::random::random_result( + sprout::random::detail::add()(offset , min_), + rnd.engine(), + *this + ) + ; + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate_false_1( + Engine const& eng, + sprout::random::random_result > const& rnd, + RangeType range + ) const + { + typedef typename Engine::result_type base_result; + return generate_false_2( + eng, + rnd, + RangeType(sprout::random::detail::subtract()(max_, min_)), + RangeType(static_cast(rnd.result() * (static_cast(range) + 1))) + ); + } + template + SPROUT_CONSTEXPR sprout::random::random_result generate( + Engine const& eng, + std::false_type + ) const + { + typedef typename Engine::result_type base_result; + typedef typename std::make_unsigned::type range_type; + return generate_false_1( + eng, + sprout::random::uniform_01()(eng), + range_type(sprout::random::detail::subtract()(max_, min_)) + ); + } + public: + SPROUT_CONSTEXPR uniform_smallint() + : min_(0) + , max_(9) + {} + SPROUT_CONSTEXPR explicit uniform_smallint(IntType min_arg, IntType max_arg = 9) + : min_(arg_check(min_arg, max_arg)) + , max_(max_arg) + {} + explicit uniform_smallint(param_type const& parm) + : min_(parm.a()) + , max_(parm.b()) + {} + SPROUT_CONSTEXPR result_type a() const { + return min_; + } + SPROUT_CONSTEXPR result_type b() const { + return max_; + } + SPROUT_CONSTEXPR result_type min() const { + return min_; + } + SPROUT_CONSTEXPR result_type max() const { + return max_; + } + SPROUT_CONSTEXPR param_type param() const { + return param_type(min_, max_); + } + void param(param_type const& parm) { + min_ = parm.a(); + max_ = parm.b(); + } + template + SPROUT_CONSTEXPR sprout::random::random_result operator()(Engine const& eng) const { + typedef typename Engine::result_type base_result; + return generate(eng, typename std::is_integral::type()); + } + template + friend std::basic_ostream& operator>>( + std::basic_istream& lhs, + uniform_smallint const& rhs + ) + { + param_type parm; + return lhs >> parm; + param(parm); + return lhs; + } + template + friend std::basic_ostream& operator<<( + std::basic_ostream& lhs, + uniform_smallint const& rhs + ) + { + return lhs << param(); + } + SPROUT_CONSTEXPR friend bool operator==(uniform_smallint const& lhs, uniform_smallint const& rhs) { + return lhs.param() == rhs.param(); + } + SPROUT_CONSTEXPR friend bool operator!=(uniform_smallint const& lhs, uniform_smallint const& rhs) { + return !(lhs == rhs); + } + }; + } // namespace random + + using sprout::random::uniform_smallint; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP + diff --git a/sprout/random/unique_seed.hpp b/sprout/random/unique_seed.hpp index 8d6defd4..9c0f2244 100644 --- a/sprout/random/unique_seed.hpp +++ b/sprout/random/unique_seed.hpp @@ -1,14 +1,14 @@ -#ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP -#define SPROUT_RANDOM_UNIQUE_SEED_HPP - -#include -#include -#include - -// -// SPROUT_UNIQUE_SEED -// -#define SPROUT_UNIQUE_SEED (::sprout::hash_value(SPROUT_PP_UNIQUE_STRING)) - -#endif // #ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP - +#ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP +#define SPROUT_RANDOM_UNIQUE_SEED_HPP + +#include +#include +#include + +// +// SPROUT_UNIQUE_SEED +// +#define SPROUT_UNIQUE_SEED (::sprout::hash_value(SPROUT_PP_UNIQUE_STRING)) + +#endif // #ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP + diff --git a/sprout/random/variate_generator.hpp b/sprout/random/variate_generator.hpp index 3e4ccc99..de76d1d3 100644 --- a/sprout/random/variate_generator.hpp +++ b/sprout/random/variate_generator.hpp @@ -1,84 +1,84 @@ -#ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP -#define SPROUT_RANDOM_VARIATE_GENERATOR_HPP - -#include -#include -#include -#include -#include - -namespace sprout { - namespace random { - // - // variate_generator - // - template - class variate_generator { - private: - typedef sprout::random::detail::ptr_helper engine_helper_type; - typedef sprout::random::detail::ptr_helper distribution_helper_type; - public: - typedef typename engine_helper_type::value_type engine_value_type; - typedef typename distribution_helper_type::value_type distribution_value_type; - typedef typename engine_helper_type::reference_type engine_reference_type; - typedef typename distribution_helper_type::reference_type distribution_reference_type; - typedef typename engine_helper_type::const_reference_type engine_const_reference_type; - typedef typename distribution_helper_type::const_reference_type distribution_const_reference_type; - typedef typename engine_helper_type::rvalue_type engine_param_type; - typedef typename distribution_helper_type::rvalue_type distribution_param_type; - public: - typedef Engine engine_type; - typedef Distribution distribution_type; - typedef typename distribution_value_type::result_type result_type; - private: - engine_type engine_; - distribution_type distribution_; - public: - SPROUT_CONSTEXPR variate_generator( - engine_param_type engine, - distribution_param_type distribution - ) - : engine_(engine) - , distribution_(distribution) - {} - SPROUT_CONSTEXPR sprout::random::random_result operator()() const { - return distribution_(engine_); - } - engine_reference_type engine() { - return engine_helper_type::ref(engine_); - } - SPROUT_CONSTEXPR engine_const_reference_type engine() const { - return engine_helper_type::ref(engine_); - } - distribution_reference_type distribution() { - return distribution_helper_type::ref(distribution_); - } - SPROUT_CONSTEXPR distribution_const_reference_type distribution() const { - return distribution_helper_type::ref(distribution_); - } - SPROUT_CONSTEXPR result_type min() const { - return distribution_.min(); - } - SPROUT_CONSTEXPR result_type max() const { - return distribution_.max(); - } - }; - - // - // combine - // - template - SPROUT_CONSTEXPR sprout::random::variate_generator combine( - Engine const& engine, - Distribution const& distribution - ) - { - return sprout::random::variate_generator(engine, distribution); - } - } // namespace random - - using sprout::random::variate_generator; -} // namespace sprout - -#endif // #ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP - +#ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP +#define SPROUT_RANDOM_VARIATE_GENERATOR_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace random { + // + // variate_generator + // + template + class variate_generator { + private: + typedef sprout::random::detail::ptr_helper engine_helper_type; + typedef sprout::random::detail::ptr_helper distribution_helper_type; + public: + typedef typename engine_helper_type::value_type engine_value_type; + typedef typename distribution_helper_type::value_type distribution_value_type; + typedef typename engine_helper_type::reference_type engine_reference_type; + typedef typename distribution_helper_type::reference_type distribution_reference_type; + typedef typename engine_helper_type::const_reference_type engine_const_reference_type; + typedef typename distribution_helper_type::const_reference_type distribution_const_reference_type; + typedef typename engine_helper_type::rvalue_type engine_param_type; + typedef typename distribution_helper_type::rvalue_type distribution_param_type; + public: + typedef Engine engine_type; + typedef Distribution distribution_type; + typedef typename distribution_value_type::result_type result_type; + private: + engine_type engine_; + distribution_type distribution_; + public: + SPROUT_CONSTEXPR variate_generator( + engine_param_type engine, + distribution_param_type distribution + ) + : engine_(engine) + , distribution_(distribution) + {} + SPROUT_CONSTEXPR sprout::random::random_result operator()() const { + return distribution_(engine_); + } + engine_reference_type engine() { + return engine_helper_type::ref(engine_); + } + SPROUT_CONSTEXPR engine_const_reference_type engine() const { + return engine_helper_type::ref(engine_); + } + distribution_reference_type distribution() { + return distribution_helper_type::ref(distribution_); + } + SPROUT_CONSTEXPR distribution_const_reference_type distribution() const { + return distribution_helper_type::ref(distribution_); + } + SPROUT_CONSTEXPR result_type min() const { + return distribution_.min(); + } + SPROUT_CONSTEXPR result_type max() const { + return distribution_.max(); + } + }; + + // + // combine + // + template + SPROUT_CONSTEXPR sprout::random::variate_generator combine( + Engine const& engine, + Distribution const& distribution + ) + { + return sprout::random::variate_generator(engine, distribution); + } + } // namespace random + + using sprout::random::variate_generator; +} // namespace sprout + +#endif // #ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP + diff --git a/sprout/utility/value_holder.hpp b/sprout/utility/value_holder.hpp index 5dd63d91..4b9a526b 100644 --- a/sprout/utility/value_holder.hpp +++ b/sprout/utility/value_holder.hpp @@ -1,160 +1,160 @@ -#ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP -#define SPROUT_UTILITY_VALUE_HOLDER_HPP - -#include - -namespace sprout { - namespace detail { - template - struct holder_helper { - public: - typedef T value_type; - typedef T& reference; - typedef T const& const_reference; - typedef T const& mutable_or_const_reference; - typedef T* pointer; - typedef T const* const_pointer; - typedef T const* mutable_or_const_pointer; - typedef T const& param_type; - typedef T holder_type; - public: - static SPROUT_CONSTEXPR holder_type const& hold(param_type p) { - return p; - } - static SPROUT_CONSTEXPR reference ref(holder_type& r) { - return r; - } - static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { - return r; - } - static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { - return &r; - } - static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) { - return &r; - } - }; - template - struct holder_helper { - public: - typedef T value_type; - typedef T const& reference; - typedef T const& const_reference; - typedef T const& mutable_or_const_reference; - typedef T const* pointer; - typedef T const* const_pointer; - typedef T const* mutable_or_const_pointer; - typedef T const& param_type; - typedef T holder_type; - public: - static SPROUT_CONSTEXPR holder_type const& hold(param_type p) { - return &p; - } - static SPROUT_CONSTEXPR reference ref(holder_type& r) { - return *r; - } - static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { - return *r; - } - static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { - return &r; - } - static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) { - return &r; - } - }; - template - struct holder_helper { - public: - typedef T value_type; - typedef T& reference; - typedef T const& const_reference; - typedef T& mutable_or_const_reference; - typedef T* pointer; - typedef T const* const_pointer; - typedef T* mutable_or_const_pointer; - typedef T& param_type; - typedef T* holder_type; - public: - static SPROUT_CONSTEXPR holder_type hold(param_type p) { - return &p; - } - static SPROUT_CONSTEXPR reference ref(holder_type r) { - return *r; - } - static SPROUT_CONSTEXPR pointer ptr(holder_type r) { - return r; - } - }; - template - struct holder_helper { - public: - typedef T value_type; - typedef T const& reference; - typedef T const& const_reference; - typedef T const& mutable_or_const_reference; - typedef T const* pointer; - typedef T const* const_pointer; - typedef T const* mutable_or_const_pointer; - typedef T const& param_type; - typedef T const* holder_type; - public: - static SPROUT_CONSTEXPR holder_type hold(param_type p) { - return &p; - } - static SPROUT_CONSTEXPR reference ref(holder_type r) { - return *r; - } - static SPROUT_CONSTEXPR pointer ptr(holder_type r) { - return r; - } - }; - } // namespace detail - // - // value_holder - // - template - class value_holder { - public: - typedef T type; - private: - typedef sprout::detail::holder_helper helper_type; - typedef typename helper_type::holder_type holder_type; - public: - typedef typename helper_type::value_type value_type; - typedef typename helper_type::reference reference; - typedef typename helper_type::const_reference const_reference; - typedef typename helper_type::mutable_or_const_reference mutable_or_const_reference; - typedef typename helper_type::pointer pointer; - typedef typename helper_type::const_pointer const_pointer; - typedef typename helper_type::mutable_or_const_pointer mutable_or_const_pointer; - typedef typename helper_type::param_type param_type; - private: - holder_type holder_; - public: - value_holder() = default; - SPROUT_CONSTEXPR explicit value_holder(param_type p) - : holder_(helper_type::hold(p)) - {} - operator reference() { - return helper_type::ref(holder_); - } - SPROUT_CONSTEXPR operator const_reference() const { - return helper_type::ref(holder_); - } - reference get() { - return helper_type::ref(holder_); - } - SPROUT_CONSTEXPR mutable_or_const_reference get() const { - return helper_type::ref(holder_); - } - pointer get_pointer() { - return helper_type::ptr(holder_); - } - SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer() const { - return helper_type::ptr(holder_); - } - }; -} // namespace sprout - -#endif // #ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP +#ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP +#define SPROUT_UTILITY_VALUE_HOLDER_HPP + +#include + +namespace sprout { + namespace detail { + template + struct holder_helper { + public: + typedef T value_type; + typedef T& reference; + typedef T const& const_reference; + typedef T const& mutable_or_const_reference; + typedef T* pointer; + typedef T const* const_pointer; + typedef T const* mutable_or_const_pointer; + typedef T const& param_type; + typedef T holder_type; + public: + static SPROUT_CONSTEXPR holder_type const& hold(param_type p) { + return p; + } + static SPROUT_CONSTEXPR reference ref(holder_type& r) { + return r; + } + static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { + return r; + } + static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { + return &r; + } + static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) { + return &r; + } + }; + template + struct holder_helper { + public: + typedef T value_type; + typedef T const& reference; + typedef T const& const_reference; + typedef T const& mutable_or_const_reference; + typedef T const* pointer; + typedef T const* const_pointer; + typedef T const* mutable_or_const_pointer; + typedef T const& param_type; + typedef T holder_type; + public: + static SPROUT_CONSTEXPR holder_type const& hold(param_type p) { + return &p; + } + static SPROUT_CONSTEXPR reference ref(holder_type& r) { + return *r; + } + static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { + return *r; + } + static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { + return &r; + } + static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) { + return &r; + } + }; + template + struct holder_helper { + public: + typedef T value_type; + typedef T& reference; + typedef T const& const_reference; + typedef T& mutable_or_const_reference; + typedef T* pointer; + typedef T const* const_pointer; + typedef T* mutable_or_const_pointer; + typedef T& param_type; + typedef T* holder_type; + public: + static SPROUT_CONSTEXPR holder_type hold(param_type p) { + return &p; + } + static SPROUT_CONSTEXPR reference ref(holder_type r) { + return *r; + } + static SPROUT_CONSTEXPR pointer ptr(holder_type r) { + return r; + } + }; + template + struct holder_helper { + public: + typedef T value_type; + typedef T const& reference; + typedef T const& const_reference; + typedef T const& mutable_or_const_reference; + typedef T const* pointer; + typedef T const* const_pointer; + typedef T const* mutable_or_const_pointer; + typedef T const& param_type; + typedef T const* holder_type; + public: + static SPROUT_CONSTEXPR holder_type hold(param_type p) { + return &p; + } + static SPROUT_CONSTEXPR reference ref(holder_type r) { + return *r; + } + static SPROUT_CONSTEXPR pointer ptr(holder_type r) { + return r; + } + }; + } // namespace detail + // + // value_holder + // + template + class value_holder { + public: + typedef T type; + private: + typedef sprout::detail::holder_helper helper_type; + typedef typename helper_type::holder_type holder_type; + public: + typedef typename helper_type::value_type value_type; + typedef typename helper_type::reference reference; + typedef typename helper_type::const_reference const_reference; + typedef typename helper_type::mutable_or_const_reference mutable_or_const_reference; + typedef typename helper_type::pointer pointer; + typedef typename helper_type::const_pointer const_pointer; + typedef typename helper_type::mutable_or_const_pointer mutable_or_const_pointer; + typedef typename helper_type::param_type param_type; + private: + holder_type holder_; + public: + value_holder() = default; + SPROUT_CONSTEXPR explicit value_holder(param_type p) + : holder_(helper_type::hold(p)) + {} + operator reference() { + return helper_type::ref(holder_); + } + SPROUT_CONSTEXPR operator const_reference() const { + return helper_type::ref(holder_); + } + reference get() { + return helper_type::ref(holder_); + } + SPROUT_CONSTEXPR mutable_or_const_reference get() const { + return helper_type::ref(holder_); + } + pointer get_pointer() { + return helper_type::ptr(holder_); + } + SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer() const { + return helper_type::ptr(holder_); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP