1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-06-07 00:51:32 +00:00

改行コード統一

This commit is contained in:
bolero-MURAKAMI 2011-10-13 05:28:33 +09:00
parent 7abc568a53
commit f3a7041250
29 changed files with 4034 additions and 4034 deletions

View file

@ -1,8 +1,8 @@
#ifndef SPROUT_FUNCTIONAL_HASH_HPP #ifndef SPROUT_FUNCTIONAL_HASH_HPP
#define SPROUT_FUNCTIONAL_HASH_HPP #define SPROUT_FUNCTIONAL_HASH_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/functional/hash/hash.hpp> #include <sprout/functional/hash/hash.hpp>
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP #endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP

View file

@ -1,17 +1,17 @@
#ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP #ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP
#define SPROUT_FUNCTIONAL_HASH_ARRAY_HPP #define SPROUT_FUNCTIONAL_HASH_ARRAY_HPP
#include <cstddef> #include <cstddef>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/functional/hash/hash.hpp> #include <sprout/functional/hash/hash.hpp>
#include <sprout/array.hpp> #include <sprout/array.hpp>
namespace sprout { namespace sprout {
template<typename T, std::size_t N> template<typename T, std::size_t N>
SPROUT_CONSTEXPR std::size_t hash_value(sprout::array<T, N> const& v) { SPROUT_CONSTEXPR std::size_t hash_value(sprout::array<T, N> const& v) {
return sprout::hash_range(v.begin(), v.end()); return sprout::hash_range(v.begin(), v.end());
} }
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP #endif // #ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP

View file

@ -1,227 +1,227 @@
#ifndef SPROUT_FUNCTIONAL_HASH_HPP #ifndef SPROUT_FUNCTIONAL_HASH_HPP
#define SPROUT_FUNCTIONAL_HASH_HPP #define SPROUT_FUNCTIONAL_HASH_HPP
#include <cstddef> #include <cstddef>
#include <limits> #include <limits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/functional/hash/hash_fwd.hpp> #include <sprout/functional/hash/hash_fwd.hpp>
namespace sprout { namespace sprout {
// //
// hash_value // hash_value
// //
SPROUT_CONSTEXPR inline std::size_t hash_value(bool v); 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(char v);
SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t 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(unsigned char v);
SPROUT_CONSTEXPR inline std::size_t hash_value(signed 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(short v);
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned 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(int v);
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned 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(long v);
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned 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(long long v);
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned 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(float v);
//SPROUT_CONSTEXPR std::size_t inline hash_value(double v); //SPROUT_CONSTEXPR std::size_t inline hash_value(double v);
//SPROUT_CONSTEXPR std::size_t inline hash_value(long double v); //SPROUT_CONSTEXPR std::size_t inline hash_value(long double v);
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_value(T*); SPROUT_CONSTEXPR std::size_t hash_value(T*);
template<typename T, std::size_t N> template<typename T, std::size_t N>
SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]); SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]);
namespace hash_detail { namespace hash_detail {
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_value_signed_2(T val, int length, std::size_t seed, T positive, std::size_t i) { 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 return i > 0
? hash_value_signed_2( ? hash_value_signed_2(
val, val,
length, length,
seed ^ static_cast<std::size_t>((positive >> i) + (seed << 6) + (seed >> 2)), seed ^ static_cast<std::size_t>((positive >> i) + (seed << 6) + (seed >> 2)),
positive, positive,
i - std::numeric_limits<std::size_t>::digits i - std::numeric_limits<std::size_t>::digits
) )
: seed ^ static_cast<std::size_t>(val + (seed << 6) + (seed >> 2)) : seed ^ static_cast<std::size_t>(val + (seed << 6) + (seed >> 2))
; ;
} }
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_value_signed_1(T val, int length, std::size_t seed, T positive) { 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<std::size_t>::digits); return hash_value_signed_2(val, length, seed, positive, length * std::numeric_limits<std::size_t>::digits);
} }
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_value_signed(T val) { SPROUT_CONSTEXPR std::size_t hash_value_signed(T val) {
return sprout::hash_detail::hash_value_signed_1( return sprout::hash_detail::hash_value_signed_1(
val, val,
(std::numeric_limits<T>::digits - 1) / std::numeric_limits<std::size_t>::digits, (std::numeric_limits<T>::digits - 1) / std::numeric_limits<std::size_t>::digits,
0, 0,
val < 0 ? -1 - val : val val < 0 ? -1 - val : val
); );
} }
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_value_unsigned_2(T val, int length, std::size_t seed, std::size_t i) { SPROUT_CONSTEXPR std::size_t hash_value_unsigned_2(T val, int length, std::size_t seed, std::size_t i) {
return i > 0 return i > 0
? hash_value_unsigned_2( ? hash_value_unsigned_2(
val, val,
length, length,
seed ^ static_cast<std::size_t>((val >> i) + (seed << 6) + (seed >> 2)), seed ^ static_cast<std::size_t>((val >> i) + (seed << 6) + (seed >> 2)),
i - std::numeric_limits<std::size_t>::digits i - std::numeric_limits<std::size_t>::digits
) )
: seed ^ static_cast<std::size_t>(val + (seed << 6) + (seed >> 2)) : seed ^ static_cast<std::size_t>(val + (seed << 6) + (seed >> 2))
; ;
} }
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_value_unsigned_1(T val, int length, std::size_t seed) { 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<std::size_t>::digits); return hash_value_unsigned_2(val, length, seed, length * std::numeric_limits<std::size_t>::digits);
} }
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_value_unsigned(T val) { SPROUT_CONSTEXPR std::size_t hash_value_unsigned(T val) {
return sprout::hash_detail::hash_value_unsigned_1( return sprout::hash_detail::hash_value_unsigned_1(
val, val,
(std::numeric_limits<T>::digits - 1) / std::numeric_limits<std::size_t>::digits, (std::numeric_limits<T>::digits - 1) / std::numeric_limits<std::size_t>::digits,
0 0
); );
} }
SPROUT_CONSTEXPR inline std::size_t hash_value_pointer_1(std::size_t x) { SPROUT_CONSTEXPR inline std::size_t hash_value_pointer_1(std::size_t x) {
return x + (x >> 3); return x + (x >> 3);
} }
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_value_pointer(T* v) { SPROUT_CONSTEXPR std::size_t hash_value_pointer(T* v) {
return sprout::hash_detail::hash_value_pointer_1(static_cast<std::size_t>(reinterpret_cast<std::ptrdiff_t>(v))); return sprout::hash_detail::hash_value_pointer_1(static_cast<std::size_t>(reinterpret_cast<std::ptrdiff_t>(v)));
} }
} // namespace hash_detail } // namespace hash_detail
// //
// hash_value // hash_value
// //
SPROUT_CONSTEXPR inline std::size_t hash_value(bool v) { SPROUT_CONSTEXPR inline std::size_t hash_value(bool v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(char v) { SPROUT_CONSTEXPR inline std::size_t hash_value(char v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v) { SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v) { SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v) { SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(short v) { SPROUT_CONSTEXPR inline std::size_t hash_value(short v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v) { SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(int v) { SPROUT_CONSTEXPR inline std::size_t hash_value(int v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v) { SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(long v) { SPROUT_CONSTEXPR inline std::size_t hash_value(long v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v) { SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v) {
return static_cast<std::size_t>(v); return static_cast<std::size_t>(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(long long v) { SPROUT_CONSTEXPR inline std::size_t hash_value(long long v) {
return sprout::hash_detail::hash_value_signed(v); return sprout::hash_detail::hash_value_signed(v);
} }
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v) { SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v) {
return sprout::hash_detail::hash_value_unsigned(v); return sprout::hash_detail::hash_value_unsigned(v);
} }
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_value(T* v) { SPROUT_CONSTEXPR std::size_t hash_value(T* v) {
return sprout::hash_detail::hash_value_pointer(v); return sprout::hash_detail::hash_value_pointer(v);
} }
template<typename T, std::size_t N > template<typename T, std::size_t N >
SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]) { SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]) {
return sprout::hash_range(&v[0], &v[0] + N); return sprout::hash_range(&v[0], &v[0] + N);
} }
// //
// hash_combine // hash_combine
// //
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v) { SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v) {
return seed ^ (sprout::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2)); return seed ^ (sprout::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
} }
// //
// hash_range // hash_range
// //
template<typename Iterator> template<typename Iterator>
SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last) { SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last) {
return sprout::hash_range(0, first, last); return sprout::hash_range(0, first, last);
} }
template<typename Iterator> template<typename Iterator>
SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last) { SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last) {
return first != last return first != last
? sprout::hash_range(sprout::hash_combine(seed, *first), sprout::next(first), last) ? sprout::hash_range(sprout::hash_combine(seed, *first), sprout::next(first), last)
: seed : seed
; ;
} }
#define SPROUT_HASH_SPECIALIZE(type) \ #define SPROUT_HASH_SPECIALIZE(type) \
template<> \ template<> \
struct hash<type> { \ struct hash<type> { \
public: \ public: \
typedef type argument_type; \ typedef type argument_type; \
typedef std::size_t result_type; \ typedef std::size_t result_type; \
public: \ public: \
SPROUT_CONSTEXPR std::size_t operator()(type v) const { \ SPROUT_CONSTEXPR std::size_t operator()(type v) const { \
return sprout::hash_value(v); \ return sprout::hash_value(v); \
} \ } \
} }
#define SPROUT_HASH_SPECIALIZE_REF(type) \ #define SPROUT_HASH_SPECIALIZE_REF(type) \
template<> \ template<> \
struct hash<type> { \ struct hash<type> { \
public: \ public: \
typedef type argument_type; \ typedef type argument_type; \
typedef std::size_t result_type; \ typedef std::size_t result_type; \
public: \ public: \
SPROUT_CONSTEXPR std::size_t operator()(type const& v) const { \ SPROUT_CONSTEXPR std::size_t operator()(type const& v) const { \
return sprout::hash_value(v); \ return sprout::hash_value(v); \
} \ } \
} }
// //
// hash // hash
// //
SPROUT_HASH_SPECIALIZE(bool); SPROUT_HASH_SPECIALIZE(bool);
SPROUT_HASH_SPECIALIZE(char); SPROUT_HASH_SPECIALIZE(char);
SPROUT_HASH_SPECIALIZE(wchar_t); SPROUT_HASH_SPECIALIZE(wchar_t);
SPROUT_HASH_SPECIALIZE(signed char); SPROUT_HASH_SPECIALIZE(signed char);
SPROUT_HASH_SPECIALIZE(unsigned char); SPROUT_HASH_SPECIALIZE(unsigned char);
SPROUT_HASH_SPECIALIZE(short); SPROUT_HASH_SPECIALIZE(short);
SPROUT_HASH_SPECIALIZE(unsigned short); SPROUT_HASH_SPECIALIZE(unsigned short);
SPROUT_HASH_SPECIALIZE(int); SPROUT_HASH_SPECIALIZE(int);
SPROUT_HASH_SPECIALIZE(unsigned int); SPROUT_HASH_SPECIALIZE(unsigned int);
SPROUT_HASH_SPECIALIZE(long); SPROUT_HASH_SPECIALIZE(long);
SPROUT_HASH_SPECIALIZE(unsigned long); SPROUT_HASH_SPECIALIZE(unsigned long);
SPROUT_HASH_SPECIALIZE(long long); SPROUT_HASH_SPECIALIZE(long long);
SPROUT_HASH_SPECIALIZE(unsigned long long); SPROUT_HASH_SPECIALIZE(unsigned long long);
#undef SPROUT_HASH_SPECIALIZE #undef SPROUT_HASH_SPECIALIZE
#undef SPROUT_HASH_SPECIALIZE_REF #undef SPROUT_HASH_SPECIALIZE_REF
template <class T> template <class T>
struct hash<T*> { struct hash<T*> {
public: public:
typedef T* argument_type; typedef T* argument_type;
typedef std::size_t result_type; typedef std::size_t result_type;
public: \ public: \
SPROUT_CONSTEXPR std::size_t operator()(T* v) const { SPROUT_CONSTEXPR std::size_t operator()(T* v) const {
return sprout::hash_value(v); return sprout::hash_value(v);
} }
}; };
} //namespace sprout } //namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP #endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP

View file

@ -1,30 +1,30 @@
#ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP #ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP
#define SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP #define SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP
#include <cstddef> #include <cstddef>
#include <sprout/config.hpp> #include <sprout/config.hpp>
namespace sprout { namespace sprout {
// //
// hash // hash
// //
template<typename T> template<typename T>
struct hash; struct hash;
// //
// hash_combine // hash_combine
// //
template<typename T> template<typename T>
SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v); SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v);
// //
// hash_range // hash_range
// //
template<typename Iterator> template<typename Iterator>
SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last); SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last);
template<typename Iterator> template<typename Iterator>
SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last); SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last);
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP #endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP

View file

@ -1,17 +1,17 @@
#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP
#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP #define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP
#include <cstddef> #include <cstddef>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/functional/hash/hash.hpp> #include <sprout/functional/hash/hash.hpp>
#include <sscrisk/cel/array.hpp> #include <sscrisk/cel/array.hpp>
namespace sprout { namespace sprout {
template<typename T, std::size_t N> template<typename T, std::size_t N>
SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::array<T, N> const& v) { SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::array<T, N> const& v) {
return sprout::hash_range(v.begin(), v.end()); return sprout::hash_range(v.begin(), v.end());
} }
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP #endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP

View file

@ -1,16 +1,16 @@
#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP
#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP #define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP
#include <cstddef> #include <cstddef>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/functional/hash/hash.hpp> #include <sprout/functional/hash/hash.hpp>
#include <sscrisk/cel/utility.hpp> #include <sscrisk/cel/utility.hpp>
namespace sprout { namespace sprout {
template<typename T1, typename T2> template<typename T1, typename T2>
SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::pair<T1, T2> const& v) { SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::pair<T1, T2> const& v) {
return sprout::hash_combine(sprout::hash_combine(0, v.first), v.second); return sprout::hash_combine(sprout::hash_combine(0, v.first), v.second);
} }
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP #endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP

View file

@ -1,17 +1,17 @@
#ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP #ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP
#define SPROUT_FUNCTIONAL_HASH_STRING_HPP #define SPROUT_FUNCTIONAL_HASH_STRING_HPP
#include <cstddef> #include <cstddef>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/functional/hash/hash.hpp> #include <sprout/functional/hash/hash.hpp>
#include <sprout/string.hpp> #include <sprout/string.hpp>
namespace sprout { namespace sprout {
template<typename T, std::size_t N, typename Traits = sprout::char_traits<T> > template<typename T, std::size_t N, typename Traits = sprout::char_traits<T> >
SPROUT_CONSTEXPR std::size_t hash_value(sprout::basic_string<T, N, Traits> const& v) { SPROUT_CONSTEXPR std::size_t hash_value(sprout::basic_string<T, N, Traits> const& v) {
return sprout::hash_range(v.begin(), v.end()); return sprout::hash_range(v.begin(), v.end());
} }
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP #endif // #ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP

View file

@ -1,17 +1,17 @@
#ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP #ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP
#define SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP #define SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP
#include <cstddef> #include <cstddef>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/functional/hash/hash.hpp> #include <sprout/functional/hash/hash.hpp>
#include <sprout/sub_array.hpp> #include <sprout/sub_array.hpp>
namespace sprout { namespace sprout {
template<typename Container> template<typename Container>
SPROUT_CONSTEXPR std::size_t hash_value(sprout::sub_array<Container> const& v) { SPROUT_CONSTEXPR std::size_t hash_value(sprout::sub_array<Container> const& v) {
return sprout::hash_range(v.begin(), v.end()); return sprout::hash_range(v.begin(), v.end());
} }
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP #endif // #ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP

View file

@ -1,8 +1,8 @@
#ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP #ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP
#define SPROUT_FUNCTIONAL_HASH_FWD_HPP #define SPROUT_FUNCTIONAL_HASH_FWD_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/functional/hash/hash_fwd.hpp> #include <sprout/functional/hash/hash_fwd.hpp>
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP #endif // #ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP

View file

@ -1,14 +1,14 @@
#ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP #ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP
#define SPROUT_PREPROCESSOR_STRINGIZE_HPP #define SPROUT_PREPROCESSOR_STRINGIZE_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#define SPROUT_PP_STRINGIZE_I(text) #text #define SPROUT_PP_STRINGIZE_I(text) #text
// //
// SPROUT_PP_STRINGIZE // SPROUT_PP_STRINGIZE
// //
#define SPROUT_PP_STRINGIZE(text) SPROUT_PP_STRINGIZE_I(text) #define SPROUT_PP_STRINGIZE(text) SPROUT_PP_STRINGIZE_I(text)
#endif // #ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP #endif // #ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP

View file

@ -1,13 +1,13 @@
#ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP #ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP
#define SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP #define SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/preprocessor/stringize.hpp> #include <sprout/preprocessor/stringize.hpp>
// //
// SPROUT_PP_UNIQUE_STRING // SPROUT_PP_UNIQUE_STRING
// //
#define SPROUT_PP_UNIQUE_STRING __DATE__ " " __TIME__ " : " __FILE__ "(" SPROUT_PP_STRINGIZE(__LINE__) ")" #define SPROUT_PP_UNIQUE_STRING __DATE__ " " __TIME__ " : " __FILE__ "(" SPROUT_PP_STRINGIZE(__LINE__) ")"
#endif // #ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP #endif // #ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP

View file

@ -1,17 +1,17 @@
#ifndef SPROUT_RANDOM_HPP #ifndef SPROUT_RANDOM_HPP
#define SPROUT_RANDOM_HPP #define SPROUT_RANDOM_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/random/linear_congruential.hpp> #include <sprout/random/linear_congruential.hpp>
#include <sprout/random/mersenne_twister.hpp> #include <sprout/random/mersenne_twister.hpp>
#include <sprout/random/uniform_smallint.hpp> #include <sprout/random/uniform_smallint.hpp>
#include <sprout/random/uniform_int_distribution.hpp> #include <sprout/random/uniform_int_distribution.hpp>
#include <sprout/random/uniform_01.hpp> #include <sprout/random/uniform_01.hpp>
#include <sprout/random/uniform_real_distribution.hpp> #include <sprout/random/uniform_real_distribution.hpp>
#include <sprout/random/bernoulli_distribution.hpp> #include <sprout/random/bernoulli_distribution.hpp>
#include <sprout/random/binomial_distribution.hpp> #include <sprout/random/binomial_distribution.hpp>
#include <sprout/random/variate_generator.hpp> #include <sprout/random/variate_generator.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
#include <sprout/random/random_iterator.hpp> #include <sprout/random/random_iterator.hpp>
#endif // #ifndef SPROUT_RANDOM_HPP #endif // #ifndef SPROUT_RANDOM_HPP

View file

@ -1,142 +1,142 @@
#ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP #ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP
#define SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP #define SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP
#include <iosfwd> #include <iosfwd>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
// //
// bernoulli_distribution // bernoulli_distribution
// //
template<typename RealType = double> template<typename RealType = double>
class bernoulli_distribution { class bernoulli_distribution {
public: public:
typedef int input_type; typedef int input_type;
typedef bool result_type; typedef bool result_type;
private: private:
static SPROUT_CONSTEXPR RealType arg_check(RealType p_arg) { static SPROUT_CONSTEXPR RealType arg_check(RealType p_arg) {
return p_arg >= 0 && p_arg <= 1 return p_arg >= 0 && p_arg <= 1
? p_arg ? p_arg
: throw "assert(p_arg >= 0 && p_arg <= 1)" : throw "assert(p_arg >= 0 && p_arg <= 1)"
; ;
} }
public: public:
// //
// param_type // param_type
// //
class param_type { class param_type {
public: public:
typedef bernoulli_distribution distribution_type; typedef bernoulli_distribution distribution_type;
private: private:
RealType p_; RealType p_;
public: public:
SPROUT_CONSTEXPR param_type() SPROUT_CONSTEXPR param_type()
: p_(RealType(0.5)) : p_(RealType(0.5))
{} {}
SPROUT_CONSTEXPR explicit param_type(RealType p_arg = RealType(0.5)) SPROUT_CONSTEXPR explicit param_type(RealType p_arg = RealType(0.5))
: p_(arg_check(p_arg)) : p_(arg_check(p_arg))
{} {}
SPROUT_CONSTEXPR RealType p() const { SPROUT_CONSTEXPR RealType p() const {
return p_; return p_;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator>>( friend std::basic_ostream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
param_type const& rhs param_type const& rhs
) )
{ {
return lhs >> rhs.p_; return lhs >> rhs.p_;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
param_type const& rhs param_type const& rhs
) )
{ {
return lhs << rhs.p_; return lhs << rhs.p_;
} }
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
return lhs.p_ == rhs.p_; return lhs.p_ == rhs.p_;
} }
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
}; };
private: private:
RealType p_; RealType p_;
private: private:
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> generate( SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> generate(
sprout::random::random_result<Engine> const& rnd sprout::random::random_result<Engine> const& rnd
) const ) const
{ {
return sprout::random::random_result<Engine, bernoulli_distribution>( return sprout::random::random_result<Engine, bernoulli_distribution>(
RealType(rnd.result() - rnd.engine().min()) <= p_ * RealType(rnd.engine().max() - rnd.engine().min()), RealType(rnd.result() - rnd.engine().min()) <= p_ * RealType(rnd.engine().max() - rnd.engine().min()),
rnd.engine(), rnd.engine(),
*this *this
); );
} }
public: public:
SPROUT_CONSTEXPR bernoulli_distribution() SPROUT_CONSTEXPR bernoulli_distribution()
: p_(RealType(0.5)) : p_(RealType(0.5))
{} {}
SPROUT_CONSTEXPR explicit bernoulli_distribution(RealType p_arg = RealType(0.5)) SPROUT_CONSTEXPR explicit bernoulli_distribution(RealType p_arg = RealType(0.5))
: p_(arg_check(p_arg)) : p_(arg_check(p_arg))
{} {}
SPROUT_CONSTEXPR RealType p() const { SPROUT_CONSTEXPR RealType p() const {
return p_; return p_;
} }
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return false; return false;
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return true; return true;
} }
SPROUT_CONSTEXPR param_type param() const { SPROUT_CONSTEXPR param_type param() const {
return param_type(p_); return param_type(p_);
} }
void param(param_type const& parm) { void param(param_type const& parm) {
p_ = parm.p(); p_ = parm.p();
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> operator()(Engine const& eng) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> operator()(Engine const& eng) const {
return p_ == RealType(0) return p_ == RealType(0)
? sprout::random::random_result<Engine, bernoulli_distribution>(false, eng, *this) ? sprout::random::random_result<Engine, bernoulli_distribution>(false, eng, *this)
: generate(eng()) : generate(eng())
; ;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator>>( friend std::basic_ostream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
bernoulli_distribution const& rhs bernoulli_distribution const& rhs
) )
{ {
param_type parm; param_type parm;
return lhs >> parm; return lhs >> parm;
param(parm); param(parm);
return lhs; return lhs;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
bernoulli_distribution const& rhs bernoulli_distribution const& rhs
) )
{ {
return lhs << param(); return lhs << param();
} }
SPROUT_CONSTEXPR friend bool operator==(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { SPROUT_CONSTEXPR friend bool operator==(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) {
return lhs.param() == rhs.param(); return lhs.param() == rhs.param();
} }
SPROUT_CONSTEXPR friend bool operator!=(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) { SPROUT_CONSTEXPR friend bool operator!=(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
}; };
} // namespace random } // namespace random
using sprout::random::bernoulli_distribution; using sprout::random::bernoulli_distribution;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP #endif // #ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP

View file

@ -1,425 +1,425 @@
#ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP #ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP
#define SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP #define SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP
#include <iosfwd> #include <iosfwd>
#include <istream> #include <istream>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/array.hpp> #include <sprout/array.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
#include <sprout/random/uniform_01.hpp> #include <sprout/random/uniform_01.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
namespace detail { namespace detail {
template<typename RealType> template<typename RealType>
struct binomial_table { struct binomial_table {
public: public:
SPROUT_STATIC_CONSTEXPR sprout::array<RealType, 10> table = sprout::array<RealType, 10>{{ SPROUT_STATIC_CONSTEXPR sprout::array<RealType, 10> table = sprout::array<RealType, 10>{{
0.08106146679532726, 0.08106146679532726,
0.04134069595540929, 0.04134069595540929,
0.02767792568499834, 0.02767792568499834,
0.02079067210376509, 0.02079067210376509,
0.01664469118982119, 0.01664469118982119,
0.01387612882307075, 0.01387612882307075,
0.01189670994589177, 0.01189670994589177,
0.01041126526197209, 0.01041126526197209,
0.009255462182712733, 0.009255462182712733,
0.008330563433362871 0.008330563433362871
}}; }};
}; };
template<class RealType> template<class RealType>
SPROUT_CONSTEXPR sprout::array<RealType, 10> sprout::random::detail::binomial_table<RealType>::table; SPROUT_CONSTEXPR sprout::array<RealType, 10> sprout::random::detail::binomial_table<RealType>::table;
} // namespace detail } // namespace detail
// //
// binomial_distribution // binomial_distribution
// //
template<typename IntType = int, typename RealType = double> template<typename IntType = int, typename RealType = double>
class binomial_distribution { class binomial_distribution {
public: public:
typedef RealType input_type; typedef RealType input_type;
typedef IntType result_type; typedef IntType result_type;
private: private:
struct btrd_type { struct btrd_type {
public: public:
RealType r; RealType r;
RealType nr; RealType nr;
RealType npq; RealType npq;
RealType b; RealType b;
RealType a; RealType a;
RealType c; RealType c;
RealType alpha; RealType alpha;
RealType v_r; RealType v_r;
RealType u_rv_r; RealType u_rv_r;
}; };
private: private:
static SPROUT_CONSTEXPR IntType arg_check(IntType t_arg, RealType p_arg) { 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) return t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1)
? t_arg ? t_arg
: throw "assert(t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1))" : throw "assert(t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1))"
; ;
} }
public: public:
// //
// param_type // param_type
// //
class param_type { class param_type {
public: public:
typedef binomial_distribution distribution_type; typedef binomial_distribution distribution_type;
private: private:
IntType t_; IntType t_;
RealType p_; RealType p_;
public: public:
SPROUT_CONSTEXPR param_type() SPROUT_CONSTEXPR param_type()
: t_(1) : t_(1)
, p_(0.5) , p_(0.5)
{} {}
SPROUT_CONSTEXPR explicit param_type(IntType t_arg, RealType p_arg = RealType(0.5)) SPROUT_CONSTEXPR explicit param_type(IntType t_arg, RealType p_arg = RealType(0.5))
: t_(arg_check(t_arg, p_arg)) : t_(arg_check(t_arg, p_arg))
, p_(p_arg) , p_(p_arg)
{} {}
SPROUT_CONSTEXPR IntType t() const { SPROUT_CONSTEXPR IntType t() const {
return t_; return t_;
} }
SPROUT_CONSTEXPR RealType p() const { SPROUT_CONSTEXPR RealType p() const {
return p_; return p_;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator>>( friend std::basic_ostream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
param_type const& rhs param_type const& rhs
) )
{ {
return lhs >> rhs.t_ >> std::ws >> rhs.p_; return lhs >> rhs.t_ >> std::ws >> rhs.p_;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
param_type const& rhs param_type const& rhs
) )
{ {
return lhs << rhs.t_ << " " << rhs.p_; return lhs << rhs.t_ << " " << rhs.p_;
} }
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
return lhs.t_ == rhs.t_ && lhs.p_ == rhs.p_; return lhs.t_ == rhs.t_ && lhs.p_ == rhs.p_;
} }
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
}; };
private: private:
static SPROUT_CONSTEXPR IntType init_t(IntType t) { static SPROUT_CONSTEXPR IntType init_t(IntType t) {
return t; return t;
} }
static SPROUT_CONSTEXPR RealType init_p(RealType p) { static SPROUT_CONSTEXPR RealType init_p(RealType p) {
return RealType(0.5) < p ? 1 - p : p; return RealType(0.5) < p ? 1 - p : p;
} }
static SPROUT_CONSTEXPR IntType init_m(IntType t, RealType p) { static SPROUT_CONSTEXPR IntType init_m(IntType t, RealType p) {
return static_cast<IntType>((init_t(t) + 1) * init_p(p)); return static_cast<IntType>((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) { 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 { return btrd_type {
r, r,
nr, nr,
npq, npq,
b, b,
a, a,
c, c,
alpha, alpha,
v_r, v_r,
RealType(0.86) * 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) { 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); 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) { 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); 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) { static SPROUT_CONSTEXPR btrd_type init_btrd_3(IntType t, RealType p, RealType r, RealType nr, RealType npq) {
using std::sqrt; using std::sqrt;
return init_btrd_4(t, p, r, nr, npq, sqrt(npq)); 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) { 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)); 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) { static SPROUT_CONSTEXPR btrd_type init_btrd_1(IntType t, RealType p) {
return init_btrd_2(t, p, p / (1 - p)); return init_btrd_2(t, p, p / (1 - p));
} }
static SPROUT_CONSTEXPR btrd_type init_btrd(IntType t, RealType p) { static SPROUT_CONSTEXPR btrd_type init_btrd(IntType t, RealType p) {
return init_btrd_1(init_t(t), init_p(p)); return init_btrd_1(init_t(t), init_p(p));
} }
static SPROUT_CONSTEXPR RealType init_q_n(IntType t, RealType p) { static SPROUT_CONSTEXPR RealType init_q_n(IntType t, RealType p) {
using std::pow; using std::pow;
return pow(1 - init_p(p), static_cast<RealType>(init_t(t))); return pow(1 - init_p(p), static_cast<RealType>(init_t(t)));
} }
static SPROUT_CONSTEXPR bool init_use_inversion(IntType t, RealType p) { static SPROUT_CONSTEXPR bool init_use_inversion(IntType t, RealType p) {
return init_m(t, p) < 11; return init_m(t, p) < 11;
} }
static SPROUT_CONSTEXPR RealType fc_1(RealType ikp1) { static SPROUT_CONSTEXPR RealType fc_1(RealType ikp1) {
return (RealType(1) / 12 - (RealType(1) / 360 - (RealType(1) / 1260) * (ikp1 * ikp1)) * (ikp1 * ikp1)) * ikp1; return (RealType(1) / 12 - (RealType(1) / 360 - (RealType(1) / 1260) * (ikp1 * ikp1)) * (ikp1 * ikp1)) * ikp1;
} }
static SPROUT_CONSTEXPR RealType fc(IntType k) { static SPROUT_CONSTEXPR RealType fc(IntType k) {
return k < 10 return k < 10
? sprout::random::detail::binomial_table<RealType>::table[k] ? sprout::random::detail::binomial_table<RealType>::table[k]
: fc_1(RealType(1) / (k + 1)) : fc_1(RealType(1) / (k + 1))
; ;
} }
private: private:
IntType t_; IntType t_;
RealType p_; RealType p_;
IntType m_; IntType m_;
btrd_type btrd_; btrd_type btrd_;
RealType q_n_; RealType q_n_;
private: private:
SPROUT_CONSTEXPR bool use_inversion() const { SPROUT_CONSTEXPR bool use_inversion() const {
return m_ < 11; return m_ < 11;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert_4(Engine const& eng, RealType u, RealType q, RealType s, RealType a, RealType r, IntType x = 0) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert_4(Engine const& eng, RealType u, RealType q, RealType s, RealType a, RealType r, IntType x = 0) const {
return u > r return u > r
? invert_4(eng, u - r, q, s, a, ((a / (x + 1)) - s) * r, x + 1) ? invert_4(eng, u - r, q, s, a, ((a / (x + 1)) - s) * r, x + 1)
: sprout::random::random_result<Engine, binomial_distribution>(x, eng, *this) : sprout::random::random_result<Engine, binomial_distribution>(x, eng, *this)
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert_3(IntType t, Engine const& eng, RealType u, RealType q, RealType s) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> 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_); return invert_4(eng, u, q, s, (t + 1) * s, q_n_);
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert_2(IntType t, RealType p, Engine const& eng, RealType u, RealType q) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert_2(IntType t, RealType p, Engine const& eng, RealType u, RealType q) const {
return invert_3(t, eng, u, q, p / q); return invert_3(t, eng, u, q, p / q);
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert_1(IntType t, RealType p, Engine const& eng, RealType u) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert_1(IntType t, RealType p, Engine const& eng, RealType u) const {
return invert_2(t, p, eng, u, 1 - p); return invert_2(t, p, eng, u, 1 - p);
} }
template<typename Engine, typename Random> template<typename Engine, typename Random>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert_0(IntType t, RealType p, Random const& rnd) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert_0(IntType t, RealType p, Random const& rnd) const {
return invert_1(t, p, rnd.engine(), rnd.result()); return invert_1(t, p, rnd.engine(), rnd.result());
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert(IntType t, RealType p, Engine const& eng) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert(IntType t, RealType p, Engine const& eng) const {
return invert_0<Engine>(t, p, sprout::random::uniform_01<RealType>()(eng)); return invert_0<Engine>(t, p, sprout::random::uniform_01<RealType>()(eng));
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert2_0(IntType t, sprout::random::random_result<Engine, binomial_distribution> const& rnd) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert2_0(IntType t, sprout::random::random_result<Engine, binomial_distribution> const& rnd) const {
return sprout::random::random_result<Engine, binomial_distribution>(t - rnd.result(), rnd.engine(), rnd.distribution()); return sprout::random::random_result<Engine, binomial_distribution>(t - rnd.result(), rnd.engine(), rnd.distribution());
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert2(IntType t, RealType p, Engine const& eng) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> invert2(IntType t, RealType p, Engine const& eng) const {
return invert2_0<Engine>(t, invert(t, p, eng)); return invert2_0<Engine>(t, invert(t, p, eng));
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_10(Engine const& eng, RealType v, IntType k, IntType nm, RealType h, IntType nk) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_10(Engine const& eng, RealType v, IntType k, IntType nm, RealType h, IntType nk) const {
using std::log; using std::log;
return v <= h + (t_ + 1) * log(static_cast<RealType>(nm) / nk) + (k + RealType(0.5)) * log(nk * btrd_.r / (k + 1))- fc(k)- fc(t_ - k) return v <= h + (t_ + 1) * log(static_cast<RealType>(nm) / nk) + (k + RealType(0.5)) * log(nk * btrd_.r / (k + 1))- fc(k)- fc(t_ - k)
? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this) ? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this)
: generate(eng) : generate(eng)
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_9(Engine const& eng, RealType v, IntType k, IntType nm) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_9(Engine const& eng, RealType v, IntType k, IntType nm) const {
using std::log; 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); 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<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_8(Engine const& eng, RealType v, IntType k, RealType rho, RealType t) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_8(Engine const& eng, RealType v, IntType k, RealType rho, RealType t) const {
return v < t - rho ? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this) return v < t - rho ? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this)
: v > t + rho ? generate(eng) : v > t + rho ? generate(eng)
: generate_9(eng, v, k, t_ - m_ + 1) : generate_9(eng, v, k, t_ - m_ + 1)
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_7_3(Engine const& eng, RealType v, IntType k, RealType f) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_7_3(Engine const& eng, RealType v, IntType k, RealType f) const {
return v <= f return v <= f
? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this) ? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this)
: generate(eng) : generate(eng)
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_7_2(Engine const& eng, RealType v, IntType k, RealType f, IntType i) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_7_2(Engine const& eng, RealType v, IntType k, RealType f, IntType i) const {
return i != k return i != k
? generate_7_2(eng, v * (btrd_.nr / (i + 1) - btrd_.r), k, f, i + 1) ? generate_7_2(eng, v * (btrd_.nr / (i + 1) - btrd_.r), k, f, i + 1)
: generate_7_3(eng, v, k, f) : generate_7_3(eng, v, k, f)
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_7_1(Engine const& eng, RealType v, IntType k, RealType f, IntType i) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_7_1(Engine const& eng, RealType v, IntType k, RealType f, IntType i) const {
return i != k return i != k
? generate_7_1(eng, v, k, f * (btrd_.nr / (i + 1) - btrd_.r), i + 1) ? generate_7_1(eng, v, k, f * (btrd_.nr / (i + 1) - btrd_.r), i + 1)
: generate_7_3(eng, v, k, f) : generate_7_3(eng, v, k, f)
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_7(Engine const& eng, RealType v, IntType k, RealType f = RealType(1)) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> 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) 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) : m_ > k ? generate_7_2(eng, v * (btrd_.nr / (k + 1) - btrd_.r), k, f, k + 1)
: generate_7_3(eng, v, k, f) : generate_7_3(eng, v, k, f)
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_6(Engine const& eng, RealType v, IntType k, RealType km) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_6(Engine const& eng, RealType v, IntType k, RealType km) const {
using std::log; using std::log;
return km <= 15 return km <= 15
? generate_7(eng, v, k) ? 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)) : 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<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_5(Engine const& eng, RealType v, RealType u, RealType us, IntType k) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_5(Engine const& eng, RealType v, RealType u, RealType us, IntType k) const {
using std::abs; using std::abs;
return k < 0 || k > t_ return k < 0 || k > t_
? generate(eng) ? generate(eng)
: generate_6(eng, v * btrd_.alpha / (btrd_.a / (us * us) + btrd_.b), k, abs(k - m_)) : generate_6(eng, v * btrd_.alpha / (btrd_.a / (us * us) + btrd_.b), k, abs(k - m_))
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_4(Engine const& eng, RealType v, RealType u, RealType us) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_4(Engine const& eng, RealType v, RealType u, RealType us) const {
using std::floor; using std::floor;
return generate_5(eng, v, u, us, static_cast<IntType>(floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c))); return generate_5(eng, v, u, us, static_cast<IntType>(floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c)));
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_3(Engine const& eng, RealType v, RealType u) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_3(Engine const& eng, RealType v, RealType u) const {
using std::abs; using std::abs;
return generate_4(eng, v, u, 0.5 - abs(u)); return generate_4(eng, v, u, 0.5 - abs(u));
} }
template<typename Engine, typename Random> template<typename Engine, typename Random>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_2(Random const& rnd, RealType v) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_2(Random const& rnd, RealType v) const {
return v >= btrd_.v_r return v >= btrd_.v_r
? generate_3( ? generate_3(
rnd.engine(), rnd.engine(),
v, v,
rnd.result() - RealType(0.5) rnd.result() - RealType(0.5)
) )
: generate_3( : generate_3(
rnd.engine(), rnd.engine(),
rnd.result() * btrd_.v_r, 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)) ((v / btrd_.v_r - RealType(0.93)) < 0 ? RealType(-0.5) : RealType(0.5)) - (v / btrd_.v_r - RealType(0.93))
) )
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_1_1(Engine const& eng, RealType u) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_1_1(Engine const& eng, RealType u) const {
using std::floor; using std::floor;
using std::abs; using std::abs;
return sprout::random::random_result<Engine, binomial_distribution>( return sprout::random::random_result<Engine, binomial_distribution>(
static_cast<IntType>(floor((2 * btrd_.a / (RealType(0.5) - abs(u)) + btrd_.b) * u + btrd_.c)), static_cast<IntType>(floor((2 * btrd_.a / (RealType(0.5) - abs(u)) + btrd_.b) * u + btrd_.c)),
eng, eng,
*this *this
); );
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_1(Engine const& eng, RealType v) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_1(Engine const& eng, RealType v) const {
return v <= btrd_.u_rv_r return v <= btrd_.u_rv_r
? generate_1_1(eng, v / btrd_.v_r - RealType(0.43)) ? generate_1_1(eng, v / btrd_.v_r - RealType(0.43))
: generate_2<Engine>(sprout::random::uniform_01<RealType>()(eng), v) : generate_2<Engine>(sprout::random::uniform_01<RealType>()(eng), v)
; ;
} }
template<typename Engine, typename Random> template<typename Engine, typename Random>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_0(Random const& rnd) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_0(Random const& rnd) const {
return generate_1(rnd.engine(), rnd.result()); return generate_1(rnd.engine(), rnd.result());
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate(Engine const& eng) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate(Engine const& eng) const {
return generate_0<Engine>(sprout::random::uniform_01<RealType>()(eng)); return generate_0<Engine>(sprout::random::uniform_01<RealType>()(eng));
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate2_0(IntType t, sprout::random::random_result<Engine, binomial_distribution> const& rnd) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate2_0(IntType t, sprout::random::random_result<Engine, binomial_distribution> const& rnd) const {
return sprout::random::random_result<Engine, binomial_distribution>(t - rnd.result(), rnd.engine(), rnd.distribution()); return sprout::random::random_result<Engine, binomial_distribution>(t - rnd.result(), rnd.engine(), rnd.distribution());
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate2(IntType t, Engine const& eng) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate2(IntType t, Engine const& eng) const {
return generate2_0<Engine>(t, generate(eng)); return generate2_0<Engine>(t, generate(eng));
} }
void init() { void init() {
m_ = init_m(t_, p_); m_ = init_m(t_, p_);
if (use_inversion()) { if (use_inversion()) {
q_n_ = init_q_n(t_, p_); q_n_ = init_q_n(t_, p_);
} else { } else {
btrd_ = init_btrd(t_, p_); btrd_ = init_btrd(t_, p_);
} }
} }
public: public:
SPROUT_CONSTEXPR binomial_distribution() SPROUT_CONSTEXPR binomial_distribution()
: t_(1) : t_(1)
, p_(RealType(0.5)) , p_(RealType(0.5))
, m_(init_m(1, 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()) , 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()) , 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)) SPROUT_CONSTEXPR explicit binomial_distribution(IntType t_arg, RealType p_arg = RealType(0.5))
: t_(arg_check(t_arg, p_arg)) : t_(arg_check(t_arg, p_arg))
, p_(p_arg) , p_(p_arg)
, m_(init_m(t_arg, 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()) , 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()) , 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) SPROUT_CONSTEXPR explicit binomial_distribution(param_type const& parm)
: t_(parm.t()) : t_(parm.t())
, p_(parm.p()) , p_(parm.p())
, m_(init_m(parm.t(), 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()) , 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()) , q_n_(init_use_inversion(parm.t(), parm.p()) ? init_q_n(parm.t(), parm.p()) : RealType())
{} {}
SPROUT_CONSTEXPR result_type t() const { SPROUT_CONSTEXPR result_type t() const {
return t_; return t_;
} }
SPROUT_CONSTEXPR result_type p() const { SPROUT_CONSTEXPR result_type p() const {
return p_; return p_;
} }
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return 0; return 0;
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return t_; return t_;
} }
SPROUT_CONSTEXPR param_type param() const { SPROUT_CONSTEXPR param_type param() const {
return param_type(t_, p_); return param_type(t_, p_);
} }
void param(param_type const& parm) { void param(param_type const& parm) {
t_ = parm.a(); t_ = parm.a();
p_ = parm.b(); p_ = parm.b();
init(); init();
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> operator()(Engine const& eng) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> operator()(Engine const& eng) const {
return use_inversion() ? RealType(0.5) < p_ return use_inversion() ? RealType(0.5) < p_
? invert2(t_, 1 - p_, eng) ? invert2(t_, 1 - p_, eng)
: invert(t_, p_, eng) : invert(t_, p_, eng)
: RealType(0.5) < p_ ? generate2(t_, eng) : RealType(0.5) < p_ ? generate2(t_, eng)
: generate(eng) : generate(eng)
; ;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator>>( friend std::basic_ostream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
binomial_distribution const& rhs binomial_distribution const& rhs
) )
{ {
param_type parm; param_type parm;
return lhs >> parm; return lhs >> parm;
param(parm); param(parm);
return lhs; return lhs;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
binomial_distribution const& rhs binomial_distribution const& rhs
) )
{ {
return lhs << param(); return lhs << param();
} }
SPROUT_CONSTEXPR friend bool operator==(binomial_distribution const& lhs, binomial_distribution const& rhs) { SPROUT_CONSTEXPR friend bool operator==(binomial_distribution const& lhs, binomial_distribution const& rhs) {
return lhs.param() == rhs.param(); return lhs.param() == rhs.param();
} }
SPROUT_CONSTEXPR friend bool operator!=(binomial_distribution const& lhs, binomial_distribution const& rhs) { SPROUT_CONSTEXPR friend bool operator!=(binomial_distribution const& lhs, binomial_distribution const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
}; };
} // namespace random } // namespace random
using sprout::random::binomial_distribution; using sprout::random::binomial_distribution;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP #endif // #ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP

View file

@ -1,132 +1,132 @@
#ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP #ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP
#define SPROUT_RANDOM_DETAIL_CONST_MOD_HPP #define SPROUT_RANDOM_DETAIL_CONST_MOD_HPP
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
namespace detail { namespace detail {
template<typename IntType, IntType m> template<typename IntType, IntType m>
class const_mod { class const_mod {
private: private:
typedef typename std::make_unsigned<IntType>::type unsigned_type; typedef typename std::make_unsigned<IntType>::type unsigned_type;
private: private:
SPROUT_STATIC_CONSTEXPR IntType suppress_warnings = m == 0; SPROUT_STATIC_CONSTEXPR IntType suppress_warnings = m == 0;
SPROUT_STATIC_CONSTEXPR IntType modulus = m + suppress_warnings; SPROUT_STATIC_CONSTEXPR IntType modulus = m + suppress_warnings;
private: private:
static_assert(suppress_warnings == 0, "suppress_warnings == 0"); static_assert(suppress_warnings == 0, "suppress_warnings == 0");
static_assert(modulus == m, "modulus == m"); static_assert(modulus == m, "modulus == m");
private: private:
static SPROUT_CONSTEXPR IntType pow_1(IntType a, std::uintmax_t exponent, IntType result = 1) { static SPROUT_CONSTEXPR IntType pow_1(IntType a, std::uintmax_t exponent, IntType result = 1) {
return exponent != 0 return exponent != 0
? pow_1(mult(a, a), exponent / 2, exponent % 2 == 1 ? mult(result, a) : result) ? pow_1(mult(a, a), exponent / 2, exponent % 2 == 1 ? mult(result, a) : result)
: result : result
; ;
} }
static SPROUT_CONSTEXPR IntType mult_small(IntType a, IntType x) { static SPROUT_CONSTEXPR IntType mult_small(IntType a, IntType x) {
return a * x % (m + suppress_warnings); return a * x % (m + suppress_warnings);
} }
static SPROUT_CONSTEXPR IntType mult_schrage_1(IntType a, IntType value, IntType q, IntType r) { static SPROUT_CONSTEXPR IntType mult_schrage_1(IntType a, IntType value, IntType q, IntType r) {
return r < q return r < q
? sub(a * (value % q), r * (value / q)) ? sub(a * (value % q), r * (value / q))
: throw "assert(r < q)" : throw "assert(r < q)"
; ;
} }
static SPROUT_CONSTEXPR IntType mult_schrage(IntType a, IntType value) { static SPROUT_CONSTEXPR IntType mult_schrage(IntType a, IntType value) {
return mult_schrage_1(a, value, m / a, m % a); return mult_schrage_1(a, value, m / a, m % a);
} }
static SPROUT_CONSTEXPR IntType mult_general(IntType a, IntType b) { static SPROUT_CONSTEXPR IntType mult_general(IntType a, IntType b) {
return std::uintmax_t(modulus) <= std::numeric_limits<std::uintmax_t>::max() / modulus return std::uintmax_t(modulus) <= std::numeric_limits<std::uintmax_t>::max() / modulus
? static_cast<IntType>(std::uintmax_t(a) * b % modulus) ? static_cast<IntType>(std::uintmax_t(a) * b % modulus)
: /*static_cast<IntType>(sprout::random::detail::mulmod(a, b, modulus))*/throw "Sorry, not implemented." : /*static_cast<IntType>(sprout::random::detail::mulmod(a, b, modulus))*/throw "Sorry, not implemented."
; ;
} }
static SPROUT_CONSTEXPR IntType sub(IntType a, IntType b) { static SPROUT_CONSTEXPR IntType sub(IntType a, IntType b) {
return a < b ? m - (b - a) : a - b; return a < b ? m - (b - a) : a - b;
} }
static SPROUT_CONSTEXPR unsigned_type unsigned_m() { static SPROUT_CONSTEXPR unsigned_type unsigned_m() {
return m == 0 ? unsigned_type((std::numeric_limits<IntType>::max)()) + 1 : unsigned_type(m); return m == 0 ? unsigned_type((std::numeric_limits<IntType>::max)()) + 1 : unsigned_type(m);
} }
static SPROUT_CONSTEXPR IntType invert_euclidian_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { 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); 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) { 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); 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) { 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); return invert_euclidian_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n);
} }
static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) { static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) {
return c > 0 return c > 0
? c == 1 ? 1 : invert_euclidian_1(c, 0, 1, c, m) ? c == 1 ? 1 : invert_euclidian_1(c, 0, 1, c, m)
: throw "assert(c > 0)" : throw "assert(c > 0)"
; ;
} }
static SPROUT_CONSTEXPR IntType invert_euclidian0_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) { 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); 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) { 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); 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) { static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
return std::numeric_limits<IntType>::max() % n != n - 1 return std::numeric_limits<IntType>::max() % n != n - 1
? invert_euclidian0_2(c, l1 + (std::numeric_limits<IntType>::max() / n) * l2, l2, n, std::numeric_limits<IntType>::max() - (std::numeric_limits<IntType>::max() / n) * n + 1) ? invert_euclidian0_2(c, l1 + (std::numeric_limits<IntType>::max() / n) * l2, l2, n, std::numeric_limits<IntType>::max() - (std::numeric_limits<IntType>::max() / n) * n + 1)
: throw "assert(std::numeric_limits<IntType>::max() % n != n - 1)" : throw "assert(std::numeric_limits<IntType>::max() % n != n - 1)"
; ;
} }
static SPROUT_CONSTEXPR IntType invert_euclidian0(IntType c) { static SPROUT_CONSTEXPR IntType invert_euclidian0(IntType c) {
return c > 0 return c > 0
? c == 1 ? 1 : invert_euclidian0_1(c, 0, 1, c, m) ? c == 1 ? 1 : invert_euclidian0_1(c, 0, 1, c, m)
: throw "assert(c > 0)" : throw "assert(c > 0)"
; ;
} }
public: public:
static SPROUT_CONSTEXPR IntType apply(IntType x) { static SPROUT_CONSTEXPR IntType apply(IntType x) {
return ((unsigned_m() - 1) & unsigned_m()) == 0 return ((unsigned_m() - 1) & unsigned_m()) == 0
? (unsigned_type(x)) & (unsigned_m() - 1) ? (unsigned_type(x)) & (unsigned_m() - 1)
: x % (m + suppress_warnings) : x % (m + suppress_warnings)
; ;
} }
static SPROUT_CONSTEXPR IntType add(IntType x, IntType c) { 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) return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1)
: c == 0 ? x : c == 0 ? x
: x < m - c ? x + c : x < m - c ? x + c
: x - (m - c) : x - (m - c)
; ;
} }
static SPROUT_CONSTEXPR IntType mult(IntType a, IntType x) { 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) return ((unsigned_m() - 1) & unsigned_m()) == 0 ? unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1)
: a == 0 ? 0 : a == 0 ? 0
: a == 1 ? x : a == 1 ? x
: m <= std::numeric_limits<IntType>::max() / a ? mult_small(a, x) : m <= std::numeric_limits<IntType>::max() / a ? mult_small(a, x)
: std::numeric_limits<IntType>::is_signed && (m % a < m / a) ? mult_schrage(a, x) : std::numeric_limits<IntType>::is_signed && (m % a < m / a) ? mult_schrage(a, x)
: mult_general(a, x) : mult_general(a, x)
; ;
} }
static SPROUT_CONSTEXPR IntType mult_add(IntType a, IntType x, IntType c) { 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) return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1)
: a == 0 ? c : a == 0 ? c
: m <= (std::numeric_limits<IntType>::max() - c) / a ? (a * x + c) % (m + suppress_warnings) : m <= (std::numeric_limits<IntType>::max() - c) / a ? (a * x + c) % (m + suppress_warnings)
: add(mult(a, x), c) : add(mult(a, x), c)
; ;
} }
static SPROUT_CONSTEXPR IntType pow(IntType a, std::uintmax_t exponent) { static SPROUT_CONSTEXPR IntType pow(IntType a, std::uintmax_t exponent) {
return pow_1(a, exponent); return pow_1(a, exponent);
} }
static SPROUT_CONSTEXPR IntType invert(IntType x) { static SPROUT_CONSTEXPR IntType invert(IntType x) {
return x == 0 ? 0 return x == 0 ? 0
: m == 0 ? invert_euclidian0(x) : m == 0 ? invert_euclidian0(x)
: invert_euclidian(x) : invert_euclidian(x)
; ;
} }
private: private:
const_mod() = delete; const_mod() = delete;
}; };
} // namespace detail } // namespace detail
} // namespace random } // namespace random
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP #endif // #ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP

View file

@ -1,73 +1,73 @@
#ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP #ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP
#define SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP #define SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
namespace detail { namespace detail {
template<typename T> template<typename T>
struct ptr_helper { struct ptr_helper {
typedef T value_type; typedef T value_type;
typedef T& reference_type; typedef T& reference_type;
typedef T const& const_reference_type; typedef T const& const_reference_type;
typedef T const& rvalue_type; typedef T const& rvalue_type;
static reference_type ref(T& r) { static reference_type ref(T& r) {
return r; return r;
} }
static SPROUT_CONSTEXPR const_reference_type ref(T const& r) { static SPROUT_CONSTEXPR const_reference_type ref(T const& r) {
return r; return r;
} }
}; };
template<typename T> template<typename T>
struct ptr_helper<T&> { struct ptr_helper<T&> {
typedef T value_type; typedef T value_type;
typedef T& reference_type; typedef T& reference_type;
typedef T const& const_reference_type; typedef T const& const_reference_type;
typedef T& rvalue_type; typedef T& rvalue_type;
static reference_type ref(T& r) { static reference_type ref(T& r) {
return r; return r;
} }
static SPROUT_CONSTEXPR const_reference_type ref(T const& r) { static SPROUT_CONSTEXPR const_reference_type ref(T const& r) {
return r; return r;
} }
}; };
template<typename T> template<typename T>
struct ptr_helper<T const&> { struct ptr_helper<T const&> {
typedef T value_type; typedef T value_type;
typedef T const& reference_type; typedef T const& reference_type;
typedef T const& const_reference_type; typedef T const& const_reference_type;
typedef T const& rvalue_type; typedef T const& rvalue_type;
static SPROUT_CONSTEXPR const_reference_type ref(T const& r) { static SPROUT_CONSTEXPR const_reference_type ref(T const& r) {
return r; return r;
} }
}; };
template<typename T> template<typename T>
struct ptr_helper<T*> { struct ptr_helper<T*> {
typedef T value_type; typedef T value_type;
typedef T& reference_type; typedef T& reference_type;
typedef T const& const_reference_type; typedef T const& const_reference_type;
typedef T* rvalue_type; typedef T* rvalue_type;
static reference_type ref(T* p) { static reference_type ref(T* p) {
return *p; return *p;
} }
static SPROUT_CONSTEXPR const_reference_type ref(T const* p) { static SPROUT_CONSTEXPR const_reference_type ref(T const* p) {
return *p; return *p;
} }
}; };
template<typename T> template<typename T>
struct ptr_helper<T const*> { struct ptr_helper<T const*> {
typedef T value_type; typedef T value_type;
typedef T const& reference_type; typedef T const& reference_type;
typedef T const& const_reference_type; typedef T const& const_reference_type;
typedef T const* rvalue_type; typedef T const* rvalue_type;
static SPROUT_CONSTEXPR const_reference_type ref(T const* p) { static SPROUT_CONSTEXPR const_reference_type ref(T const* p) {
return *p; return *p;
} }
}; };
} // namespace detail } // namespace detail
} // namespace random } // namespace random
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP #endif // #ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP

View file

@ -1,63 +1,63 @@
#ifndef SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP #ifndef SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP
#define SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP #define SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
namespace detail { namespace detail {
template<typename T, bool B = std::numeric_limits<T>::is_signed> template<typename T, bool B = std::numeric_limits<T>::is_signed>
struct subtract {}; struct subtract {};
template<typename T> template<typename T>
struct subtract<T, false> { struct subtract<T, false> {
public: public:
typedef T result_type; typedef T result_type;
public: public:
SPROUT_CONSTEXPR result_type operator()(T x, T y) const { SPROUT_CONSTEXPR result_type operator()(T x, T y) const {
return x - y; return x - y;
} }
}; };
template<typename T> template<typename T>
struct subtract<T, true> { struct subtract<T, true> {
public: public:
typedef typename std::make_unsigned<T>::type result_type; typedef typename std::make_unsigned<T>::type result_type;
public: public:
SPROUT_CONSTEXPR result_type operator()(T x, T y) const { SPROUT_CONSTEXPR result_type operator()(T x, T y) const {
return y >= 0 ? result_type(x) - result_type(y) return y >= 0 ? result_type(x) - result_type(y)
: x >= 0 ? result_type(x) + result_type(-(y + 1)) + 1 : x >= 0 ? result_type(x) + result_type(-(y + 1)) + 1
: result_type(x - y) : result_type(x - y)
; ;
} }
}; };
template<typename T1, typename T2, bool B = std::numeric_limits<T2>::is_signed> template<typename T1, typename T2, bool B = std::numeric_limits<T2>::is_signed>
struct add {}; struct add {};
template<typename T1, typename T2> template<typename T1, typename T2>
struct add<T1, T2, false> { struct add<T1, T2, false> {
public: public:
typedef T2 result_type; typedef T2 result_type;
public: public:
SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const { SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const {
return T2(x) + y; return T2(x) + y;
} }
}; };
template<typename T1, typename T2> template<typename T1, typename T2>
struct add<T1, T2, true> { struct add<T1, T2, true> {
public: public:
typedef T2 result_type; typedef T2 result_type;
public: public:
SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const { SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const {
return y >= 0 ? T2(x) + y return y >= 0 ? T2(x) + y
: x >= T1(-(y + 1)) ? T2(x - T1(-(y + 1)) - 1) : x >= T1(-(y + 1)) ? T2(x - T1(-(y + 1)) - 1)
: T2(x) + y : T2(x) + y
; ;
} }
}; };
} // namespace detail } // namespace detail
} // namespace random } // namespace random
} // namespace sprout } // namespace sprout
#endif // SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP #endif // SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP

View file

@ -1,74 +1,74 @@
#ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP #ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
#define SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP #define SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
#include <sprout/random/detail/generator_bits.hpp> #include <sprout/random/detail/generator_bits.hpp>
#include <sprout/detail/integer.hpp> #include <sprout/detail/integer.hpp>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT_DETAIL #include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT_DETAIL
namespace sprout { namespace sprout {
namespace random { namespace random {
namespace detail { namespace detail {
template<class URNG> template<class URNG>
class uniform_int_float { class uniform_int_float {
public: public:
typedef URNG base_type; typedef URNG base_type;
typedef typename base_type::result_type base_result; typedef typename base_type::result_type base_result;
typedef typename sprout::detail::uint_t< typedef typename sprout::detail::uint_t<
(std::numeric_limits<std::uintmax_t>::digits < std::numeric_limits<base_result>::digits) (std::numeric_limits<std::uintmax_t>::digits < std::numeric_limits<base_result>::digits)
? std::numeric_limits<std::uintmax_t>::digits ? std::numeric_limits<std::uintmax_t>::digits
: std::numeric_limits<base_result>::digits : std::numeric_limits<base_result>::digits
>::fast result_type; >::fast result_type;
private: private:
base_type rng_; base_type rng_;
public: public:
//uniform_int_float = default; // ??? //uniform_int_float = default; // ???
SPROUT_CONSTEXPR uniform_int_float() SPROUT_CONSTEXPR uniform_int_float()
: rng_() : rng_()
{} {}
SPROUT_CONSTEXPR explicit uniform_int_float(base_type const& rng) SPROUT_CONSTEXPR explicit uniform_int_float(base_type const& rng)
: rng_(rng) : rng_(rng)
{} {}
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return 0; return 0;
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return ( return (
result_type(2) << ( result_type(2) << (
NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min( NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(
std::numeric_limits<result_type>::digits, std::numeric_limits<result_type>::digits,
sprout::random::detail::generator_bits<base_type>::value() sprout::random::detail::generator_bits<base_type>::value()
) - 1 ) - 1
) )
) - 1 ) - 1
; ;
} }
base_type& base() { base_type& base() {
return rng_; return rng_;
} }
SPROUT_CONSTEXPR base_type const& base() const { SPROUT_CONSTEXPR base_type const& base() const {
return rng_; return rng_;
} }
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> generate( SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> generate(
sprout::random::random_result<base_type> const& rnd sprout::random::random_result<base_type> const& rnd
) const ) const
{ {
return sprout::random::random_result<uniform_int_float>( return sprout::random::random_result<uniform_int_float>(
static_cast<result_type>(rnd.result() * (static_cast<base_result>(max()) + 1)), static_cast<result_type>(rnd.result() * (static_cast<base_result>(max()) + 1)),
uniform_int_float(rnd.engine()) uniform_int_float(rnd.engine())
); );
} }
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> operator()() const {
return generate(rng_()); return generate(rng_());
} }
}; };
} // namespace detail } // namespace detail
} // namespace random } // namespace random
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP #endif // #ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP

View file

@ -1,216 +1,216 @@
#ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP #ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP
#define SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP #define SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include <ios> #include <ios>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/random/detail/const_mod.hpp> #include <sprout/random/detail/const_mod.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
// //
// linear_congruential_engine // linear_congruential_engine
// //
template<typename IntType, IntType a, IntType c, IntType m> template<typename IntType, IntType a, IntType c, IntType m>
class linear_congruential_engine { class linear_congruential_engine {
public: public:
typedef IntType result_type; typedef IntType result_type;
private: private:
struct private_constructor_tag {}; struct private_constructor_tag {};
public: public:
SPROUT_STATIC_CONSTEXPR IntType multiplier = a; SPROUT_STATIC_CONSTEXPR IntType multiplier = a;
SPROUT_STATIC_CONSTEXPR IntType increment = c; SPROUT_STATIC_CONSTEXPR IntType increment = c;
SPROUT_STATIC_CONSTEXPR IntType modulus = m; SPROUT_STATIC_CONSTEXPR IntType modulus = m;
SPROUT_STATIC_CONSTEXPR IntType default_seed = 1; SPROUT_STATIC_CONSTEXPR IntType default_seed = 1;
public: public:
static_assert(std::numeric_limits<IntType>::is_integer, "std::numeric_limits<IntType>::is_integer"); static_assert(std::numeric_limits<IntType>::is_integer, "std::numeric_limits<IntType>::is_integer");
static_assert(m == 0 || a < m, "m == 0 || a < m"); static_assert(m == 0 || a < m, "m == 0 || a < m");
static_assert(m == 0 || c < m, "m == 0 || c < m"); static_assert(m == 0 || c < m, "m == 0 || c < m");
private: private:
static SPROUT_CONSTEXPR IntType init_seed_3(IntType const& x0) { static SPROUT_CONSTEXPR IntType init_seed_3(IntType const& x0) {
return x0 >= static_min() && x0 <= static_max() return x0 >= static_min() && x0 <= static_max()
? x0 ? x0
: throw "assert(x0 >= static_min() && x0 <= static_max())" : throw "assert(x0 >= static_min() && x0 <= static_max())"
; ;
} }
static SPROUT_CONSTEXPR IntType init_seed_2(IntType const& x0) { static SPROUT_CONSTEXPR IntType init_seed_2(IntType const& x0) {
return init_seed_3(increment == 0 && x0 == 0 ? 1 : x0); return init_seed_3(increment == 0 && x0 == 0 ? 1 : x0);
} }
static SPROUT_CONSTEXPR IntType init_seed_1(IntType const& x0) { static SPROUT_CONSTEXPR IntType init_seed_1(IntType const& x0) {
return init_seed_2(x0 <= 0 && x0 != 0 ? x0 + modulus : x0); return init_seed_2(x0 <= 0 && x0 != 0 ? x0 + modulus : x0);
} }
static SPROUT_CONSTEXPR IntType init_seed(IntType const& x0) { static SPROUT_CONSTEXPR IntType init_seed(IntType const& x0) {
return init_seed_1(modulus == 0 ? x0 : x0 % modulus); return init_seed_1(modulus == 0 ? x0 : x0 % modulus);
} }
public: public:
static SPROUT_CONSTEXPR result_type static_min() { static SPROUT_CONSTEXPR result_type static_min() {
return c == 0 ? 1 : 0; return c == 0 ? 1 : 0;
} }
static SPROUT_CONSTEXPR result_type static_max() { static SPROUT_CONSTEXPR result_type static_max() {
return modulus - 1; return modulus - 1;
} }
private: private:
IntType x_; IntType x_;
private: private:
SPROUT_CONSTEXPR linear_congruential_engine(IntType const& x, private_constructor_tag) SPROUT_CONSTEXPR linear_congruential_engine(IntType const& x, private_constructor_tag)
: x_(x) : x_(x)
{} {}
SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> generate(result_type result) const { SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> generate(result_type result) const {
return sprout::random::random_result<linear_congruential_engine>( return sprout::random::random_result<linear_congruential_engine>(
result, result,
linear_congruential_engine(result, private_constructor_tag()) linear_congruential_engine(result, private_constructor_tag())
); );
} }
public: public:
SPROUT_CONSTEXPR linear_congruential_engine() SPROUT_CONSTEXPR linear_congruential_engine()
: x_(init_seed(default_seed)) : x_(init_seed(default_seed))
{} {}
SPROUT_CONSTEXPR explicit linear_congruential_engine(IntType const& x0) SPROUT_CONSTEXPR explicit linear_congruential_engine(IntType const& x0)
: x_(init_seed(x0)) : x_(init_seed(x0))
{} {}
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return static_min(); return static_min();
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return static_max(); return static_max();
} }
SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> operator()() const {
return generate(sprout::random::detail::const_mod<IntType, m>::mult_add(a, x_, c)); return generate(sprout::random::detail::const_mod<IntType, m>::mult_add(a, x_, c));
} }
friend SPROUT_CONSTEXPR bool operator==(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) { friend SPROUT_CONSTEXPR bool operator==(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) {
return lhs.x_ == rhs.x_; return lhs.x_ == rhs.x_;
} }
friend SPROUT_CONSTEXPR bool operator!=(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) { friend SPROUT_CONSTEXPR bool operator!=(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_istream<Elem, Traits>& operator>>( friend std::basic_istream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
linear_congruential_engine const& rhs linear_congruential_engine const& rhs
) )
{ {
IntType x; IntType x;
if(lhs >> x) { if(lhs >> x) {
if(x >= min() && x <= max()) { if(x >= min() && x <= max()) {
rhs.x_ = x; rhs.x_ = x;
} else { } else {
lhs.setstate(std::ios_base::failbit); lhs.setstate(std::ios_base::failbit);
} }
} }
return lhs; return lhs;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
linear_congruential_engine const& rhs linear_congruential_engine const& rhs
) )
{ {
return lhs << rhs.x_; return lhs << rhs.x_;
} }
}; };
template<typename IntType, IntType a, IntType c, IntType m> template<typename IntType, IntType a, IntType c, IntType m>
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::multiplier; SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::multiplier;
template<typename IntType, IntType a, IntType c, IntType m> template<typename IntType, IntType a, IntType c, IntType m>
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::increment; SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::increment;
template<typename IntType, IntType a, IntType c, IntType m> template<typename IntType, IntType a, IntType c, IntType m>
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::modulus; SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::modulus;
template<typename IntType, IntType a, IntType c, IntType m> template<typename IntType, IntType a, IntType c, IntType m>
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::default_seed; SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::default_seed;
// //
// minstd_rand0 // minstd_rand0
// //
typedef sprout::random::linear_congruential_engine<std::uint32_t, 16807, 0, 2147483647> minstd_rand0; typedef sprout::random::linear_congruential_engine<std::uint32_t, 16807, 0, 2147483647> minstd_rand0;
// //
// minstd_rand // minstd_rand
// //
typedef sprout::random::linear_congruential_engine<std::uint32_t, 48271, 0, 2147483647> minstd_rand; typedef sprout::random::linear_congruential_engine<std::uint32_t, 48271, 0, 2147483647> minstd_rand;
// //
// rand48 // rand48
// //
class rand48 { class rand48 {
public: public:
typedef std::uint32_t result_type; typedef std::uint32_t result_type;
private: private:
struct private_constructor_tag {}; struct private_constructor_tag {};
typedef sprout::random::linear_congruential_engine< typedef sprout::random::linear_congruential_engine<
std::uint64_t, std::uint64_t,
std::uint64_t(0xDEECE66DUL) | (std::uint64_t(0x5) << 32), std::uint64_t(0xDEECE66DUL) | (std::uint64_t(0x5) << 32),
0xB, 0xB,
std::uint64_t(1) << 48 std::uint64_t(1) << 48
> lcf_type; > lcf_type;
public: public:
static SPROUT_CONSTEXPR result_type static_min() { static SPROUT_CONSTEXPR result_type static_min() {
return 0; return 0;
} }
static SPROUT_CONSTEXPR result_type static_max() { static SPROUT_CONSTEXPR result_type static_max() {
return 0x7FFFFFFF; return 0x7FFFFFFF;
} }
static SPROUT_CONSTEXPR std::uint64_t cnv(std::uint32_t x) { static SPROUT_CONSTEXPR std::uint64_t cnv(std::uint32_t x) {
return (static_cast<std::uint64_t>(x) << 16) | 0x330e; return (static_cast<std::uint64_t>(x) << 16) | 0x330e;
} }
private: private:
lcf_type lcf_; lcf_type lcf_;
private: private:
SPROUT_CONSTEXPR rand48(lcf_type const& lcf, private_constructor_tag) SPROUT_CONSTEXPR rand48(lcf_type const& lcf, private_constructor_tag)
: lcf_(lcf) : lcf_(lcf)
{} {}
SPROUT_CONSTEXPR sprout::random::random_result<rand48> generate( SPROUT_CONSTEXPR sprout::random::random_result<rand48> generate(
sprout::random::random_result<lcf_type> const& lcf_result sprout::random::random_result<lcf_type> const& lcf_result
) const ) const
{ {
return sprout::random::random_result<rand48>( return sprout::random::random_result<rand48>(
lcf_result.result() >> 17, lcf_result.result() >> 17,
rand48(lcf_result.engine(), private_constructor_tag()) rand48(lcf_result.engine(), private_constructor_tag())
); );
} }
public: public:
SPROUT_CONSTEXPR rand48() SPROUT_CONSTEXPR rand48()
: lcf_(cnv(static_cast<std::uint32_t>(1))) : lcf_(cnv(static_cast<std::uint32_t>(1)))
{} {}
SPROUT_CONSTEXPR explicit rand48(result_type const& x0) SPROUT_CONSTEXPR explicit rand48(result_type const& x0)
: lcf_(cnv(x0)) : lcf_(cnv(x0))
{} {}
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return static_min(); return static_min();
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return static_max(); return static_max();
} }
SPROUT_CONSTEXPR sprout::random::random_result<rand48> operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<rand48> operator()() const {
return generate(lcf_()); return generate(lcf_());
} }
friend SPROUT_CONSTEXPR bool operator==(rand48 const& lhs, rand48 const& rhs) { friend SPROUT_CONSTEXPR bool operator==(rand48 const& lhs, rand48 const& rhs) {
return lhs.lcf_ == rhs.lcf_; return lhs.lcf_ == rhs.lcf_;
} }
friend SPROUT_CONSTEXPR bool operator!=(rand48 const& lhs, rand48 const& rhs) { friend SPROUT_CONSTEXPR bool operator!=(rand48 const& lhs, rand48 const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_istream<Elem, Traits>& operator>>( friend std::basic_istream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
rand48 const& rhs rand48 const& rhs
) )
{ {
return lhs >> rhs.lcf_; return lhs >> rhs.lcf_;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
rand48 const& rhs rand48 const& rhs
) )
{ {
return lhs << rhs.lcf_; return lhs << rhs.lcf_;
} }
}; };
} // namespace random } // namespace random
using sprout::random::minstd_rand0; using sprout::random::minstd_rand0;
using sprout::random::minstd_rand; using sprout::random::minstd_rand;
using sprout::random::rand48; using sprout::random::rand48;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP #endif // #ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP

View file

@ -1,468 +1,468 @@
#ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP #ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP
#define SPROUT_RANDOM_MERSENNE_TWISTER_HPP #define SPROUT_RANDOM_MERSENNE_TWISTER_HPP
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <ios> #include <ios>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
#include <sprout/array.hpp> #include <sprout/array.hpp>
#include <sprout/detail/integer/integer_mask.hpp> #include <sprout/detail/integer/integer_mask.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
// //
// mersenne_twister_engine // mersenne_twister_engine
// //
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
class mersenne_twister_engine { class mersenne_twister_engine {
public: public:
typedef UIntType result_type; typedef UIntType result_type;
private: private:
struct private_constructor_tag {}; struct private_constructor_tag {};
public: public:
SPROUT_STATIC_CONSTEXPR std::size_t word_size = w; SPROUT_STATIC_CONSTEXPR std::size_t word_size = w;
SPROUT_STATIC_CONSTEXPR std::size_t state_size = n; SPROUT_STATIC_CONSTEXPR std::size_t state_size = n;
SPROUT_STATIC_CONSTEXPR std::size_t shift_size = m; SPROUT_STATIC_CONSTEXPR std::size_t shift_size = m;
SPROUT_STATIC_CONSTEXPR std::size_t mask_bits = r; SPROUT_STATIC_CONSTEXPR std::size_t mask_bits = r;
SPROUT_STATIC_CONSTEXPR UIntType xor_mask = a; SPROUT_STATIC_CONSTEXPR UIntType xor_mask = a;
SPROUT_STATIC_CONSTEXPR std::size_t tempering_u = u; SPROUT_STATIC_CONSTEXPR std::size_t tempering_u = u;
SPROUT_STATIC_CONSTEXPR UIntType tempering_d = d; SPROUT_STATIC_CONSTEXPR UIntType tempering_d = d;
SPROUT_STATIC_CONSTEXPR std::size_t tempering_s = s; SPROUT_STATIC_CONSTEXPR std::size_t tempering_s = s;
SPROUT_STATIC_CONSTEXPR UIntType tempering_b = b; SPROUT_STATIC_CONSTEXPR UIntType tempering_b = b;
SPROUT_STATIC_CONSTEXPR std::size_t tempering_t = t; SPROUT_STATIC_CONSTEXPR std::size_t tempering_t = t;
SPROUT_STATIC_CONSTEXPR UIntType tempering_c = c; SPROUT_STATIC_CONSTEXPR UIntType tempering_c = c;
SPROUT_STATIC_CONSTEXPR std::size_t tempering_l = l; SPROUT_STATIC_CONSTEXPR std::size_t tempering_l = l;
SPROUT_STATIC_CONSTEXPR UIntType initialization_multiplier = f; SPROUT_STATIC_CONSTEXPR UIntType initialization_multiplier = f;
SPROUT_STATIC_CONSTEXPR UIntType default_seed = 5489u; SPROUT_STATIC_CONSTEXPR UIntType default_seed = 5489u;
private: private:
SPROUT_STATIC_CONSTEXPR UIntType upper_mask = (~static_cast<UIntType>(0)) << r; SPROUT_STATIC_CONSTEXPR UIntType upper_mask = (~static_cast<UIntType>(0)) << r;
SPROUT_STATIC_CONSTEXPR UIntType lower_mask = ~upper_mask; SPROUT_STATIC_CONSTEXPR UIntType lower_mask = ~upper_mask;
SPROUT_STATIC_CONSTEXPR std::size_t unroll_factor = 6; 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_extra1 = (n - m) % unroll_factor;
SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra2 = (m - 1) % unroll_factor; SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra2 = (m - 1) % unroll_factor;
private: private:
template<typename... Args> template<typename... Args>
static SPROUT_CONSTEXPR typename std::enable_if< static SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) + 1 == n, sizeof...(Args) + 1 == n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type init_seed_1(UIntType const& value, Args const&... args) { >::type init_seed_1(UIntType const& value, Args const&... args) {
return sprout::array<UIntType, n>{{args..., value}}; return sprout::array<UIntType, n>{{args..., value}};
} }
template<typename... Args> template<typename... Args>
static SPROUT_CONSTEXPR typename std::enable_if< static SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) + 1 < n, sizeof...(Args) + 1 < n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type init_seed_1(UIntType const& value, Args const&... args) { >::type init_seed_1(UIntType const& value, Args const&... args) {
return init_seed_1( return init_seed_1(
(f * (value ^ (value >> (w - 2))) + (sizeof...(Args) + 1)) & static_max(), (f * (value ^ (value >> (w - 2))) + (sizeof...(Args) + 1)) & static_max(),
args..., args...,
value value
); );
} }
static SPROUT_CONSTEXPR sprout::array<UIntType, n> init_seed(UIntType const& value) { static SPROUT_CONSTEXPR sprout::array<UIntType, n> init_seed(UIntType const& value) {
return init_seed_1(value & static_max()); return init_seed_1(value & static_max());
} }
public: public:
static SPROUT_CONSTEXPR result_type static_min() { static SPROUT_CONSTEXPR result_type static_min() {
return 0; return 0;
} }
static SPROUT_CONSTEXPR result_type static_max() { static SPROUT_CONSTEXPR result_type static_max() {
return sprout::detail::low_bits_mask_t<w>::sig_bits; return sprout::detail::low_bits_mask_t<w>::sig_bits;
} }
private: private:
sprout::array<UIntType, n> x_; sprout::array<UIntType, n> x_;
std::size_t i_; std::size_t i_;
private: private:
SPROUT_CONSTEXPR mersenne_twister_engine(sprout::array<UIntType, n> const& x, std::size_t i, private_constructor_tag) SPROUT_CONSTEXPR mersenne_twister_engine(sprout::array<UIntType, n> const& x, std::size_t i, private_constructor_tag)
: x_(x) : x_(x)
, i_(i) , i_(i)
{} {}
SPROUT_CONSTEXPR UIntType rewind_find_1(UIntType const* last, std::size_t size, std::size_t index) const { SPROUT_CONSTEXPR UIntType rewind_find_1(UIntType const* last, std::size_t size, std::size_t index) const {
return index < n - size return index < n - size
? x_[index] ? x_[index]
: *(last - (n - 1 - index)) : *(last - (n - 1 - index))
; ;
} }
SPROUT_CONSTEXPR UIntType rewind_find(UIntType const* last, std::size_t size, std::size_t i) const { 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); return rewind_find_1(last, size, (i + n - size + n - 1) % n);
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == n, sizeof...(Args) == n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_finish_1(sprout::array<UIntType, n> const& data, Args const&... args) const { >::type rewind_finish_1(sprout::array<UIntType, n> const& data, Args const&... args) const {
return sprout::array<UIntType, n>{{args...}}; return sprout::array<UIntType, n>{{args...}};
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) < n, sizeof...(Args) < n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_finish_1(sprout::array<UIntType, n> const& data, Args const&... args) const { >::type rewind_finish_1(sprout::array<UIntType, n> const& data, Args const&... args) const {
return rewind_finish_1(data, args..., data[sizeof...(args)]); return rewind_finish_1(data, args..., data[sizeof...(args)]);
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == n, sizeof...(Args) == n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_finish(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, std::size_t i, Args const&... args) const { >::type rewind_finish(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, std::size_t i, Args const&... args) const {
return sprout::array<UIntType, n>{{args...}}; return sprout::array<UIntType, n>{{args...}};
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) < n, sizeof...(Args) < n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_finish(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, std::size_t i, Args const&... args) const { >::type rewind_finish(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, std::size_t i, Args const&... args) const {
return &data[0] + i == last - z return &data[0] + i == last - z
? rewind_finish_1(data, data[i], args...) ? rewind_finish_1(data, data[i], args...)
: rewind_finish(data, last, z, i + 1, data[i], args...) : rewind_finish(data, last, z, i + 1, data[i], args...)
; ;
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == n, sizeof...(Args) == n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_4(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { >::type rewind_4(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const {
return sprout::array<UIntType, n>{{args...}}; return sprout::array<UIntType, n>{{args...}};
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) < n, sizeof...(Args) < n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_4(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { >::type rewind_4(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const {
return rewind_2( return rewind_2(
data, data,
last, last,
z, z,
y1, y1,
i, i,
(y0 & upper_mask) | (y1 & lower_mask), (y0 & upper_mask) | (y1 & lower_mask),
args... args...
); );
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == n, sizeof...(Args) == n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_3(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { >::type rewind_3(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const {
return sprout::array<UIntType, n>{{args...}}; return sprout::array<UIntType, n>{{args...}};
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) < n, sizeof...(Args) < n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_3(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const { >::type rewind_3(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, UIntType y1, std::size_t i, Args const&... args) const {
return rewind_4( return rewind_4(
data, data,
last, last,
z, z,
y0, y0,
y1 & (static_cast<UIntType>(1) << (w - 1)) y1 & (static_cast<UIntType>(1) << (w - 1))
? ((y1 ^ a) << 1) | 1 ? ((y1 ^ a) << 1) | 1
: y1 << 1 : y1 << 1
, ,
i, i,
args... args...
); );
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == n, sizeof...(Args) == n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_2(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, std::size_t i, Args const&... args) const { >::type rewind_2(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, std::size_t i, Args const&... args) const {
return sprout::array<UIntType, n>{{args...}}; return sprout::array<UIntType, n>{{args...}};
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) < n, sizeof...(Args) < n,
sprout::array<UIntType, n> sprout::array<UIntType, n>
>::type rewind_2(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, std::size_t i, Args const&... args) const { >::type rewind_2(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0, std::size_t i, Args const&... args) const {
return i < z return i < z
? rewind_3(data, last, z, y0, rewind_find(last, i, m - 1) ^ rewind_find(last, i, n - 1), i, args...) ? 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...) : rewind_finish(data, last, z, 0, args...)
; ;
} }
SPROUT_CONSTEXPR sprout::array<UIntType, n> rewind_1(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0) const { SPROUT_CONSTEXPR sprout::array<UIntType, n> rewind_1(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0) const {
return rewind_2( return rewind_2(
data, data,
last, last,
z, z,
y0 & (static_cast<UIntType>(1) << (w - 1)) y0 & (static_cast<UIntType>(1) << (w - 1))
? ((y0 ^ a) << 1) | 1 ? ((y0 ^ a) << 1) | 1
: y0 << 1 : y0 << 1
, ,
0 0
); );
} }
SPROUT_CONSTEXPR sprout::array<UIntType, n> rewind(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z) const { SPROUT_CONSTEXPR sprout::array<UIntType, n> rewind(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z) const {
return rewind_1(data, last, z, x_[m - 1] ^ x_[n - 1]); 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<UIntType, n> back, std::size_t offset, std::size_t i = 0) const { SPROUT_CONSTEXPR bool equal_impl_2(mersenne_twister_engine const& other, sprout::array<UIntType, n> back, std::size_t offset, std::size_t i = 0) const {
return i < offset return i < offset
? back[i + n - offset] != other.x_[i] ? back[i + n - offset] != other.x_[i]
? false ? false
: equal_impl_2(other, back, offset, i + 1) : equal_impl_2(other, back, offset, i + 1)
: true : true
; ;
} }
SPROUT_CONSTEXPR bool equal_impl_1(mersenne_twister_engine const& other, sprout::array<UIntType, n> back, std::size_t offset, std::size_t i = 0) const { SPROUT_CONSTEXPR bool equal_impl_1(mersenne_twister_engine const& other, sprout::array<UIntType, n> back, std::size_t offset, std::size_t i = 0) const {
return i + offset < n return i + offset < n
? x_[i] != other.x_[i + offset] ? x_[i] != other.x_[i + offset]
? false ? false
: equal_impl_1(other, back, offset, i + 1) : equal_impl_1(other, back, offset, i + 1)
: equal_impl_2(other, rewind(back, &back[n - 1], offset), offset) : equal_impl_2(other, rewind(back, &back[n - 1], offset), offset)
; ;
} }
SPROUT_CONSTEXPR bool equal_impl(mersenne_twister_engine const& other) const { SPROUT_CONSTEXPR bool equal_impl(mersenne_twister_engine const& other) const {
return equal_impl_1(other, sprout::array<UIntType, n>(), other.i_ - i_); return equal_impl_1(other, sprout::array<UIntType, n>(), other.i_ - i_);
} }
SPROUT_CONSTEXPR UIntType generate_impl_4(UIntType z) const { SPROUT_CONSTEXPR UIntType generate_impl_4(UIntType z) const {
return z ^ (z >> l); return z ^ (z >> l);
} }
SPROUT_CONSTEXPR UIntType generate_impl_3(UIntType z) const { SPROUT_CONSTEXPR UIntType generate_impl_3(UIntType z) const {
return z ^ generate_impl_4((z << t) & c); return z ^ generate_impl_4((z << t) & c);
} }
SPROUT_CONSTEXPR UIntType generate_impl_2(UIntType z) const { SPROUT_CONSTEXPR UIntType generate_impl_2(UIntType z) const {
return z ^ generate_impl_3((z << s) & b); return z ^ generate_impl_3((z << s) & b);
} }
SPROUT_CONSTEXPR UIntType generate_impl_1(UIntType z) const { SPROUT_CONSTEXPR UIntType generate_impl_1(UIntType z) const {
return z ^ generate_impl_2((z >> u) & d); return z ^ generate_impl_2((z >> u) & d);
} }
SPROUT_CONSTEXPR UIntType generate_impl() const { SPROUT_CONSTEXPR UIntType generate_impl() const {
return generate_impl_1(x_[i_]); return generate_impl_1(x_[i_]);
} }
SPROUT_CONSTEXPR sprout::random::random_result<mersenne_twister_engine> generate() const { SPROUT_CONSTEXPR sprout::random::random_result<mersenne_twister_engine> generate() const {
return sprout::random::random_result<mersenne_twister_engine>( return sprout::random::random_result<mersenne_twister_engine>(
generate_impl(), generate_impl(),
mersenne_twister_engine( mersenne_twister_engine(
x_, x_,
i_ + 1, i_ + 1,
private_constructor_tag() private_constructor_tag()
) )
); );
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR mersenne_twister_engine twist_5(Args const&... args) const { SPROUT_CONSTEXPR mersenne_twister_engine twist_5(Args const&... args) const {
return mersenne_twister_engine( return mersenne_twister_engine(
sprout::array<UIntType, n>{{args..., x_[m - 1] ^ ((x_[n - 1] & upper_mask) | (x_[0] & lower_mask) >> 1) ^ ((x_[0] & 1) * a)}}, sprout::array<UIntType, n>{{args..., x_[m - 1] ^ ((x_[n - 1] & upper_mask) | (x_[0] & lower_mask) >> 1) ^ ((x_[0] & 1) * a)}},
0, 0,
private_constructor_tag() private_constructor_tag()
); );
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == n - 1, sizeof...(Args) == n - 1,
mersenne_twister_engine mersenne_twister_engine
>::type twist_4(std::size_t i, Args const&... args) const { >::type twist_4(std::size_t i, Args const&... args) const {
return twist_5(args...); return twist_5(args...);
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) < n - 1, sizeof...(Args) < n - 1,
mersenne_twister_engine mersenne_twister_engine
>::type twist_4(std::size_t i, Args const&... args) const { >::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)); 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<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == n - 1 - unroll_extra2, sizeof...(Args) == n - 1 - unroll_extra2,
mersenne_twister_engine mersenne_twister_engine
>::type twist_3(std::size_t i, Args const&... args) const { >::type twist_3(std::size_t i, Args const&... args) const {
return twist_4(n - 1 - unroll_extra2, args...); return twist_4(n - 1 - unroll_extra2, args...);
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) < n - 1 - unroll_extra2, sizeof...(Args) < n - 1 - unroll_extra2,
mersenne_twister_engine mersenne_twister_engine
>::type twist_3(std::size_t i, Args const&... args) const { >::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)); 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<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == n - m, sizeof...(Args) == n - m,
mersenne_twister_engine mersenne_twister_engine
>::type twist_2(std::size_t i, Args const&... args) const { >::type twist_2(std::size_t i, Args const&... args) const {
return twist_3(n - m, args...); return twist_3(n - m, args...);
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) < n - m, sizeof...(Args) < n - m,
mersenne_twister_engine mersenne_twister_engine
>::type twist_2(std::size_t i, Args const&... args) const { >::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)); 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<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) == n - m - unroll_extra1, sizeof...(Args) == n - m - unroll_extra1,
mersenne_twister_engine mersenne_twister_engine
>::type twist_1(std::size_t i, Args const&... args) const { >::type twist_1(std::size_t i, Args const&... args) const {
return twist_2(n - m - unroll_extra1, args...); return twist_2(n - m - unroll_extra1, args...);
} }
template<typename... Args> template<typename... Args>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
sizeof...(Args) < n - m - unroll_extra1, sizeof...(Args) < n - m - unroll_extra1,
mersenne_twister_engine mersenne_twister_engine
>::type twist_1(std::size_t i, Args const&... args) const { >::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)); 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 { SPROUT_CONSTEXPR mersenne_twister_engine twist() const {
return twist_1(0); return twist_1(0);
} }
public: public:
SPROUT_CONSTEXPR mersenne_twister_engine() SPROUT_CONSTEXPR mersenne_twister_engine()
: x_(init_seed(default_seed)) : x_(init_seed(default_seed))
, i_(n) , i_(n)
{} {}
SPROUT_CONSTEXPR explicit mersenne_twister_engine(UIntType const& value) SPROUT_CONSTEXPR explicit mersenne_twister_engine(UIntType const& value)
: x_(init_seed(value)) : x_(init_seed(value))
, i_(n) , i_(n)
{} {}
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return static_min(); return static_min();
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return static_max(); return static_max();
} }
SPROUT_CONSTEXPR sprout::random::random_result<mersenne_twister_engine> operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<mersenne_twister_engine> operator()() const {
return i_ == n return i_ == n
? twist().generate() ? twist().generate()
: generate() : generate()
; ;
} }
friend SPROUT_CONSTEXPR bool operator==(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) { friend SPROUT_CONSTEXPR bool operator==(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) {
return lhs.i_ < lhs.i_ return lhs.i_ < lhs.i_
? lhs.equal_impl(rhs) ? lhs.equal_impl(rhs)
: rhs.equal_impl(lhs) : rhs.equal_impl(lhs)
; ;
} }
friend SPROUT_CONSTEXPR bool operator!=(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) { friend SPROUT_CONSTEXPR bool operator!=(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_istream<Elem, Traits>& operator>>( friend std::basic_istream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
mersenne_twister_engine const& rhs mersenne_twister_engine const& rhs
) )
{ {
sprout::array<UIntType, n> data; sprout::array<UIntType, n> data;
for(std::size_t i = 0; i < rhs.i_; ++i) { for(std::size_t i = 0; i < rhs.i_; ++i) {
data[i + n - rhs.i_] = rhs.x_[i]; data[i + n - rhs.i_] = rhs.x_[i];
} }
if (rhs.i_ != n) { if (rhs.i_ != n) {
data = rhs.rewind(data, &data[n - rhs.i_ - 1], n - rhs.i_); data = rhs.rewind(data, &data[n - rhs.i_ - 1], n - rhs.i_);
} }
lhs << data[0]; lhs << data[0];
for (std::size_t i = 0; i < rhs.i_; ++i) { for (std::size_t i = 0; i < rhs.i_; ++i) {
lhs << ' ' << data[i]; lhs << ' ' << data[i];
} }
return lhs; return lhs;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
mersenne_twister_engine const& rhs mersenne_twister_engine const& rhs
) )
{ {
for (std::size_t i = 0; i < state_size; ++i) { for (std::size_t i = 0; i < state_size; ++i) {
lhs >> rhs.x_[i] >> std::ws; lhs >> rhs.x_[i] >> std::ws;
} }
rhs.i_ = state_size; rhs.i_ = state_size;
return lhs; return lhs;
} }
}; };
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::word_size; SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::word_size;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::state_size; SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::state_size;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::shift_size; SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::shift_size;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::mask_bits; SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::mask_bits;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::xor_mask; SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::xor_mask;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_u; SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_u;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_d; SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_d;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_s; SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_s;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_b; SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_b;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_t; SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_t;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_c; SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_c;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_l; SPROUT_CONSTEXPR std::size_t sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::tempering_l;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::initialization_multiplier; SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::initialization_multiplier;
template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f> template<typename UIntType, std::size_t w, std::size_t n, std::size_t m, std::size_t r, UIntType a, std::size_t u, UIntType d, std::size_t s, UIntType b, std::size_t t, UIntType c, std::size_t l, UIntType f>
SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::default_seed; SPROUT_CONSTEXPR UIntType sprout::random::mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>::default_seed;
// //
// mt11213b // mt11213b
// //
typedef sprout::random::mersenne_twister_engine< typedef sprout::random::mersenne_twister_engine<
std::uint32_t, std::uint32_t,
32, 32,
351, 351,
175, 175,
19, 19,
0xccab8ee7, 0xccab8ee7,
11, 11,
0xffffffff, 0xffffffff,
7, 7,
0x31b6ab00, 0x31b6ab00,
15, 15,
0xffe50000, 0xffe50000,
17, 17,
1812433253 1812433253
> mt11213b; > mt11213b;
// //
// mt19937 // mt19937
// //
typedef sprout::random::mersenne_twister_engine< typedef sprout::random::mersenne_twister_engine<
std::uint32_t, std::uint32_t,
32, 32,
624, 624,
397, 397,
31, 31,
0x9908b0df, 0x9908b0df,
11, 11,
0xffffffff, 0xffffffff,
7, 7,
0x9d2c5680, 0x9d2c5680,
15, 15,
0xefc60000, 0xefc60000,
18, 18,
1812433253 1812433253
> mt19937; > mt19937;
// //
// mt19937_64 // mt19937_64
// //
typedef sprout::random::mersenne_twister_engine< typedef sprout::random::mersenne_twister_engine<
std::uint64_t, std::uint64_t,
64, 64,
312, 312,
156, 156,
31, 31,
UINT64_C(0xb5026f5aa96619e9), UINT64_C(0xb5026f5aa96619e9),
29, 29,
UINT64_C(0x5555555555555555), UINT64_C(0x5555555555555555),
17, 17,
UINT64_C(0x71d67fffeda60000), UINT64_C(0x71d67fffeda60000),
37, 37,
UINT64_C(0xfff7eee000000000), UINT64_C(0xfff7eee000000000),
43, 43,
UINT64_C(6364136223846793005) UINT64_C(6364136223846793005)
> mt19937_64; > mt19937_64;
} // namespace random } // namespace random
using sprout::random::mt11213b; using sprout::random::mt11213b;
using sprout::random::mt19937; using sprout::random::mt19937;
using sprout::random::mt19937_64; using sprout::random::mt19937_64;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP #endif // #ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP

View file

@ -1,326 +1,326 @@
#ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP #ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP
#define SPROUT_RANDOM_RANDOM_ITERATOR_HPP #define SPROUT_RANDOM_RANDOM_ITERATOR_HPP
#include <cstddef> #include <cstddef>
#include <iterator> #include <iterator>
#include <utility> #include <utility>
#include <stdexcept> #include <stdexcept>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/next.hpp> #include <sprout/iterator/next.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
// //
// random_iterator // random_iterator
// //
template<typename Engine, typename Distribution = void, typename Enable = void> template<typename Engine, typename Distribution = void, typename Enable = void>
class random_iterator; class random_iterator;
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
class random_iterator< class random_iterator<
Engine, Engine,
Distribution, Distribution,
typename std::enable_if<!std::is_same<Distribution, void>::value>::type typename std::enable_if<!std::is_same<Distribution, void>::value>::type
> >
: public std::iterator< : public std::iterator<
typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::iterator_category, typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::iterator_category,
typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::value_type, typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::value_type,
typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::difference_type, typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::difference_type,
typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::pointer, typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::pointer,
typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::reference typename std::iterator_traits<sprout::random::random_result<Engine, Distribution> >::reference
> >
{ {
public: public:
typedef sprout::random::random_result<Engine, Distribution> random_result_type; typedef sprout::random::random_result<Engine, Distribution> random_result_type;
typedef typename random_result_type::engine_type engine_type; typedef typename random_result_type::engine_type engine_type;
typedef typename random_result_type::distribution_type distribution_type; typedef typename random_result_type::distribution_type distribution_type;
typedef typename random_result_type::result_type result_type; typedef typename random_result_type::result_type result_type;
typedef typename std::iterator_traits<random_result_type>::iterator_category iterator_category; typedef typename std::iterator_traits<random_result_type>::iterator_category iterator_category;
typedef typename std::iterator_traits<random_result_type>::value_type value_type; typedef typename std::iterator_traits<random_result_type>::value_type value_type;
typedef typename std::iterator_traits<random_result_type>::difference_type difference_type; typedef typename std::iterator_traits<random_result_type>::difference_type difference_type;
typedef typename std::iterator_traits<random_result_type>::pointer pointer; typedef typename std::iterator_traits<random_result_type>::pointer pointer;
typedef typename std::iterator_traits<random_result_type>::reference reference; typedef typename std::iterator_traits<random_result_type>::reference reference;
private: private:
random_result_type random_; random_result_type random_;
difference_type count_; difference_type count_;
public: public:
//random_iterator() = default; // ??? //random_iterator() = default; // ???
SPROUT_CONSTEXPR random_iterator() SPROUT_CONSTEXPR random_iterator()
: random_() : random_()
, count_() , count_()
{} {}
SPROUT_CONSTEXPR random_iterator( SPROUT_CONSTEXPR random_iterator(
engine_type const& engine, engine_type const& engine,
distribution_type const& distribution, distribution_type const& distribution,
difference_type count = -1 difference_type count = -1
) )
: random_(distribution(engine)) : random_(distribution(engine))
, count_(count) , count_(count)
{} {}
SPROUT_CONSTEXPR explicit random_iterator( SPROUT_CONSTEXPR explicit random_iterator(
random_result_type const& random, random_result_type const& random,
difference_type count = -1 difference_type count = -1
) )
: random_(random) : random_(random)
, count_(count) , count_(count)
{} {}
SPROUT_CONSTEXPR random_iterator operator()() const { SPROUT_CONSTEXPR random_iterator operator()() const {
return count_ != 0 return count_ != 0
? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_) ? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_)
: throw "assert(count_ != 0)" : throw "assert(count_ != 0)"
; ;
} }
random_result_type& random_result() { random_result_type& random_result() {
return random_; return random_;
} }
SPROUT_CONSTEXPR random_result_type const& random_result() const { SPROUT_CONSTEXPR random_result_type const& random_result() const {
return random_; return random_;
} }
result_type& result() { result_type& result() {
return random_.result(); return random_.result();
} }
SPROUT_CONSTEXPR result_type const& result() const { SPROUT_CONSTEXPR result_type const& result() const {
return random_.result(); return random_.result();
} }
engine_type& engine() { engine_type& engine() {
return random_.engine(); return random_.engine();
} }
SPROUT_CONSTEXPR engine_type const& engine() const { SPROUT_CONSTEXPR engine_type const& engine() const {
return random_.engine(); return random_.engine();
} }
distribution_type& distribution() { distribution_type& distribution() {
return random_.distribution(); return random_.distribution();
} }
SPROUT_CONSTEXPR distribution_type const& distribution() const { SPROUT_CONSTEXPR distribution_type const& distribution() const {
return random_.distribution(); return random_.distribution();
} }
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return random_.min(); return random_.min();
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return random_.max(); return random_.max();
} }
SPROUT_CONSTEXPR result_type count() const { SPROUT_CONSTEXPR result_type count() const {
return count_; return count_;
} }
void swap(random_iterator& other) { void swap(random_iterator& other) {
using std::swap; using std::swap;
swap(random_, other.random_); swap(random_, other.random_);
swap(count_, other.count_); swap(count_, other.count_);
} }
friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) { 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_); 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) { friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
SPROUT_CONSTEXPR reference operator*() const { SPROUT_CONSTEXPR reference operator*() const {
return count_ != 0 return count_ != 0
? random_.result() ? random_.result()
: (throw "assert(count_ != 0)", random_.result()) : (throw "assert(count_ != 0)", random_.result())
; ;
} }
SPROUT_CONSTEXPR pointer operator->() const { SPROUT_CONSTEXPR pointer operator->() const {
return count_ != 0 return count_ != 0
? &random_.result() ? &random_.result()
: throw "assert(count_ != 0)" : throw "assert(count_ != 0)"
; ;
} }
random_iterator& operator++() { random_iterator& operator++() {
random_iterator temp((*this)()); random_iterator temp((*this)());
temp.swap(*this); temp.swap(*this);
return *this; return *this;
} }
random_iterator operator++(int) { random_iterator operator++(int) {
random_iterator result(*this); random_iterator result(*this);
++*this; ++*this;
return result; return result;
} }
}; };
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
class random_iterator< class random_iterator<
Engine, Engine,
Distribution, Distribution,
typename std::enable_if<std::is_same<Distribution, void>::value>::type typename std::enable_if<std::is_same<Distribution, void>::value>::type
> >
: public std::iterator< : public std::iterator<
typename std::iterator_traits<sprout::random::random_result<Engine> >::iterator_category, typename std::iterator_traits<sprout::random::random_result<Engine> >::iterator_category,
typename std::iterator_traits<sprout::random::random_result<Engine> >::value_type, typename std::iterator_traits<sprout::random::random_result<Engine> >::value_type,
typename std::iterator_traits<sprout::random::random_result<Engine> >::difference_type, typename std::iterator_traits<sprout::random::random_result<Engine> >::difference_type,
typename std::iterator_traits<sprout::random::random_result<Engine> >::pointer, typename std::iterator_traits<sprout::random::random_result<Engine> >::pointer,
typename std::iterator_traits<sprout::random::random_result<Engine> >::reference typename std::iterator_traits<sprout::random::random_result<Engine> >::reference
> >
{ {
public: public:
typedef sprout::random::random_result<Engine> random_result_type; typedef sprout::random::random_result<Engine> random_result_type;
typedef typename random_result_type::engine_type engine_type; typedef typename random_result_type::engine_type engine_type;
typedef typename random_result_type::result_type result_type; typedef typename random_result_type::result_type result_type;
typedef typename std::iterator_traits<random_result_type>::iterator_category iterator_category; typedef typename std::iterator_traits<random_result_type>::iterator_category iterator_category;
typedef typename std::iterator_traits<random_result_type>::value_type value_type; typedef typename std::iterator_traits<random_result_type>::value_type value_type;
typedef typename std::iterator_traits<random_result_type>::difference_type difference_type; typedef typename std::iterator_traits<random_result_type>::difference_type difference_type;
typedef typename std::iterator_traits<random_result_type>::pointer pointer; typedef typename std::iterator_traits<random_result_type>::pointer pointer;
typedef typename std::iterator_traits<random_result_type>::reference reference; typedef typename std::iterator_traits<random_result_type>::reference reference;
private: private:
random_result_type random_; random_result_type random_;
difference_type count_; difference_type count_;
public: public:
//random_iterator() = default; // ??? //random_iterator() = default; // ???
SPROUT_CONSTEXPR random_iterator() SPROUT_CONSTEXPR random_iterator()
: random_() : random_()
, count_() , count_()
{} {}
SPROUT_CONSTEXPR random_iterator( SPROUT_CONSTEXPR random_iterator(
engine_type const& engine, engine_type const& engine,
difference_type count = -1 difference_type count = -1
) )
: random_(engine()) : random_(engine())
, count_(count) , count_(count)
{} {}
SPROUT_CONSTEXPR explicit random_iterator( SPROUT_CONSTEXPR explicit random_iterator(
random_result_type const& random, random_result_type const& random,
difference_type count = -1 difference_type count = -1
) )
: random_(random) : random_(random)
, count_(count) , count_(count)
{} {}
SPROUT_CONSTEXPR random_iterator operator()() const { SPROUT_CONSTEXPR random_iterator operator()() const {
return count_ != 0 return count_ != 0
? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_) ? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_)
: throw "assert(count_ != 0)" : throw "assert(count_ != 0)"
; ;
} }
random_result_type& random_result() { random_result_type& random_result() {
return random_; return random_;
} }
SPROUT_CONSTEXPR random_result_type const& random_result() const { SPROUT_CONSTEXPR random_result_type const& random_result() const {
return random_; return random_;
} }
result_type& result() { result_type& result() {
return random_.result(); return random_.result();
} }
SPROUT_CONSTEXPR result_type const& result() const { SPROUT_CONSTEXPR result_type const& result() const {
return random_.result(); return random_.result();
} }
engine_type& engine() { engine_type& engine() {
return random_.engine(); return random_.engine();
} }
SPROUT_CONSTEXPR engine_type const& engine() const { SPROUT_CONSTEXPR engine_type const& engine() const {
return random_.engine(); return random_.engine();
} }
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return random_.min(); return random_.min();
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return random_.max(); return random_.max();
} }
SPROUT_CONSTEXPR result_type count() const { SPROUT_CONSTEXPR result_type count() const {
return count_; return count_;
} }
void swap(random_iterator& other) { void swap(random_iterator& other) {
using std::swap; using std::swap;
swap(random_, other.random_); swap(random_, other.random_);
swap(count_, other.count_); swap(count_, other.count_);
} }
friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) { 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_); 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) { friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
SPROUT_CONSTEXPR reference operator*() const { SPROUT_CONSTEXPR reference operator*() const {
return count_ != 0 return count_ != 0
? random_.result() ? random_.result()
: (throw "assert(count_ != 0)", random_.result()) : (throw "assert(count_ != 0)", random_.result())
; ;
} }
SPROUT_CONSTEXPR pointer operator->() const { SPROUT_CONSTEXPR pointer operator->() const {
return count_ > 0 return count_ > 0
? &random_.result() ? &random_.result()
: throw "assert(count_ != 0)" : throw "assert(count_ != 0)"
; ;
} }
random_iterator& operator++() { random_iterator& operator++() {
random_iterator temp((*this)()); random_iterator temp((*this)());
temp.swap(*this); temp.swap(*this);
return *this; return *this;
} }
random_iterator operator++(int) { random_iterator operator++(int) {
random_iterator result(*this); random_iterator result(*this);
++*this; ++*this;
return result; return result;
} }
}; };
// //
// swap // swap
// //
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
void swap( void swap(
sprout::random::random_iterator<Engine, Distribution>& lhs, sprout::random::random_iterator<Engine, Distribution>& lhs,
sprout::random::random_iterator<Engine, Distribution>& rhs sprout::random::random_iterator<Engine, Distribution>& rhs
) )
{ {
lhs.swap(rhs); lhs.swap(rhs);
} }
// //
// begin // begin
// //
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
SPROUT_CONSTEXPR typename std::enable_if< SPROUT_CONSTEXPR typename std::enable_if<
!std::is_integral<Distribution>::value, !std::is_integral<Distribution>::value,
sprout::random::random_iterator<Engine, Distribution> sprout::random::random_iterator<Engine, Distribution>
>::type begin( >::type begin(
Engine const& engine, Engine const& engine,
Distribution const& distribution, Distribution const& distribution,
typename sprout::random::random_iterator<Engine, Distribution>::difference_type count = -1 typename sprout::random::random_iterator<Engine, Distribution>::difference_type count = -1
) )
{ {
return sprout::random::random_iterator<Engine, Distribution>(engine, distribution, count); return sprout::random::random_iterator<Engine, Distribution>(engine, distribution, count);
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine> begin( SPROUT_CONSTEXPR sprout::random::random_iterator<Engine> begin(
Engine const& engine, Engine const& engine,
typename sprout::random::random_iterator<Engine>::difference_type count = -1 typename sprout::random::random_iterator<Engine>::difference_type count = -1
) )
{ {
return sprout::random::random_iterator<Engine>(engine, count); return sprout::random::random_iterator<Engine>(engine, count);
} }
// //
// end // end
// //
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine, Distribution> end( SPROUT_CONSTEXPR sprout::random::random_iterator<Engine, Distribution> end(
Engine const& engine, Engine const& engine,
Distribution const& distribution Distribution const& distribution
) )
{ {
return sprout::random::random_iterator<Engine, Distribution>(); return sprout::random::random_iterator<Engine, Distribution>();
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine> end( SPROUT_CONSTEXPR sprout::random::random_iterator<Engine> end(
Engine const& engine Engine const& engine
) )
{ {
return sprout::random::random_iterator<Engine>(); return sprout::random::random_iterator<Engine>();
} }
// //
// next // next
// //
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine, Distribution> next( SPROUT_CONSTEXPR sprout::random::random_iterator<Engine, Distribution> next(
sprout::random::random_iterator<Engine, Distribution> const& it sprout::random::random_iterator<Engine, Distribution> const& it
) )
{ {
return it(); return it();
} }
} // namespace random } // namespace random
using sprout::random::random_iterator; using sprout::random::random_iterator;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP #endif // #ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP

View file

@ -1,263 +1,263 @@
#ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP #ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP
#define SPROUT_RANDOM_RANDOM_RESULT_HPP #define SPROUT_RANDOM_RANDOM_RESULT_HPP
#include <cstddef> #include <cstddef>
#include <iterator> #include <iterator>
#include <utility> #include <utility>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/iterator/next.hpp> #include <sprout/iterator/next.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
// //
// random_result // random_result
// //
template<typename Engine, typename Distribution = void, typename Enable = void> template<typename Engine, typename Distribution = void, typename Enable = void>
class random_result; class random_result;
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
class random_result< class random_result<
Engine, Engine,
Distribution, Distribution,
typename std::enable_if<!std::is_same<Distribution, void>::value>::type typename std::enable_if<!std::is_same<Distribution, void>::value>::type
> >
: public std::iterator< : public std::iterator<
std::input_iterator_tag, std::input_iterator_tag,
typename Distribution::result_type, typename Distribution::result_type,
std::ptrdiff_t, std::ptrdiff_t,
typename Distribution::result_type const*, typename Distribution::result_type const*,
typename Distribution::result_type const& typename Distribution::result_type const&
> >
{ {
public: public:
typedef Engine engine_type; typedef Engine engine_type;
typedef Distribution distribution_type; typedef Distribution distribution_type;
typedef typename distribution_type::result_type result_type; typedef typename distribution_type::result_type result_type;
private: private:
typedef std::iterator< typedef std::iterator<
std::input_iterator_tag, std::input_iterator_tag,
result_type, result_type,
std::ptrdiff_t, std::ptrdiff_t,
result_type const*, result_type const*,
result_type const& result_type const&
> base_type; > base_type;
public: public:
typedef typename base_type::iterator_category iterator_category; typedef typename base_type::iterator_category iterator_category;
typedef typename base_type::value_type value_type; typedef typename base_type::value_type value_type;
typedef typename base_type::difference_type difference_type; typedef typename base_type::difference_type difference_type;
typedef typename base_type::pointer pointer; typedef typename base_type::pointer pointer;
typedef typename base_type::reference reference; typedef typename base_type::reference reference;
private: private:
result_type result_; result_type result_;
engine_type engine_; engine_type engine_;
distribution_type distribution_; distribution_type distribution_;
public: public:
//random_result() = default; // ??? //random_result() = default; // ???
SPROUT_CONSTEXPR random_result() SPROUT_CONSTEXPR random_result()
: result_() : result_()
, engine_() , engine_()
, distribution_() , distribution_()
{} {}
SPROUT_CONSTEXPR random_result( SPROUT_CONSTEXPR random_result(
result_type result, result_type result,
engine_type const& engine, engine_type const& engine,
distribution_type const& distribution distribution_type const& distribution
) )
: result_(result) : result_(result)
, engine_(engine) , engine_(engine)
, distribution_(distribution) , distribution_(distribution)
{} {}
SPROUT_CONSTEXPR operator result_type() const { SPROUT_CONSTEXPR operator result_type() const {
return result_; return result_;
} }
SPROUT_CONSTEXPR random_result operator()() const { SPROUT_CONSTEXPR random_result operator()() const {
return distribution_(engine_); return distribution_(engine_);
} }
result_type& result() { result_type& result() {
return result_; return result_;
} }
SPROUT_CONSTEXPR result_type const& result() const { SPROUT_CONSTEXPR result_type const& result() const {
return result_; return result_;
} }
engine_type& engine() { engine_type& engine() {
return engine_; return engine_;
} }
SPROUT_CONSTEXPR engine_type const& engine() const { SPROUT_CONSTEXPR engine_type const& engine() const {
return engine_; return engine_;
} }
distribution_type& distribution() { distribution_type& distribution() {
return distribution_; return distribution_;
} }
SPROUT_CONSTEXPR distribution_type const& distribution() const { SPROUT_CONSTEXPR distribution_type const& distribution() const {
return distribution_; return distribution_;
} }
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return distribution_.min(); return distribution_.min();
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return distribution_.max(); return distribution_.max();
} }
void swap(random_result& other) { void swap(random_result& other) {
using std::swap; using std::swap;
swap(result_, other.result_); swap(result_, other.result_);
swap(engine_, other.engine_); swap(engine_, other.engine_);
swap(distribution_, other.distribution_); swap(distribution_, other.distribution_);
} }
friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) { friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) {
return lhs.result_ == rhs.result_ return lhs.result_ == rhs.result_
&& lhs.engine_ == rhs.engine_ && lhs.engine_ == rhs.engine_
&& lhs.distribution_ == rhs.distribution_ && lhs.distribution_ == rhs.distribution_
; ;
} }
friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) { friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
SPROUT_CONSTEXPR reference operator*() const { SPROUT_CONSTEXPR reference operator*() const {
return result_; return result_;
} }
SPROUT_CONSTEXPR pointer operator->() const { SPROUT_CONSTEXPR pointer operator->() const {
return &result_; return &result_;
} }
random_result& operator++() { random_result& operator++() {
random_result temp((*this)()); random_result temp((*this)());
temp.swap(*this); temp.swap(*this);
return *this; return *this;
} }
random_result operator++(int) { random_result operator++(int) {
random_result result(*this); random_result result(*this);
++*this; ++*this;
return result; return result;
} }
}; };
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
class random_result< class random_result<
Engine, Engine,
Distribution, Distribution,
typename std::enable_if<std::is_same<Distribution, void>::value>::type typename std::enable_if<std::is_same<Distribution, void>::value>::type
> >
: public std::iterator< : public std::iterator<
std::input_iterator_tag, std::input_iterator_tag,
typename Engine::result_type, typename Engine::result_type,
std::ptrdiff_t, std::ptrdiff_t,
typename Engine::result_type const*, typename Engine::result_type const*,
typename Engine::result_type const& typename Engine::result_type const&
> >
{ {
public: public:
typedef Engine engine_type; typedef Engine engine_type;
typedef typename engine_type::result_type result_type; typedef typename engine_type::result_type result_type;
private: private:
typedef std::iterator< typedef std::iterator<
std::input_iterator_tag, std::input_iterator_tag,
result_type, result_type,
std::ptrdiff_t, std::ptrdiff_t,
result_type const*, result_type const*,
result_type const& result_type const&
> base_type; > base_type;
public: public:
typedef typename base_type::iterator_category iterator_category; typedef typename base_type::iterator_category iterator_category;
typedef typename base_type::value_type value_type; typedef typename base_type::value_type value_type;
typedef typename base_type::difference_type difference_type; typedef typename base_type::difference_type difference_type;
typedef typename base_type::pointer pointer; typedef typename base_type::pointer pointer;
typedef typename base_type::reference reference; typedef typename base_type::reference reference;
private: private:
result_type result_; result_type result_;
engine_type engine_; engine_type engine_;
public: public:
//random_result() = default; // ??? //random_result() = default; // ???
SPROUT_CONSTEXPR random_result() SPROUT_CONSTEXPR random_result()
: result_() : result_()
, engine_() , engine_()
{} {}
SPROUT_CONSTEXPR random_result( SPROUT_CONSTEXPR random_result(
result_type result, result_type result,
engine_type const& engine engine_type const& engine
) )
: result_(result) : result_(result)
, engine_(engine) , engine_(engine)
{} {}
SPROUT_CONSTEXPR operator result_type() const { SPROUT_CONSTEXPR operator result_type() const {
return result_; return result_;
} }
SPROUT_CONSTEXPR random_result operator()() const { SPROUT_CONSTEXPR random_result operator()() const {
return engine_(); return engine_();
} }
result_type& result() { result_type& result() {
return result_; return result_;
} }
SPROUT_CONSTEXPR result_type const& result() const { SPROUT_CONSTEXPR result_type const& result() const {
return result_; return result_;
} }
engine_type& engine() { engine_type& engine() {
return engine_; return engine_;
} }
SPROUT_CONSTEXPR engine_type const& engine() const { SPROUT_CONSTEXPR engine_type const& engine() const {
return engine_; return engine_;
} }
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return engine_.min(); return engine_.min();
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return engine_.max(); return engine_.max();
} }
friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) { friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) {
return lhs.result_ == rhs.result_ return lhs.result_ == rhs.result_
&& lhs.engine_ == rhs.engine_ && lhs.engine_ == rhs.engine_
; ;
} }
friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) { friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
void swap(random_result& other) { void swap(random_result& other) {
using std::swap; using std::swap;
swap(result_, other.result_); swap(result_, other.result_);
swap(engine_, other.engine_); swap(engine_, other.engine_);
} }
SPROUT_CONSTEXPR reference operator*() const { SPROUT_CONSTEXPR reference operator*() const {
return result_; return result_;
} }
SPROUT_CONSTEXPR pointer operator->() const { SPROUT_CONSTEXPR pointer operator->() const {
return &result_; return &result_;
} }
random_result& operator++() { random_result& operator++() {
random_result temp((*this)()); random_result temp((*this)());
temp.swap(*this); temp.swap(*this);
return *this; return *this;
} }
random_result operator++(int) { random_result operator++(int) {
random_result result(*this); random_result result(*this);
random_result temp((*this)()); random_result temp((*this)());
temp.swap(*this); temp.swap(*this);
return result; return result;
} }
}; };
// //
// swap // swap
// //
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
void swap( void swap(
sprout::random::random_result<Engine, Distribution>& lhs, sprout::random::random_result<Engine, Distribution>& lhs,
sprout::random::random_result<Engine, Distribution>& rhs sprout::random::random_result<Engine, Distribution>& rhs
) )
{ {
lhs.swap(rhs); lhs.swap(rhs);
} }
} // namespace random } // namespace random
// //
// next // next
// //
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, Distribution> next( SPROUT_CONSTEXPR sprout::random::random_result<Engine, Distribution> next(
sprout::random::random_result<Engine, Distribution> const& it sprout::random::random_result<Engine, Distribution> const& it
) )
{ {
return it(); return it();
} }
using sprout::random::random_result; using sprout::random::random_result;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP #endif // #ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP

View file

@ -1,92 +1,92 @@
#ifndef SPROUT_RANDOM_UNIFORM_01_HPP #ifndef SPROUT_RANDOM_UNIFORM_01_HPP
#define SPROUT_RANDOM_UNIFORM_01_HPP #define SPROUT_RANDOM_UNIFORM_01_HPP
#include <iosfwd> #include <iosfwd>
#include <istream> #include <istream>
#include <limits> #include <limits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
// //
// uniform_01 // uniform_01
// //
template<typename RealType = double> template<typename RealType = double>
class uniform_01 { class uniform_01 {
public: public:
typedef RealType input_type; typedef RealType input_type;
typedef RealType result_type; typedef RealType result_type;
private: private:
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> generate_1( SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> generate_1(
Engine const& eng, Engine const& eng,
sprout::random::random_result<Engine> const& rnd, sprout::random::random_result<Engine> const& rnd,
result_type result result_type result
) const ) const
{ {
return result < result_type(1) return result < result_type(1)
? sprout::random::random_result<Engine, uniform_01>(result, rnd.engine(), *this) ? sprout::random::random_result<Engine, uniform_01>(result, rnd.engine(), *this)
: operator()(rnd.engine()) : operator()(rnd.engine())
; ;
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> generate( SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> generate(
Engine const& eng, Engine const& eng,
sprout::random::random_result<Engine> const& rnd sprout::random::random_result<Engine> const& rnd
) const ) const
{ {
typedef typename Engine::result_type base_result; typedef typename Engine::result_type base_result;
return generate_1( return generate_1(
eng, eng,
rnd, rnd,
result_type(rnd.result() - eng.min()) * ( result_type(rnd.result() - eng.min()) * (
result_type(1) / ( result_type(1) / (
result_type(eng.max() - eng.min()) + result_type( result_type(eng.max() - eng.min()) + result_type(
std::numeric_limits<base_result>::is_integer ? 1 : 0 std::numeric_limits<base_result>::is_integer ? 1 : 0
) )
) )
) )
); );
} }
public: public:
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return result_type(0); return result_type(0);
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return result_type(1); return result_type(1);
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> operator()(Engine const& eng) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> operator()(Engine const& eng) const {
return generate(eng, eng()); return generate(eng, eng());
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator>>( friend std::basic_ostream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
uniform_01 const& rhs uniform_01 const& rhs
) )
{ {
return lhs; return lhs;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
uniform_01 const& rhs uniform_01 const& rhs
) )
{ {
return lhs; return lhs;
} }
SPROUT_CONSTEXPR friend bool operator==(uniform_01 const& lhs, uniform_01 const& rhs) { SPROUT_CONSTEXPR friend bool operator==(uniform_01 const& lhs, uniform_01 const& rhs) {
return true; return true;
} }
SPROUT_CONSTEXPR friend bool operator!=(uniform_01 const& lhs, uniform_01 const& rhs) { SPROUT_CONSTEXPR friend bool operator!=(uniform_01 const& lhs, uniform_01 const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
}; };
} // namespace random } // namespace random
using sprout::random::uniform_01; using sprout::random::uniform_01;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_UNIFORM_01_HPP #endif // #ifndef SPROUT_RANDOM_UNIFORM_01_HPP

File diff suppressed because it is too large Load diff

View file

@ -1,319 +1,319 @@
#ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP #ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
#define SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP #define SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
#include <ios> #include <ios>
#include <istream> #include <istream>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/random/detail/signed_unsigned_tools.hpp> #include <sprout/random/detail/signed_unsigned_tools.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
namespace detail { namespace detail {
template<typename T, typename Engine> template<typename T, typename Engine>
struct generate_uniform_real_result { struct generate_uniform_real_result {
public: public:
T result; T result;
Engine engine; Engine engine;
}; };
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_1( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_1(
sprout::random::random_result<Engine> const& rnd, sprout::random::random_result<Engine> const& rnd,
T min_value, T min_value,
T max_value T max_value
); );
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_3( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_3(
Engine const& eng, Engine const& eng,
T min_value, T min_value,
T max_value, T max_value,
T result T result
) )
{ {
return result < max_value return result < max_value
? sprout::random::detail::generate_uniform_real_result<T, Engine>{result, eng} ? sprout::random::detail::generate_uniform_real_result<T, Engine>{result, eng}
: sprout::random::detail::generate_uniform_real_false_1(eng(), min_value, max_value) : sprout::random::detail::generate_uniform_real_false_1(eng(), min_value, max_value)
; ;
} }
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_2( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_2(
Engine const& eng, Engine const& eng,
T min_value, T min_value,
T max_value, T max_value,
T numerator, T numerator,
T divisor T divisor
) )
{ {
return divisor > 0 return divisor > 0
? numerator >= 0 && numerator <= divisor ? numerator >= 0 && numerator <= divisor
? sprout::random::detail::generate_uniform_real_false_3( ? sprout::random::detail::generate_uniform_real_false_3(
eng, eng,
min_value, min_value,
max_value, max_value,
numerator / divisor * (max_value - min_value) + min_value numerator / divisor * (max_value - min_value) + min_value
) )
: throw "assert(numerator >= 0 && numerator <= divisor)" : throw "assert(numerator >= 0 && numerator <= divisor)"
: throw "assert(divisor > 0)" : throw "assert(divisor > 0)"
; ;
} }
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_1( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_1(
sprout::random::random_result<Engine> const& rnd, sprout::random::random_result<Engine> const& rnd,
T min_value, T min_value,
T max_value T max_value
) )
{ {
return sprout::random::detail::generate_uniform_real_false_2( return sprout::random::detail::generate_uniform_real_false_2(
rnd.engine(), rnd.engine(),
min_value, min_value,
max_value, max_value,
static_cast<T>(rnd.result() - rnd.engine().min()), static_cast<T>(rnd.result() - rnd.engine().min()),
static_cast<T>(rnd.engine().max() - rnd.engine().min()) static_cast<T>(rnd.engine().max() - rnd.engine().min())
); );
} }
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real(
Engine const& eng, Engine const& eng,
T min_value, T min_value,
T max_value, T max_value,
std::false_type std::false_type
) )
{ {
return sprout::random::detail::generate_uniform_real_false_1( return sprout::random::detail::generate_uniform_real_false_1(
eng(), eng(),
min_value, min_value,
max_value max_value
); );
} }
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_1( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_1(
sprout::random::random_result<Engine> const& rnd, sprout::random::random_result<Engine> const& rnd,
T min_value, T min_value,
T max_value T max_value
); );
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_3( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_3(
Engine const& eng, Engine const& eng,
T min_value, T min_value,
T max_value, T max_value,
T result T result
) )
{ {
return result < max_value return result < max_value
? sprout::random::detail::generate_uniform_real_result<T, Engine>{result, eng} ? sprout::random::detail::generate_uniform_real_result<T, Engine>{result, eng}
: sprout::random::detail::generate_uniform_real_true_1(eng(), min_value, max_value) : sprout::random::detail::generate_uniform_real_true_1(eng(), min_value, max_value)
; ;
} }
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_2( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_2(
Engine const& eng, Engine const& eng,
T min_value, T min_value,
T max_value, T max_value,
T numerator, T numerator,
T divisor T divisor
) )
{ {
return divisor > 0 return divisor > 0
? numerator >= 0 && numerator <= divisor ? numerator >= 0 && numerator <= divisor
? sprout::random::detail::generate_uniform_real_true_3( ? sprout::random::detail::generate_uniform_real_true_3(
eng, eng,
min_value, min_value,
max_value, max_value,
numerator / divisor * (max_value - min_value) + min_value numerator / divisor * (max_value - min_value) + min_value
) )
: throw "assert(numerator >= 0 && numerator <= divisor)" : throw "assert(numerator >= 0 && numerator <= divisor)"
: throw "assert(divisor > 0)" : throw "assert(divisor > 0)"
; ;
} }
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_1( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_1(
sprout::random::random_result<Engine> const& rnd, sprout::random::random_result<Engine> const& rnd,
T min_value, T min_value,
T max_value T max_value
) )
{ {
typedef T result_type; typedef T result_type;
typedef typename Engine::result_type base_result; typedef typename Engine::result_type base_result;
return sprout::random::detail::generate_uniform_real_true_2( return sprout::random::detail::generate_uniform_real_true_2(
rnd.engine(), rnd.engine(),
min_value, min_value,
max_value, max_value,
static_cast<T>(sprout::random::detail::subtract<base_result>()(rnd.result(), rnd.engine().min())), static_cast<T>(sprout::random::detail::subtract<base_result>()(rnd.result(), rnd.engine().min())),
static_cast<T>(sprout::random::detail::subtract<base_result>()(rnd.engine().max(), rnd.engine().min())) + 1 static_cast<T>(sprout::random::detail::subtract<base_result>()(rnd.engine().max(), rnd.engine().min())) + 1
); );
} }
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real(
Engine const& eng, Engine const& eng,
T min_value, T min_value,
T max_value, T max_value,
std::true_type std::true_type
) )
{ {
return sprout::random::detail::generate_uniform_real_true_1( return sprout::random::detail::generate_uniform_real_true_1(
eng(), eng(),
min_value, min_value,
max_value max_value
); );
} }
template<typename Engine, typename T> template<typename Engine, typename T>
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real( SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real(
Engine const& eng, Engine const& eng,
T min_value, T min_value,
T max_value T max_value
) )
{ {
return sprout::random::detail::generate_uniform_real( return sprout::random::detail::generate_uniform_real(
eng, eng,
min_value, min_value,
max_value, max_value,
std::is_integral<typename Engine::result_type>() std::is_integral<typename Engine::result_type>()
); );
} }
} // namespace detail } // namespace detail
// //
// uniform_real_distribution // uniform_real_distribution
// //
template<typename RealType = double> template<typename RealType = double>
class uniform_real_distribution { class uniform_real_distribution {
public: public:
typedef RealType input_type; typedef RealType input_type;
typedef RealType result_type; typedef RealType result_type;
private: private:
static SPROUT_CONSTEXPR RealType arg_check(RealType min_arg, RealType max_arg) { static SPROUT_CONSTEXPR RealType arg_check(RealType min_arg, RealType max_arg) {
return min_arg <= max_arg return min_arg <= max_arg
? min_arg ? min_arg
: throw "assert(min_arg <= max_arg)" : throw "assert(min_arg <= max_arg)"
; ;
} }
public: public:
// //
// param_type // param_type
// //
class param_type { class param_type {
public: public:
typedef uniform_real_distribution distribution_type; typedef uniform_real_distribution distribution_type;
private: private:
RealType min_; RealType min_;
RealType max_; RealType max_;
public: public:
SPROUT_CONSTEXPR param_type() SPROUT_CONSTEXPR param_type()
: min_(RealType(0.0)) : min_(RealType(0.0))
, max_(RealType(1.0)) , max_(RealType(1.0))
{} {}
SPROUT_CONSTEXPR explicit param_type(RealType min_arg, RealType max_arg = RealType(1.0)) SPROUT_CONSTEXPR explicit param_type(RealType min_arg, RealType max_arg = RealType(1.0))
: min_(arg_check(min_arg, max_arg)) : min_(arg_check(min_arg, max_arg))
, max_(max_arg) , max_(max_arg)
{} {}
SPROUT_CONSTEXPR RealType a() const { SPROUT_CONSTEXPR RealType a() const {
return min_; return min_;
} }
SPROUT_CONSTEXPR RealType b() const { SPROUT_CONSTEXPR RealType b() const {
return max_; return max_;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator>>( friend std::basic_ostream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
param_type const& rhs param_type const& rhs
) )
{ {
return lhs >> rhs.min_ >> std::ws >> rhs.max_; return lhs >> rhs.min_ >> std::ws >> rhs.max_;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
param_type const& rhs param_type const& rhs
) )
{ {
return lhs << rhs.min_ << " " << rhs.max_; return lhs << rhs.min_ << " " << rhs.max_;
} }
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_;
} }
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
}; };
private: private:
result_type min_; result_type min_;
result_type max_; result_type max_;
private: private:
template<typename Engine, typename Result> template<typename Engine, typename Result>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_real_distribution> generate(Result const& rnd) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_real_distribution> generate(Result const& rnd) const {
return sprout::random::random_result<Engine, uniform_real_distribution>( return sprout::random::random_result<Engine, uniform_real_distribution>(
rnd.result, rnd.result,
rnd.engine, rnd.engine,
*this *this
); );
} }
public: public:
SPROUT_CONSTEXPR uniform_real_distribution() SPROUT_CONSTEXPR uniform_real_distribution()
: min_(RealType(0.0)) : min_(RealType(0.0))
, max_(RealType(1.0)) , max_(RealType(1.0))
{} {}
SPROUT_CONSTEXPR explicit uniform_real_distribution(RealType min_arg, RealType max_arg = 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)) : min_(arg_check(min_arg, max_arg))
, max_(max_arg) , max_(max_arg)
{} {}
explicit uniform_real_distribution(param_type const& parm) explicit uniform_real_distribution(param_type const& parm)
: min_(parm.a()) : min_(parm.a())
, max_(parm.b()) , max_(parm.b())
{} {}
SPROUT_CONSTEXPR result_type a() const { SPROUT_CONSTEXPR result_type a() const {
return min_; return min_;
} }
SPROUT_CONSTEXPR result_type b() const { SPROUT_CONSTEXPR result_type b() const {
return max_; return max_;
} }
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return min_; return min_;
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return max_; return max_;
} }
SPROUT_CONSTEXPR param_type param() const { SPROUT_CONSTEXPR param_type param() const {
return param_type(min_, max_); return param_type(min_, max_);
} }
void param(param_type const& parm) { void param(param_type const& parm) {
min_ = parm.a(); min_ = parm.a();
max_ = parm.b(); max_ = parm.b();
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_real_distribution> operator()(Engine const& eng) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_real_distribution> operator()(Engine const& eng) const {
return generate<Engine>(sprout::random::detail::generate_uniform_real(eng, min_, max_)); return generate<Engine>(sprout::random::detail::generate_uniform_real(eng, min_, max_));
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator>>( friend std::basic_ostream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
uniform_real_distribution const& rhs uniform_real_distribution const& rhs
) )
{ {
param_type parm; param_type parm;
return lhs >> parm; return lhs >> parm;
param(parm); param(parm);
return lhs; return lhs;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
uniform_real_distribution const& rhs uniform_real_distribution const& rhs
) )
{ {
return lhs << param(); return lhs << param();
} }
SPROUT_CONSTEXPR friend bool operator==(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { SPROUT_CONSTEXPR friend bool operator==(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) {
return lhs.param() == rhs.param(); return lhs.param() == rhs.param();
} }
SPROUT_CONSTEXPR friend bool operator!=(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) { SPROUT_CONSTEXPR friend bool operator!=(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
}; };
} // namespace random } // namespace random
using sprout::random::uniform_real_distribution; using sprout::random::uniform_real_distribution;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP #endif // #ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP

View file

@ -1,255 +1,255 @@
#ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP #ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP
#define SPROUT_RANDOM_UNIFORM_SMALLINT_HPP #define SPROUT_RANDOM_UNIFORM_SMALLINT_HPP
#include <iosfwd> #include <iosfwd>
#include <istream> #include <istream>
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/random/detail/signed_unsigned_tools.hpp> #include <sprout/random/detail/signed_unsigned_tools.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
#include <sprout/random/uniform_01.hpp> #include <sprout/random/uniform_01.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
// //
// uniform_smallint // uniform_smallint
// //
template<typename IntType = int> template<typename IntType = int>
class uniform_smallint { class uniform_smallint {
public: public:
typedef IntType input_type; typedef IntType input_type;
typedef IntType result_type; typedef IntType result_type;
private: private:
static SPROUT_CONSTEXPR IntType arg_check(IntType min_arg, IntType max_arg) { static SPROUT_CONSTEXPR IntType arg_check(IntType min_arg, IntType max_arg) {
return min_arg <= max_arg return min_arg <= max_arg
? min_arg ? min_arg
: throw "assert(min_arg <= max_arg)" : throw "assert(min_arg <= max_arg)"
; ;
} }
public: public:
// //
// param_type // param_type
// //
class param_type { class param_type {
public: public:
typedef uniform_smallint distribution_type; typedef uniform_smallint distribution_type;
private: private:
IntType min_; IntType min_;
IntType max_; IntType max_;
public: public:
SPROUT_CONSTEXPR param_type() SPROUT_CONSTEXPR param_type()
: min_(0) : min_(0)
, max_(9) , max_(9)
{} {}
SPROUT_CONSTEXPR explicit param_type(IntType min_arg, IntType max_arg = 9) SPROUT_CONSTEXPR explicit param_type(IntType min_arg, IntType max_arg = 9)
: min_(arg_check(min_arg, max_arg)) : min_(arg_check(min_arg, max_arg))
, max_(max_arg) , max_(max_arg)
{} {}
SPROUT_CONSTEXPR IntType a() const { SPROUT_CONSTEXPR IntType a() const {
return min_; return min_;
} }
SPROUT_CONSTEXPR IntType b() const { SPROUT_CONSTEXPR IntType b() const {
return max_; return max_;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator>>( friend std::basic_ostream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
param_type const& rhs param_type const& rhs
) )
{ {
return lhs >> rhs.min_ >> std::ws >> rhs.max_; return lhs >> rhs.min_ >> std::ws >> rhs.max_;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
param_type const& rhs param_type const& rhs
) )
{ {
return lhs << rhs.min_ << " " << rhs.max_; return lhs << rhs.min_ << " " << rhs.max_;
} }
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) { SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_; return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_;
} }
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) { SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
}; };
private: private:
result_type min_; result_type min_;
result_type max_; result_type max_;
private: private:
template<typename Engine, typename RangeType, typename BaseUnsigned> template<typename Engine, typename RangeType, typename BaseUnsigned>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_2( SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_2(
Engine const& eng, Engine const& eng,
sprout::random::random_result<Engine> const& rnd, sprout::random::random_result<Engine> const& rnd,
RangeType range, RangeType range,
BaseUnsigned base_range, BaseUnsigned base_range,
BaseUnsigned val BaseUnsigned val
) const ) const
{ {
return range >= base_range return range >= base_range
? sprout::random::random_result<Engine, uniform_smallint>( ? sprout::random::random_result<Engine, uniform_smallint>(
sprout::random::detail::add<RangeType, result_type>()(static_cast<RangeType>(val), min_), sprout::random::detail::add<RangeType, result_type>()(static_cast<RangeType>(val), min_),
rnd.engine(), rnd.engine(),
*this *this
) )
: sprout::random::random_result<Engine, uniform_smallint>( : sprout::random::random_result<Engine, uniform_smallint>(
sprout::random::detail::add<RangeType, result_type>()(static_cast<RangeType>(val % (static_cast<BaseUnsigned>(range) + 1)), min_), sprout::random::detail::add<RangeType, result_type>()(static_cast<RangeType>(val % (static_cast<BaseUnsigned>(range) + 1)), min_),
rnd.engine(), rnd.engine(),
*this *this
) )
; ;
} }
template<typename Engine, typename RangeType, typename BaseUnsigned> template<typename Engine, typename RangeType, typename BaseUnsigned>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_1( SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_1(
Engine const& eng, Engine const& eng,
sprout::random::random_result<Engine> const& rnd, sprout::random::random_result<Engine> const& rnd,
RangeType range, RangeType range,
BaseUnsigned base_range BaseUnsigned base_range
) const ) const
{ {
typedef typename Engine::result_type base_result; typedef typename Engine::result_type base_result;
return generate_true_2( return generate_true_2(
eng, eng,
rnd, rnd,
range, range,
base_range, base_range,
BaseUnsigned(sprout::random::detail::subtract<base_result>()(rnd.result(), eng.min())) BaseUnsigned(sprout::random::detail::subtract<base_result>()(rnd.result(), eng.min()))
); );
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate( SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate(
Engine const& eng, Engine const& eng,
std::true_type std::true_type
) const ) const
{ {
typedef typename Engine::result_type base_result; typedef typename Engine::result_type base_result;
typedef typename std::make_unsigned<base_result>::type base_unsigned; typedef typename std::make_unsigned<base_result>::type base_unsigned;
typedef typename std::make_unsigned<result_type>::type range_type; typedef typename std::make_unsigned<result_type>::type range_type;
return generate_true_1( return generate_true_1(
eng, eng,
eng(), eng(),
range_type(sprout::random::detail::subtract<result_type>()(max_, min_)), range_type(sprout::random::detail::subtract<result_type>()(max_, min_)),
base_unsigned(sprout::random::detail::subtract<result_type>()(eng.max(), eng.min())) base_unsigned(sprout::random::detail::subtract<result_type>()(eng.max(), eng.min()))
); );
} }
template<typename Engine, typename RangeType> template<typename Engine, typename RangeType>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_false_2( SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_false_2(
Engine const& eng, Engine const& eng,
sprout::random::random_result<Engine, sprout::random::uniform_01<typename Engine::result_type> > const& rnd, sprout::random::random_result<Engine, sprout::random::uniform_01<typename Engine::result_type> > const& rnd,
RangeType range, RangeType range,
RangeType offset RangeType offset
) const ) const
{ {
return offset > range return offset > range
? sprout::random::random_result<Engine, uniform_smallint>( ? sprout::random::random_result<Engine, uniform_smallint>(
max_, max_,
rnd.engine(), rnd.engine(),
*this *this
) )
: sprout::random::random_result<Engine, uniform_smallint>( : sprout::random::random_result<Engine, uniform_smallint>(
sprout::random::detail::add<RangeType, result_type>()(offset , min_), sprout::random::detail::add<RangeType, result_type>()(offset , min_),
rnd.engine(), rnd.engine(),
*this *this
) )
; ;
} }
template<typename Engine, typename RangeType> template<typename Engine, typename RangeType>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_false_1( SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_false_1(
Engine const& eng, Engine const& eng,
sprout::random::random_result<Engine, sprout::random::uniform_01<typename Engine::result_type> > const& rnd, sprout::random::random_result<Engine, sprout::random::uniform_01<typename Engine::result_type> > const& rnd,
RangeType range RangeType range
) const ) const
{ {
typedef typename Engine::result_type base_result; typedef typename Engine::result_type base_result;
return generate_false_2( return generate_false_2(
eng, eng,
rnd, rnd,
RangeType(sprout::random::detail::subtract<result_type>()(max_, min_)), RangeType(sprout::random::detail::subtract<result_type>()(max_, min_)),
RangeType(static_cast<RangeType>(rnd.result() * (static_cast<base_result>(range) + 1))) RangeType(static_cast<RangeType>(rnd.result() * (static_cast<base_result>(range) + 1)))
); );
} }
template<class Engine> template<class Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate( SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate(
Engine const& eng, Engine const& eng,
std::false_type std::false_type
) const ) const
{ {
typedef typename Engine::result_type base_result; typedef typename Engine::result_type base_result;
typedef typename std::make_unsigned<result_type>::type range_type; typedef typename std::make_unsigned<result_type>::type range_type;
return generate_false_1( return generate_false_1(
eng, eng,
sprout::random::uniform_01<base_result>()(eng), sprout::random::uniform_01<base_result>()(eng),
range_type(sprout::random::detail::subtract<result_type>()(max_, min_)) range_type(sprout::random::detail::subtract<result_type>()(max_, min_))
); );
} }
public: public:
SPROUT_CONSTEXPR uniform_smallint() SPROUT_CONSTEXPR uniform_smallint()
: min_(0) : min_(0)
, max_(9) , max_(9)
{} {}
SPROUT_CONSTEXPR explicit uniform_smallint(IntType min_arg, IntType max_arg = 9) SPROUT_CONSTEXPR explicit uniform_smallint(IntType min_arg, IntType max_arg = 9)
: min_(arg_check(min_arg, max_arg)) : min_(arg_check(min_arg, max_arg))
, max_(max_arg) , max_(max_arg)
{} {}
explicit uniform_smallint(param_type const& parm) explicit uniform_smallint(param_type const& parm)
: min_(parm.a()) : min_(parm.a())
, max_(parm.b()) , max_(parm.b())
{} {}
SPROUT_CONSTEXPR result_type a() const { SPROUT_CONSTEXPR result_type a() const {
return min_; return min_;
} }
SPROUT_CONSTEXPR result_type b() const { SPROUT_CONSTEXPR result_type b() const {
return max_; return max_;
} }
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return min_; return min_;
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return max_; return max_;
} }
SPROUT_CONSTEXPR param_type param() const { SPROUT_CONSTEXPR param_type param() const {
return param_type(min_, max_); return param_type(min_, max_);
} }
void param(param_type const& parm) { void param(param_type const& parm) {
min_ = parm.a(); min_ = parm.a();
max_ = parm.b(); max_ = parm.b();
} }
template<typename Engine> template<typename Engine>
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> operator()(Engine const& eng) const { SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> operator()(Engine const& eng) const {
typedef typename Engine::result_type base_result; typedef typename Engine::result_type base_result;
return generate(eng, typename std::is_integral<base_result>::type()); return generate(eng, typename std::is_integral<base_result>::type());
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator>>( friend std::basic_ostream<Elem, Traits>& operator>>(
std::basic_istream<Elem, Traits>& lhs, std::basic_istream<Elem, Traits>& lhs,
uniform_smallint const& rhs uniform_smallint const& rhs
) )
{ {
param_type parm; param_type parm;
return lhs >> parm; return lhs >> parm;
param(parm); param(parm);
return lhs; return lhs;
} }
template<typename Elem, typename Traits> template<typename Elem, typename Traits>
friend std::basic_ostream<Elem, Traits>& operator<<( friend std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& lhs, std::basic_ostream<Elem, Traits>& lhs,
uniform_smallint const& rhs uniform_smallint const& rhs
) )
{ {
return lhs << param(); return lhs << param();
} }
SPROUT_CONSTEXPR friend bool operator==(uniform_smallint const& lhs, uniform_smallint const& rhs) { SPROUT_CONSTEXPR friend bool operator==(uniform_smallint const& lhs, uniform_smallint const& rhs) {
return lhs.param() == rhs.param(); return lhs.param() == rhs.param();
} }
SPROUT_CONSTEXPR friend bool operator!=(uniform_smallint const& lhs, uniform_smallint const& rhs) { SPROUT_CONSTEXPR friend bool operator!=(uniform_smallint const& lhs, uniform_smallint const& rhs) {
return !(lhs == rhs); return !(lhs == rhs);
} }
}; };
} // namespace random } // namespace random
using sprout::random::uniform_smallint; using sprout::random::uniform_smallint;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP #endif // #ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP

View file

@ -1,14 +1,14 @@
#ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP #ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP
#define SPROUT_RANDOM_UNIQUE_SEED_HPP #define SPROUT_RANDOM_UNIQUE_SEED_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/functional/hash/hash.hpp> #include <sprout/functional/hash/hash.hpp>
#include <sprout/preprocessor/unique_string.hpp> #include <sprout/preprocessor/unique_string.hpp>
// //
// SPROUT_UNIQUE_SEED // SPROUT_UNIQUE_SEED
// //
#define SPROUT_UNIQUE_SEED (::sprout::hash_value(SPROUT_PP_UNIQUE_STRING)) #define SPROUT_UNIQUE_SEED (::sprout::hash_value(SPROUT_PP_UNIQUE_STRING))
#endif // #ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP #endif // #ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP

View file

@ -1,84 +1,84 @@
#ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP #ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP
#define SPROUT_RANDOM_VARIATE_GENERATOR_HPP #define SPROUT_RANDOM_VARIATE_GENERATOR_HPP
#include <type_traits> #include <type_traits>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/detail/if.hpp> #include <sprout/detail/if.hpp>
#include <sprout/random/detail/ptr_helper.hpp> #include <sprout/random/detail/ptr_helper.hpp>
#include <sprout/random/random_result.hpp> #include <sprout/random/random_result.hpp>
namespace sprout { namespace sprout {
namespace random { namespace random {
// //
// variate_generator // variate_generator
// //
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
class variate_generator { class variate_generator {
private: private:
typedef sprout::random::detail::ptr_helper<Engine> engine_helper_type; typedef sprout::random::detail::ptr_helper<Engine> engine_helper_type;
typedef sprout::random::detail::ptr_helper<Distribution> distribution_helper_type; typedef sprout::random::detail::ptr_helper<Distribution> distribution_helper_type;
public: public:
typedef typename engine_helper_type::value_type engine_value_type; typedef typename engine_helper_type::value_type engine_value_type;
typedef typename distribution_helper_type::value_type distribution_value_type; typedef typename distribution_helper_type::value_type distribution_value_type;
typedef typename engine_helper_type::reference_type engine_reference_type; typedef typename engine_helper_type::reference_type engine_reference_type;
typedef typename distribution_helper_type::reference_type distribution_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 engine_helper_type::const_reference_type engine_const_reference_type;
typedef typename distribution_helper_type::const_reference_type distribution_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 engine_helper_type::rvalue_type engine_param_type;
typedef typename distribution_helper_type::rvalue_type distribution_param_type; typedef typename distribution_helper_type::rvalue_type distribution_param_type;
public: public:
typedef Engine engine_type; typedef Engine engine_type;
typedef Distribution distribution_type; typedef Distribution distribution_type;
typedef typename distribution_value_type::result_type result_type; typedef typename distribution_value_type::result_type result_type;
private: private:
engine_type engine_; engine_type engine_;
distribution_type distribution_; distribution_type distribution_;
public: public:
SPROUT_CONSTEXPR variate_generator( SPROUT_CONSTEXPR variate_generator(
engine_param_type engine, engine_param_type engine,
distribution_param_type distribution distribution_param_type distribution
) )
: engine_(engine) : engine_(engine)
, distribution_(distribution) , distribution_(distribution)
{} {}
SPROUT_CONSTEXPR sprout::random::random_result<engine_value_type, distribution_value_type> operator()() const { SPROUT_CONSTEXPR sprout::random::random_result<engine_value_type, distribution_value_type> operator()() const {
return distribution_(engine_); return distribution_(engine_);
} }
engine_reference_type engine() { engine_reference_type engine() {
return engine_helper_type::ref(engine_); return engine_helper_type::ref(engine_);
} }
SPROUT_CONSTEXPR engine_const_reference_type engine() const { SPROUT_CONSTEXPR engine_const_reference_type engine() const {
return engine_helper_type::ref(engine_); return engine_helper_type::ref(engine_);
} }
distribution_reference_type distribution() { distribution_reference_type distribution() {
return distribution_helper_type::ref(distribution_); return distribution_helper_type::ref(distribution_);
} }
SPROUT_CONSTEXPR distribution_const_reference_type distribution() const { SPROUT_CONSTEXPR distribution_const_reference_type distribution() const {
return distribution_helper_type::ref(distribution_); return distribution_helper_type::ref(distribution_);
} }
SPROUT_CONSTEXPR result_type min() const { SPROUT_CONSTEXPR result_type min() const {
return distribution_.min(); return distribution_.min();
} }
SPROUT_CONSTEXPR result_type max() const { SPROUT_CONSTEXPR result_type max() const {
return distribution_.max(); return distribution_.max();
} }
}; };
// //
// combine // combine
// //
template<typename Engine, typename Distribution> template<typename Engine, typename Distribution>
SPROUT_CONSTEXPR sprout::random::variate_generator<Engine const&, Distribution const&> combine( SPROUT_CONSTEXPR sprout::random::variate_generator<Engine const&, Distribution const&> combine(
Engine const& engine, Engine const& engine,
Distribution const& distribution Distribution const& distribution
) )
{ {
return sprout::random::variate_generator<Engine const&, Distribution const&>(engine, distribution); return sprout::random::variate_generator<Engine const&, Distribution const&>(engine, distribution);
} }
} // namespace random } // namespace random
using sprout::random::variate_generator; using sprout::random::variate_generator;
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP #endif // #ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP

View file

@ -1,160 +1,160 @@
#ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP #ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP
#define SPROUT_UTILITY_VALUE_HOLDER_HPP #define SPROUT_UTILITY_VALUE_HOLDER_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
namespace sprout { namespace sprout {
namespace detail { namespace detail {
template<typename T> template<typename T>
struct holder_helper { struct holder_helper {
public: public:
typedef T value_type; typedef T value_type;
typedef T& reference; typedef T& reference;
typedef T const& const_reference; typedef T const& const_reference;
typedef T const& mutable_or_const_reference; typedef T const& mutable_or_const_reference;
typedef T* pointer; typedef T* pointer;
typedef T const* const_pointer; typedef T const* const_pointer;
typedef T const* mutable_or_const_pointer; typedef T const* mutable_or_const_pointer;
typedef T const& param_type; typedef T const& param_type;
typedef T holder_type; typedef T holder_type;
public: public:
static SPROUT_CONSTEXPR holder_type const& hold(param_type p) { static SPROUT_CONSTEXPR holder_type const& hold(param_type p) {
return p; return p;
} }
static SPROUT_CONSTEXPR reference ref(holder_type& r) { static SPROUT_CONSTEXPR reference ref(holder_type& r) {
return r; return r;
} }
static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) {
return r; return r;
} }
static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { static SPROUT_CONSTEXPR pointer ptr(holder_type& r) {
return &r; return &r;
} }
static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) { static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) {
return &r; return &r;
} }
}; };
template<typename T> template<typename T>
struct holder_helper<T const> { struct holder_helper<T const> {
public: public:
typedef T value_type; typedef T value_type;
typedef T const& reference; typedef T const& reference;
typedef T const& const_reference; typedef T const& const_reference;
typedef T const& mutable_or_const_reference; typedef T const& mutable_or_const_reference;
typedef T const* pointer; typedef T const* pointer;
typedef T const* const_pointer; typedef T const* const_pointer;
typedef T const* mutable_or_const_pointer; typedef T const* mutable_or_const_pointer;
typedef T const& param_type; typedef T const& param_type;
typedef T holder_type; typedef T holder_type;
public: public:
static SPROUT_CONSTEXPR holder_type const& hold(param_type p) { static SPROUT_CONSTEXPR holder_type const& hold(param_type p) {
return &p; return &p;
} }
static SPROUT_CONSTEXPR reference ref(holder_type& r) { static SPROUT_CONSTEXPR reference ref(holder_type& r) {
return *r; return *r;
} }
static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) {
return *r; return *r;
} }
static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { static SPROUT_CONSTEXPR pointer ptr(holder_type& r) {
return &r; return &r;
} }
static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) { static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) {
return &r; return &r;
} }
}; };
template<typename T> template<typename T>
struct holder_helper<T&> { struct holder_helper<T&> {
public: public:
typedef T value_type; typedef T value_type;
typedef T& reference; typedef T& reference;
typedef T const& const_reference; typedef T const& const_reference;
typedef T& mutable_or_const_reference; typedef T& mutable_or_const_reference;
typedef T* pointer; typedef T* pointer;
typedef T const* const_pointer; typedef T const* const_pointer;
typedef T* mutable_or_const_pointer; typedef T* mutable_or_const_pointer;
typedef T& param_type; typedef T& param_type;
typedef T* holder_type; typedef T* holder_type;
public: public:
static SPROUT_CONSTEXPR holder_type hold(param_type p) { static SPROUT_CONSTEXPR holder_type hold(param_type p) {
return &p; return &p;
} }
static SPROUT_CONSTEXPR reference ref(holder_type r) { static SPROUT_CONSTEXPR reference ref(holder_type r) {
return *r; return *r;
} }
static SPROUT_CONSTEXPR pointer ptr(holder_type r) { static SPROUT_CONSTEXPR pointer ptr(holder_type r) {
return r; return r;
} }
}; };
template<typename T> template<typename T>
struct holder_helper<T const&> { struct holder_helper<T const&> {
public: public:
typedef T value_type; typedef T value_type;
typedef T const& reference; typedef T const& reference;
typedef T const& const_reference; typedef T const& const_reference;
typedef T const& mutable_or_const_reference; typedef T const& mutable_or_const_reference;
typedef T const* pointer; typedef T const* pointer;
typedef T const* const_pointer; typedef T const* const_pointer;
typedef T const* mutable_or_const_pointer; typedef T const* mutable_or_const_pointer;
typedef T const& param_type; typedef T const& param_type;
typedef T const* holder_type; typedef T const* holder_type;
public: public:
static SPROUT_CONSTEXPR holder_type hold(param_type p) { static SPROUT_CONSTEXPR holder_type hold(param_type p) {
return &p; return &p;
} }
static SPROUT_CONSTEXPR reference ref(holder_type r) { static SPROUT_CONSTEXPR reference ref(holder_type r) {
return *r; return *r;
} }
static SPROUT_CONSTEXPR pointer ptr(holder_type r) { static SPROUT_CONSTEXPR pointer ptr(holder_type r) {
return r; return r;
} }
}; };
} // namespace detail } // namespace detail
// //
// value_holder // value_holder
// //
template<typename T> template<typename T>
class value_holder { class value_holder {
public: public:
typedef T type; typedef T type;
private: private:
typedef sprout::detail::holder_helper<type> helper_type; typedef sprout::detail::holder_helper<type> helper_type;
typedef typename helper_type::holder_type holder_type; typedef typename helper_type::holder_type holder_type;
public: public:
typedef typename helper_type::value_type value_type; typedef typename helper_type::value_type value_type;
typedef typename helper_type::reference reference; typedef typename helper_type::reference reference;
typedef typename helper_type::const_reference const_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::mutable_or_const_reference mutable_or_const_reference;
typedef typename helper_type::pointer pointer; typedef typename helper_type::pointer pointer;
typedef typename helper_type::const_pointer const_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::mutable_or_const_pointer mutable_or_const_pointer;
typedef typename helper_type::param_type param_type; typedef typename helper_type::param_type param_type;
private: private:
holder_type holder_; holder_type holder_;
public: public:
value_holder() = default; value_holder() = default;
SPROUT_CONSTEXPR explicit value_holder(param_type p) SPROUT_CONSTEXPR explicit value_holder(param_type p)
: holder_(helper_type::hold(p)) : holder_(helper_type::hold(p))
{} {}
operator reference() { operator reference() {
return helper_type::ref(holder_); return helper_type::ref(holder_);
} }
SPROUT_CONSTEXPR operator const_reference() const { SPROUT_CONSTEXPR operator const_reference() const {
return helper_type::ref(holder_); return helper_type::ref(holder_);
} }
reference get() { reference get() {
return helper_type::ref(holder_); return helper_type::ref(holder_);
} }
SPROUT_CONSTEXPR mutable_or_const_reference get() const { SPROUT_CONSTEXPR mutable_or_const_reference get() const {
return helper_type::ref(holder_); return helper_type::ref(holder_);
} }
pointer get_pointer() { pointer get_pointer() {
return helper_type::ptr(holder_); return helper_type::ptr(holder_);
} }
SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer() const { SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer() const {
return helper_type::ptr(holder_); return helper_type::ptr(holder_);
} }
}; };
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP #endif // #ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP