mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2025-06-07 00:51:32 +00:00
改行コード統一
This commit is contained in:
parent
7abc568a53
commit
f3a7041250
29 changed files with 4034 additions and 4034 deletions
|
@ -1,8 +1,8 @@
|
|||
#ifndef SPROUT_FUNCTIONAL_HASH_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP
|
||||
|
||||
#ifndef SPROUT_FUNCTIONAL_HASH_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_ARRAY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
|
||||
namespace sprout {
|
||||
template<typename T, std::size_t N>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(sprout::array<T, N> const& v) {
|
||||
return sprout::hash_range(v.begin(), v.end());
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP
|
||||
|
||||
#ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_ARRAY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
|
||||
namespace sprout {
|
||||
template<typename T, std::size_t N>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(sprout::array<T, N> const& v) {
|
||||
return sprout::hash_range(v.begin(), v.end());
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_ARRAY_HPP
|
||||
|
||||
|
|
|
@ -1,227 +1,227 @@
|
|||
#ifndef SPROUT_FUNCTIONAL_HASH_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/functional/hash/hash_fwd.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// hash_value
|
||||
//
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(bool v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(char v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(short v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(int v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(long v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(long long v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v);
|
||||
//SPROUT_CONSTEXPR std::size_t inline hash_value(float v);
|
||||
//SPROUT_CONSTEXPR std::size_t inline hash_value(double v);
|
||||
//SPROUT_CONSTEXPR std::size_t inline hash_value(long double v);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(T*);
|
||||
template<typename T, std::size_t N>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]);
|
||||
|
||||
namespace hash_detail {
|
||||
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) {
|
||||
return i > 0
|
||||
? hash_value_signed_2(
|
||||
val,
|
||||
length,
|
||||
seed ^ static_cast<std::size_t>((positive >> i) + (seed << 6) + (seed >> 2)),
|
||||
positive,
|
||||
i - std::numeric_limits<std::size_t>::digits
|
||||
)
|
||||
: seed ^ static_cast<std::size_t>(val + (seed << 6) + (seed >> 2))
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
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);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value_signed(T val) {
|
||||
return sprout::hash_detail::hash_value_signed_1(
|
||||
val,
|
||||
(std::numeric_limits<T>::digits - 1) / std::numeric_limits<std::size_t>::digits,
|
||||
0,
|
||||
val < 0 ? -1 - val : val
|
||||
);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value_unsigned_2(T val, int length, std::size_t seed, std::size_t i) {
|
||||
return i > 0
|
||||
? hash_value_unsigned_2(
|
||||
val,
|
||||
length,
|
||||
seed ^ static_cast<std::size_t>((val >> i) + (seed << 6) + (seed >> 2)),
|
||||
i - std::numeric_limits<std::size_t>::digits
|
||||
)
|
||||
: seed ^ static_cast<std::size_t>(val + (seed << 6) + (seed >> 2))
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
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);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value_unsigned(T val) {
|
||||
return sprout::hash_detail::hash_value_unsigned_1(
|
||||
val,
|
||||
(std::numeric_limits<T>::digits - 1) / std::numeric_limits<std::size_t>::digits,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value_pointer_1(std::size_t x) {
|
||||
return x + (x >> 3);
|
||||
}
|
||||
template<typename T>
|
||||
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)));
|
||||
}
|
||||
} // namespace hash_detail
|
||||
|
||||
//
|
||||
// hash_value
|
||||
//
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(bool v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(char v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(short v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(int v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(long v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(long long v) {
|
||||
return sprout::hash_detail::hash_value_signed(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v) {
|
||||
return sprout::hash_detail::hash_value_unsigned(v);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(T* v) {
|
||||
return sprout::hash_detail::hash_value_pointer(v);
|
||||
}
|
||||
template<typename T, std::size_t N >
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]) {
|
||||
return sprout::hash_range(&v[0], &v[0] + N);
|
||||
}
|
||||
|
||||
//
|
||||
// hash_combine
|
||||
//
|
||||
template<typename T>
|
||||
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));
|
||||
}
|
||||
|
||||
//
|
||||
// hash_range
|
||||
//
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last) {
|
||||
return sprout::hash_range(0, first, last);
|
||||
}
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last) {
|
||||
return first != last
|
||||
? sprout::hash_range(sprout::hash_combine(seed, *first), sprout::next(first), last)
|
||||
: seed
|
||||
;
|
||||
}
|
||||
|
||||
#define SPROUT_HASH_SPECIALIZE(type) \
|
||||
template<> \
|
||||
struct hash<type> { \
|
||||
public: \
|
||||
typedef type argument_type; \
|
||||
typedef std::size_t result_type; \
|
||||
public: \
|
||||
SPROUT_CONSTEXPR std::size_t operator()(type v) const { \
|
||||
return sprout::hash_value(v); \
|
||||
} \
|
||||
}
|
||||
#define SPROUT_HASH_SPECIALIZE_REF(type) \
|
||||
template<> \
|
||||
struct hash<type> { \
|
||||
public: \
|
||||
typedef type argument_type; \
|
||||
typedef std::size_t result_type; \
|
||||
public: \
|
||||
SPROUT_CONSTEXPR std::size_t operator()(type const& v) const { \
|
||||
return sprout::hash_value(v); \
|
||||
} \
|
||||
}
|
||||
|
||||
//
|
||||
// hash
|
||||
//
|
||||
SPROUT_HASH_SPECIALIZE(bool);
|
||||
SPROUT_HASH_SPECIALIZE(char);
|
||||
SPROUT_HASH_SPECIALIZE(wchar_t);
|
||||
SPROUT_HASH_SPECIALIZE(signed char);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned char);
|
||||
SPROUT_HASH_SPECIALIZE(short);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned short);
|
||||
SPROUT_HASH_SPECIALIZE(int);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned int);
|
||||
SPROUT_HASH_SPECIALIZE(long);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned long);
|
||||
SPROUT_HASH_SPECIALIZE(long long);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned long long);
|
||||
|
||||
#undef SPROUT_HASH_SPECIALIZE
|
||||
#undef SPROUT_HASH_SPECIALIZE_REF
|
||||
|
||||
template <class T>
|
||||
struct hash<T*> {
|
||||
public:
|
||||
typedef T* argument_type;
|
||||
typedef std::size_t result_type;
|
||||
public: \
|
||||
SPROUT_CONSTEXPR std::size_t operator()(T* v) const {
|
||||
return sprout::hash_value(v);
|
||||
}
|
||||
};
|
||||
} //namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP
|
||||
|
||||
#ifndef SPROUT_FUNCTIONAL_HASH_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/operation.hpp>
|
||||
#include <sprout/functional/hash/hash_fwd.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// hash_value
|
||||
//
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(bool v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(char v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(short v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(int v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(long v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(long long v);
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v);
|
||||
//SPROUT_CONSTEXPR std::size_t inline hash_value(float v);
|
||||
//SPROUT_CONSTEXPR std::size_t inline hash_value(double v);
|
||||
//SPROUT_CONSTEXPR std::size_t inline hash_value(long double v);
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(T*);
|
||||
template<typename T, std::size_t N>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]);
|
||||
|
||||
namespace hash_detail {
|
||||
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) {
|
||||
return i > 0
|
||||
? hash_value_signed_2(
|
||||
val,
|
||||
length,
|
||||
seed ^ static_cast<std::size_t>((positive >> i) + (seed << 6) + (seed >> 2)),
|
||||
positive,
|
||||
i - std::numeric_limits<std::size_t>::digits
|
||||
)
|
||||
: seed ^ static_cast<std::size_t>(val + (seed << 6) + (seed >> 2))
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
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);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value_signed(T val) {
|
||||
return sprout::hash_detail::hash_value_signed_1(
|
||||
val,
|
||||
(std::numeric_limits<T>::digits - 1) / std::numeric_limits<std::size_t>::digits,
|
||||
0,
|
||||
val < 0 ? -1 - val : val
|
||||
);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value_unsigned_2(T val, int length, std::size_t seed, std::size_t i) {
|
||||
return i > 0
|
||||
? hash_value_unsigned_2(
|
||||
val,
|
||||
length,
|
||||
seed ^ static_cast<std::size_t>((val >> i) + (seed << 6) + (seed >> 2)),
|
||||
i - std::numeric_limits<std::size_t>::digits
|
||||
)
|
||||
: seed ^ static_cast<std::size_t>(val + (seed << 6) + (seed >> 2))
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
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);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value_unsigned(T val) {
|
||||
return sprout::hash_detail::hash_value_unsigned_1(
|
||||
val,
|
||||
(std::numeric_limits<T>::digits - 1) / std::numeric_limits<std::size_t>::digits,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value_pointer_1(std::size_t x) {
|
||||
return x + (x >> 3);
|
||||
}
|
||||
template<typename T>
|
||||
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)));
|
||||
}
|
||||
} // namespace hash_detail
|
||||
|
||||
//
|
||||
// hash_value
|
||||
//
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(bool v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(char v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(wchar_t v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned char v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(signed char v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(short v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned short v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(int v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned int v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(long v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long v) {
|
||||
return static_cast<std::size_t>(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(long long v) {
|
||||
return sprout::hash_detail::hash_value_signed(v);
|
||||
}
|
||||
SPROUT_CONSTEXPR inline std::size_t hash_value(unsigned long long v) {
|
||||
return sprout::hash_detail::hash_value_unsigned(v);
|
||||
}
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(T* v) {
|
||||
return sprout::hash_detail::hash_value_pointer(v);
|
||||
}
|
||||
template<typename T, std::size_t N >
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(T const (&v)[N]) {
|
||||
return sprout::hash_range(&v[0], &v[0] + N);
|
||||
}
|
||||
|
||||
//
|
||||
// hash_combine
|
||||
//
|
||||
template<typename T>
|
||||
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));
|
||||
}
|
||||
|
||||
//
|
||||
// hash_range
|
||||
//
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last) {
|
||||
return sprout::hash_range(0, first, last);
|
||||
}
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last) {
|
||||
return first != last
|
||||
? sprout::hash_range(sprout::hash_combine(seed, *first), sprout::next(first), last)
|
||||
: seed
|
||||
;
|
||||
}
|
||||
|
||||
#define SPROUT_HASH_SPECIALIZE(type) \
|
||||
template<> \
|
||||
struct hash<type> { \
|
||||
public: \
|
||||
typedef type argument_type; \
|
||||
typedef std::size_t result_type; \
|
||||
public: \
|
||||
SPROUT_CONSTEXPR std::size_t operator()(type v) const { \
|
||||
return sprout::hash_value(v); \
|
||||
} \
|
||||
}
|
||||
#define SPROUT_HASH_SPECIALIZE_REF(type) \
|
||||
template<> \
|
||||
struct hash<type> { \
|
||||
public: \
|
||||
typedef type argument_type; \
|
||||
typedef std::size_t result_type; \
|
||||
public: \
|
||||
SPROUT_CONSTEXPR std::size_t operator()(type const& v) const { \
|
||||
return sprout::hash_value(v); \
|
||||
} \
|
||||
}
|
||||
|
||||
//
|
||||
// hash
|
||||
//
|
||||
SPROUT_HASH_SPECIALIZE(bool);
|
||||
SPROUT_HASH_SPECIALIZE(char);
|
||||
SPROUT_HASH_SPECIALIZE(wchar_t);
|
||||
SPROUT_HASH_SPECIALIZE(signed char);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned char);
|
||||
SPROUT_HASH_SPECIALIZE(short);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned short);
|
||||
SPROUT_HASH_SPECIALIZE(int);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned int);
|
||||
SPROUT_HASH_SPECIALIZE(long);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned long);
|
||||
SPROUT_HASH_SPECIALIZE(long long);
|
||||
SPROUT_HASH_SPECIALIZE(unsigned long long);
|
||||
|
||||
#undef SPROUT_HASH_SPECIALIZE
|
||||
#undef SPROUT_HASH_SPECIALIZE_REF
|
||||
|
||||
template <class T>
|
||||
struct hash<T*> {
|
||||
public:
|
||||
typedef T* argument_type;
|
||||
typedef std::size_t result_type;
|
||||
public: \
|
||||
SPROUT_CONSTEXPR std::size_t operator()(T* v) const {
|
||||
return sprout::hash_value(v);
|
||||
}
|
||||
};
|
||||
} //namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HPP
|
||||
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
#ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// hash
|
||||
//
|
||||
template<typename T>
|
||||
struct hash;
|
||||
|
||||
//
|
||||
// hash_combine
|
||||
//
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v);
|
||||
|
||||
//
|
||||
// hash_range
|
||||
//
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last);
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last);
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP
|
||||
|
||||
#ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
//
|
||||
// hash
|
||||
//
|
||||
template<typename T>
|
||||
struct hash;
|
||||
|
||||
//
|
||||
// hash_combine
|
||||
//
|
||||
template<typename T>
|
||||
SPROUT_CONSTEXPR std::size_t hash_combine(std::size_t seed, T const& v);
|
||||
|
||||
//
|
||||
// hash_range
|
||||
//
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR std::size_t hash_range(Iterator first, Iterator last);
|
||||
template<typename Iterator>
|
||||
SPROUT_CONSTEXPR std::size_t hash_range(std::size_t seed, Iterator first, Iterator last);
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_HASH_FWD_HPP
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sscrisk/cel/array.hpp>
|
||||
|
||||
namespace sprout {
|
||||
template<typename T, std::size_t N>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::array<T, N> const& v) {
|
||||
return sprout::hash_range(v.begin(), v.end());
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP
|
||||
|
||||
#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sscrisk/cel/array.hpp>
|
||||
|
||||
namespace sprout {
|
||||
template<typename T, std::size_t N>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(sscrisk::cel::array<T, N> const& v) {
|
||||
return sprout::hash_range(v.begin(), v.end());
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_ARRAY_HPP
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sscrisk/cel/utility.hpp>
|
||||
|
||||
namespace sprout {
|
||||
template<typename T1, typename T2>
|
||||
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);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP
|
||||
#ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sscrisk/cel/utility.hpp>
|
||||
|
||||
namespace sprout {
|
||||
template<typename T1, typename T2>
|
||||
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);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SSCRISK_CEL_UTILITY_HPP
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_STRING_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sprout/string.hpp>
|
||||
|
||||
namespace sprout {
|
||||
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) {
|
||||
return sprout::hash_range(v.begin(), v.end());
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP
|
||||
|
||||
#ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_STRING_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sprout/string.hpp>
|
||||
|
||||
namespace sprout {
|
||||
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) {
|
||||
return sprout::hash_range(v.begin(), v.end());
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_STRING_HPP
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sprout/sub_array.hpp>
|
||||
|
||||
namespace sprout {
|
||||
template<typename Container>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(sprout::sub_array<Container> const& v) {
|
||||
return sprout::hash_range(v.begin(), v.end());
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP
|
||||
|
||||
#ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sprout/sub_array.hpp>
|
||||
|
||||
namespace sprout {
|
||||
template<typename Container>
|
||||
SPROUT_CONSTEXPR std::size_t hash_value(sprout::sub_array<Container> const& v) {
|
||||
return sprout::hash_range(v.begin(), v.end());
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_SUB_ARRAY_HPP
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_FWD_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash_fwd.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP
|
||||
|
||||
#ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP
|
||||
#define SPROUT_FUNCTIONAL_HASH_FWD_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash_fwd.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_FUNCTIONAL_HASH_FWD_HPP
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP
|
||||
#define SPROUT_PREPROCESSOR_STRINGIZE_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
#define SPROUT_PP_STRINGIZE_I(text) #text
|
||||
|
||||
//
|
||||
// SPROUT_PP_STRINGIZE
|
||||
//
|
||||
#define SPROUT_PP_STRINGIZE(text) SPROUT_PP_STRINGIZE_I(text)
|
||||
|
||||
#endif // #ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP
|
||||
|
||||
#ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP
|
||||
#define SPROUT_PREPROCESSOR_STRINGIZE_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
#define SPROUT_PP_STRINGIZE_I(text) #text
|
||||
|
||||
//
|
||||
// SPROUT_PP_STRINGIZE
|
||||
//
|
||||
#define SPROUT_PP_STRINGIZE(text) SPROUT_PP_STRINGIZE_I(text)
|
||||
|
||||
#endif // #ifndef SPROUT_PREPROCESSOR_STRINGIZE_HPP
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP
|
||||
#define SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/preprocessor/stringize.hpp>
|
||||
|
||||
//
|
||||
// SPROUT_PP_UNIQUE_STRING
|
||||
//
|
||||
#define SPROUT_PP_UNIQUE_STRING __DATE__ " " __TIME__ " : " __FILE__ "(" SPROUT_PP_STRINGIZE(__LINE__) ")"
|
||||
|
||||
#endif // #ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP
|
||||
|
||||
#ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP
|
||||
#define SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/preprocessor/stringize.hpp>
|
||||
|
||||
//
|
||||
// SPROUT_PP_UNIQUE_STRING
|
||||
//
|
||||
#define SPROUT_PP_UNIQUE_STRING __DATE__ " " __TIME__ " : " __FILE__ "(" SPROUT_PP_STRINGIZE(__LINE__) ")"
|
||||
|
||||
#endif // #ifndef SPROUT_PREPROCESSOR_UNIQUE_STRING_HPP
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#ifndef SPROUT_RANDOM_HPP
|
||||
#define SPROUT_RANDOM_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/linear_congruential.hpp>
|
||||
#include <sprout/random/mersenne_twister.hpp>
|
||||
#include <sprout/random/uniform_smallint.hpp>
|
||||
#include <sprout/random/uniform_int_distribution.hpp>
|
||||
#include <sprout/random/uniform_01.hpp>
|
||||
#include <sprout/random/uniform_real_distribution.hpp>
|
||||
#include <sprout/random/bernoulli_distribution.hpp>
|
||||
#include <sprout/random/binomial_distribution.hpp>
|
||||
#include <sprout/random/variate_generator.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/random/random_iterator.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_HPP
|
||||
#ifndef SPROUT_RANDOM_HPP
|
||||
#define SPROUT_RANDOM_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/linear_congruential.hpp>
|
||||
#include <sprout/random/mersenne_twister.hpp>
|
||||
#include <sprout/random/uniform_smallint.hpp>
|
||||
#include <sprout/random/uniform_int_distribution.hpp>
|
||||
#include <sprout/random/uniform_01.hpp>
|
||||
#include <sprout/random/uniform_real_distribution.hpp>
|
||||
#include <sprout/random/bernoulli_distribution.hpp>
|
||||
#include <sprout/random/binomial_distribution.hpp>
|
||||
#include <sprout/random/variate_generator.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/random/random_iterator.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_HPP
|
||||
|
|
|
@ -1,142 +1,142 @@
|
|||
#ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP
|
||||
#define SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// bernoulli_distribution
|
||||
//
|
||||
template<typename RealType = double>
|
||||
class bernoulli_distribution {
|
||||
public:
|
||||
typedef int input_type;
|
||||
typedef bool result_type;
|
||||
private:
|
||||
static SPROUT_CONSTEXPR RealType arg_check(RealType p_arg) {
|
||||
return p_arg >= 0 && p_arg <= 1
|
||||
? p_arg
|
||||
: throw "assert(p_arg >= 0 && p_arg <= 1)"
|
||||
;
|
||||
}
|
||||
public:
|
||||
//
|
||||
// param_type
|
||||
//
|
||||
class param_type {
|
||||
public:
|
||||
typedef bernoulli_distribution distribution_type;
|
||||
private:
|
||||
RealType p_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR param_type()
|
||||
: p_(RealType(0.5))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit param_type(RealType p_arg = RealType(0.5))
|
||||
: p_(arg_check(p_arg))
|
||||
{}
|
||||
SPROUT_CONSTEXPR RealType p() const {
|
||||
return p_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.p_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
|
||||
return lhs.p_ == rhs.p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
private:
|
||||
RealType p_;
|
||||
private:
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> generate(
|
||||
sprout::random::random_result<Engine> const& rnd
|
||||
) const
|
||||
{
|
||||
return sprout::random::random_result<Engine, bernoulli_distribution>(
|
||||
RealType(rnd.result() - rnd.engine().min()) <= p_ * RealType(rnd.engine().max() - rnd.engine().min()),
|
||||
rnd.engine(),
|
||||
*this
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR bernoulli_distribution()
|
||||
: p_(RealType(0.5))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit bernoulli_distribution(RealType p_arg = RealType(0.5))
|
||||
: p_(arg_check(p_arg))
|
||||
{}
|
||||
SPROUT_CONSTEXPR RealType p() const {
|
||||
return p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return false;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return true;
|
||||
}
|
||||
SPROUT_CONSTEXPR param_type param() const {
|
||||
return param_type(p_);
|
||||
}
|
||||
void param(param_type const& parm) {
|
||||
p_ = parm.p();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> operator()(Engine const& eng) const {
|
||||
return p_ == RealType(0)
|
||||
? sprout::random::random_result<Engine, bernoulli_distribution>(false, eng, *this)
|
||||
: generate(eng())
|
||||
;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
bernoulli_distribution const& rhs
|
||||
)
|
||||
{
|
||||
param_type parm;
|
||||
return lhs >> parm;
|
||||
param(parm);
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
bernoulli_distribution const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) {
|
||||
return lhs.param() == rhs.param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::bernoulli_distribution;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP
|
||||
#define SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// bernoulli_distribution
|
||||
//
|
||||
template<typename RealType = double>
|
||||
class bernoulli_distribution {
|
||||
public:
|
||||
typedef int input_type;
|
||||
typedef bool result_type;
|
||||
private:
|
||||
static SPROUT_CONSTEXPR RealType arg_check(RealType p_arg) {
|
||||
return p_arg >= 0 && p_arg <= 1
|
||||
? p_arg
|
||||
: throw "assert(p_arg >= 0 && p_arg <= 1)"
|
||||
;
|
||||
}
|
||||
public:
|
||||
//
|
||||
// param_type
|
||||
//
|
||||
class param_type {
|
||||
public:
|
||||
typedef bernoulli_distribution distribution_type;
|
||||
private:
|
||||
RealType p_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR param_type()
|
||||
: p_(RealType(0.5))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit param_type(RealType p_arg = RealType(0.5))
|
||||
: p_(arg_check(p_arg))
|
||||
{}
|
||||
SPROUT_CONSTEXPR RealType p() const {
|
||||
return p_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.p_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
|
||||
return lhs.p_ == rhs.p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
private:
|
||||
RealType p_;
|
||||
private:
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> generate(
|
||||
sprout::random::random_result<Engine> const& rnd
|
||||
) const
|
||||
{
|
||||
return sprout::random::random_result<Engine, bernoulli_distribution>(
|
||||
RealType(rnd.result() - rnd.engine().min()) <= p_ * RealType(rnd.engine().max() - rnd.engine().min()),
|
||||
rnd.engine(),
|
||||
*this
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR bernoulli_distribution()
|
||||
: p_(RealType(0.5))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit bernoulli_distribution(RealType p_arg = RealType(0.5))
|
||||
: p_(arg_check(p_arg))
|
||||
{}
|
||||
SPROUT_CONSTEXPR RealType p() const {
|
||||
return p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return false;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return true;
|
||||
}
|
||||
SPROUT_CONSTEXPR param_type param() const {
|
||||
return param_type(p_);
|
||||
}
|
||||
void param(param_type const& parm) {
|
||||
p_ = parm.p();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, bernoulli_distribution> operator()(Engine const& eng) const {
|
||||
return p_ == RealType(0)
|
||||
? sprout::random::random_result<Engine, bernoulli_distribution>(false, eng, *this)
|
||||
: generate(eng())
|
||||
;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
bernoulli_distribution const& rhs
|
||||
)
|
||||
{
|
||||
param_type parm;
|
||||
return lhs >> parm;
|
||||
param(parm);
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
bernoulli_distribution const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) {
|
||||
return lhs.param() == rhs.param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(bernoulli_distribution const& lhs, bernoulli_distribution const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::bernoulli_distribution;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_BERNOULLI_DISTRIBUTION_HPP
|
||||
|
||||
|
|
|
@ -1,425 +1,425 @@
|
|||
#ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP
|
||||
#define SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <istream>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/random/uniform_01.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename RealType>
|
||||
struct binomial_table {
|
||||
public:
|
||||
SPROUT_STATIC_CONSTEXPR sprout::array<RealType, 10> table = sprout::array<RealType, 10>{{
|
||||
0.08106146679532726,
|
||||
0.04134069595540929,
|
||||
0.02767792568499834,
|
||||
0.02079067210376509,
|
||||
0.01664469118982119,
|
||||
0.01387612882307075,
|
||||
0.01189670994589177,
|
||||
0.01041126526197209,
|
||||
0.009255462182712733,
|
||||
0.008330563433362871
|
||||
}};
|
||||
};
|
||||
template<class RealType>
|
||||
SPROUT_CONSTEXPR sprout::array<RealType, 10> sprout::random::detail::binomial_table<RealType>::table;
|
||||
} // namespace detail
|
||||
//
|
||||
// binomial_distribution
|
||||
//
|
||||
template<typename IntType = int, typename RealType = double>
|
||||
class binomial_distribution {
|
||||
public:
|
||||
typedef RealType input_type;
|
||||
typedef IntType result_type;
|
||||
private:
|
||||
struct btrd_type {
|
||||
public:
|
||||
RealType r;
|
||||
RealType nr;
|
||||
RealType npq;
|
||||
RealType b;
|
||||
RealType a;
|
||||
RealType c;
|
||||
RealType alpha;
|
||||
RealType v_r;
|
||||
RealType u_rv_r;
|
||||
};
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType arg_check(IntType t_arg, RealType p_arg) {
|
||||
return t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1)
|
||||
? t_arg
|
||||
: throw "assert(t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1))"
|
||||
;
|
||||
}
|
||||
public:
|
||||
//
|
||||
// param_type
|
||||
//
|
||||
class param_type {
|
||||
public:
|
||||
typedef binomial_distribution distribution_type;
|
||||
private:
|
||||
IntType t_;
|
||||
RealType p_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR param_type()
|
||||
: t_(1)
|
||||
, p_(0.5)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit param_type(IntType t_arg, RealType p_arg = RealType(0.5))
|
||||
: t_(arg_check(t_arg, p_arg))
|
||||
, p_(p_arg)
|
||||
{}
|
||||
SPROUT_CONSTEXPR IntType t() const {
|
||||
return t_;
|
||||
}
|
||||
SPROUT_CONSTEXPR RealType p() const {
|
||||
return p_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.t_ >> std::ws >> rhs.p_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.t_ << " " << rhs.p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
|
||||
return lhs.t_ == rhs.t_ && lhs.p_ == rhs.p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType init_t(IntType t) {
|
||||
return t;
|
||||
}
|
||||
static SPROUT_CONSTEXPR RealType init_p(RealType p) {
|
||||
return RealType(0.5) < p ? 1 - p : p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType init_m(IntType t, RealType p) {
|
||||
return static_cast<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) {
|
||||
return btrd_type {
|
||||
r,
|
||||
nr,
|
||||
npq,
|
||||
b,
|
||||
a,
|
||||
c,
|
||||
alpha,
|
||||
v_r,
|
||||
RealType(0.86) * v_r
|
||||
};
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_5(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType sqrt_npq, RealType b) {
|
||||
return init_btrd_6(t, p, r, nr, npq, b, RealType(-0.0873) + RealType(0.0248) * b + RealType(0.01) * p, t * p + RealType(0.5), (RealType(2.83) + RealType(5.1) / b) * sqrt_npq, RealType(0.92) - RealType(4.2) / b);
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_4(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType sqrt_npq) {
|
||||
return init_btrd_5(t, p, r, nr, npq, sqrt_npq, RealType(1.15) + RealType(2.53) * sqrt_npq);
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_3(IntType t, RealType p, RealType r, RealType nr, RealType npq) {
|
||||
using std::sqrt;
|
||||
return init_btrd_4(t, p, r, nr, npq, sqrt(npq));
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_2(IntType t, RealType p, RealType r) {
|
||||
return init_btrd_3(t, p, r, (t + 1) * r, t * p * (1 - p));
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_1(IntType t, RealType p) {
|
||||
return init_btrd_2(t, p, p / (1 - p));
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd(IntType t, RealType p) {
|
||||
return init_btrd_1(init_t(t), init_p(p));
|
||||
}
|
||||
static SPROUT_CONSTEXPR RealType init_q_n(IntType t, RealType p) {
|
||||
using std::pow;
|
||||
return pow(1 - init_p(p), static_cast<RealType>(init_t(t)));
|
||||
}
|
||||
static SPROUT_CONSTEXPR bool init_use_inversion(IntType t, RealType p) {
|
||||
return init_m(t, p) < 11;
|
||||
}
|
||||
static SPROUT_CONSTEXPR RealType fc_1(RealType ikp1) {
|
||||
return (RealType(1) / 12 - (RealType(1) / 360 - (RealType(1) / 1260) * (ikp1 * ikp1)) * (ikp1 * ikp1)) * ikp1;
|
||||
}
|
||||
static SPROUT_CONSTEXPR RealType fc(IntType k) {
|
||||
return k < 10
|
||||
? sprout::random::detail::binomial_table<RealType>::table[k]
|
||||
: fc_1(RealType(1) / (k + 1))
|
||||
;
|
||||
}
|
||||
private:
|
||||
IntType t_;
|
||||
RealType p_;
|
||||
IntType m_;
|
||||
btrd_type btrd_;
|
||||
RealType q_n_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR bool use_inversion() const {
|
||||
return m_ < 11;
|
||||
}
|
||||
template<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 {
|
||||
return u > r
|
||||
? 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)
|
||||
;
|
||||
}
|
||||
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 {
|
||||
return invert_4(eng, u, q, s, (t + 1) * s, q_n_);
|
||||
}
|
||||
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 {
|
||||
return invert_3(t, eng, u, q, p / q);
|
||||
}
|
||||
template<typename Engine>
|
||||
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);
|
||||
}
|
||||
template<typename Engine, typename Random>
|
||||
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());
|
||||
}
|
||||
template<typename Engine>
|
||||
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));
|
||||
}
|
||||
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 {
|
||||
return sprout::random::random_result<Engine, binomial_distribution>(t - rnd.result(), rnd.engine(), rnd.distribution());
|
||||
}
|
||||
template<typename Engine>
|
||||
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));
|
||||
}
|
||||
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 {
|
||||
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)
|
||||
? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this)
|
||||
: generate(eng)
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_9(Engine const& eng, RealType v, IntType k, IntType nm) const {
|
||||
using std::log;
|
||||
return generate_10(eng, v, k, nm, (m_ + RealType(0.5)) * log((m_ + 1) / (btrd_.r * nm)) + fc(m_) + fc(t_ - m_), t_ - k + 1);
|
||||
}
|
||||
template<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 {
|
||||
return v < t - rho ? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this)
|
||||
: v > t + rho ? generate(eng)
|
||||
: generate_9(eng, v, k, t_ - m_ + 1)
|
||||
;
|
||||
}
|
||||
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 {
|
||||
return v <= f
|
||||
? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this)
|
||||
: generate(eng)
|
||||
;
|
||||
}
|
||||
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 {
|
||||
return i != k
|
||||
? generate_7_2(eng, v * (btrd_.nr / (i + 1) - btrd_.r), k, f, i + 1)
|
||||
: generate_7_3(eng, v, k, f)
|
||||
;
|
||||
}
|
||||
template<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 {
|
||||
return i != k
|
||||
? generate_7_1(eng, v, k, f * (btrd_.nr / (i + 1) - btrd_.r), i + 1)
|
||||
: generate_7_3(eng, v, k, f)
|
||||
;
|
||||
}
|
||||
template<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 {
|
||||
return m_ < k ? generate_7_1(eng, v, k, f * (btrd_.nr / (m_ + 1) - btrd_.r), m_ + 1)
|
||||
: m_ > k ? generate_7_2(eng, v * (btrd_.nr / (k + 1) - btrd_.r), k, f, k + 1)
|
||||
: generate_7_3(eng, v, k, f)
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_6(Engine const& eng, RealType v, IntType k, RealType km) const {
|
||||
using std::log;
|
||||
return km <= 15
|
||||
? generate_7(eng, v, k)
|
||||
: generate_8(eng, log(v), k, (km / btrd_.npq) * (((km / RealType(3.0) + RealType(0.625)) * km + RealType(1.0) / 6) / btrd_.npq + RealType(0.5)), -km * km / (2 * btrd_.npq))
|
||||
;
|
||||
}
|
||||
template<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 {
|
||||
using std::abs;
|
||||
return k < 0 || k > t_
|
||||
? generate(eng)
|
||||
: generate_6(eng, v * btrd_.alpha / (btrd_.a / (us * us) + btrd_.b), k, abs(k - m_))
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_4(Engine const& eng, RealType v, RealType u, RealType us) const {
|
||||
using std::floor;
|
||||
return generate_5(eng, v, u, us, static_cast<IntType>(floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c)));
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_3(Engine const& eng, RealType v, RealType u) const {
|
||||
using std::abs;
|
||||
return generate_4(eng, v, u, 0.5 - abs(u));
|
||||
}
|
||||
template<typename Engine, typename Random>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_2(Random const& rnd, RealType v) const {
|
||||
return v >= btrd_.v_r
|
||||
? generate_3(
|
||||
rnd.engine(),
|
||||
v,
|
||||
rnd.result() - RealType(0.5)
|
||||
)
|
||||
: generate_3(
|
||||
rnd.engine(),
|
||||
rnd.result() * btrd_.v_r,
|
||||
((v / btrd_.v_r - RealType(0.93)) < 0 ? RealType(-0.5) : RealType(0.5)) - (v / btrd_.v_r - RealType(0.93))
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_1_1(Engine const& eng, RealType u) const {
|
||||
using std::floor;
|
||||
using std::abs;
|
||||
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)),
|
||||
eng,
|
||||
*this
|
||||
);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_1(Engine const& eng, RealType v) const {
|
||||
return v <= btrd_.u_rv_r
|
||||
? generate_1_1(eng, v / btrd_.v_r - RealType(0.43))
|
||||
: generate_2<Engine>(sprout::random::uniform_01<RealType>()(eng), v)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename Random>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_0(Random const& rnd) const {
|
||||
return generate_1(rnd.engine(), rnd.result());
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate(Engine const& eng) const {
|
||||
return generate_0<Engine>(sprout::random::uniform_01<RealType>()(eng));
|
||||
}
|
||||
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 {
|
||||
return sprout::random::random_result<Engine, binomial_distribution>(t - rnd.result(), rnd.engine(), rnd.distribution());
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate2(IntType t, Engine const& eng) const {
|
||||
return generate2_0<Engine>(t, generate(eng));
|
||||
}
|
||||
void init() {
|
||||
m_ = init_m(t_, p_);
|
||||
if (use_inversion()) {
|
||||
q_n_ = init_q_n(t_, p_);
|
||||
} else {
|
||||
btrd_ = init_btrd(t_, p_);
|
||||
}
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR binomial_distribution()
|
||||
: t_(1)
|
||||
, p_(RealType(0.5))
|
||||
, m_(init_m(1, RealType(0.5)))
|
||||
, btrd_(!init_use_inversion(1, RealType(0.5)) ? init_btrd(1, RealType(0.5)) : btrd_type())
|
||||
, q_n_(init_use_inversion(1, RealType(0.5)) ? init_q_n(1, RealType(0.5)) : RealType())
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit binomial_distribution(IntType t_arg, RealType p_arg = RealType(0.5))
|
||||
: t_(arg_check(t_arg, p_arg))
|
||||
, p_(p_arg)
|
||||
, m_(init_m(t_arg, p_arg))
|
||||
, btrd_(!init_use_inversion(t_arg, p_arg) ? init_btrd(t_arg, p_arg) : btrd_type())
|
||||
, q_n_(init_use_inversion(t_arg, p_arg) ? init_q_n(t_arg, p_arg) : RealType())
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit binomial_distribution(param_type const& parm)
|
||||
: t_(parm.t())
|
||||
, p_(parm.p())
|
||||
, m_(init_m(parm.t(), parm.p()))
|
||||
, btrd_(!init_use_inversion(parm.t(), parm.p()) ? init_btrd(parm.t(), parm.p()) : btrd_type())
|
||||
, q_n_(init_use_inversion(parm.t(), parm.p()) ? init_q_n(parm.t(), parm.p()) : RealType())
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type t() const {
|
||||
return t_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type p() const {
|
||||
return p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return 0;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return t_;
|
||||
}
|
||||
SPROUT_CONSTEXPR param_type param() const {
|
||||
return param_type(t_, p_);
|
||||
}
|
||||
void param(param_type const& parm) {
|
||||
t_ = parm.a();
|
||||
p_ = parm.b();
|
||||
init();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> operator()(Engine const& eng) const {
|
||||
return use_inversion() ? RealType(0.5) < p_
|
||||
? invert2(t_, 1 - p_, eng)
|
||||
: invert(t_, p_, eng)
|
||||
: RealType(0.5) < p_ ? generate2(t_, eng)
|
||||
: generate(eng)
|
||||
;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
binomial_distribution const& rhs
|
||||
)
|
||||
{
|
||||
param_type parm;
|
||||
return lhs >> parm;
|
||||
param(parm);
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
binomial_distribution const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(binomial_distribution const& lhs, binomial_distribution const& rhs) {
|
||||
return lhs.param() == rhs.param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(binomial_distribution const& lhs, binomial_distribution const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::binomial_distribution;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP
|
||||
#define SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <istream>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/random/uniform_01.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename RealType>
|
||||
struct binomial_table {
|
||||
public:
|
||||
SPROUT_STATIC_CONSTEXPR sprout::array<RealType, 10> table = sprout::array<RealType, 10>{{
|
||||
0.08106146679532726,
|
||||
0.04134069595540929,
|
||||
0.02767792568499834,
|
||||
0.02079067210376509,
|
||||
0.01664469118982119,
|
||||
0.01387612882307075,
|
||||
0.01189670994589177,
|
||||
0.01041126526197209,
|
||||
0.009255462182712733,
|
||||
0.008330563433362871
|
||||
}};
|
||||
};
|
||||
template<class RealType>
|
||||
SPROUT_CONSTEXPR sprout::array<RealType, 10> sprout::random::detail::binomial_table<RealType>::table;
|
||||
} // namespace detail
|
||||
//
|
||||
// binomial_distribution
|
||||
//
|
||||
template<typename IntType = int, typename RealType = double>
|
||||
class binomial_distribution {
|
||||
public:
|
||||
typedef RealType input_type;
|
||||
typedef IntType result_type;
|
||||
private:
|
||||
struct btrd_type {
|
||||
public:
|
||||
RealType r;
|
||||
RealType nr;
|
||||
RealType npq;
|
||||
RealType b;
|
||||
RealType a;
|
||||
RealType c;
|
||||
RealType alpha;
|
||||
RealType v_r;
|
||||
RealType u_rv_r;
|
||||
};
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType arg_check(IntType t_arg, RealType p_arg) {
|
||||
return t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1)
|
||||
? t_arg
|
||||
: throw "assert(t_arg >= IntType(0) && RealType(0) <= p_arg && p_arg <= RealType(1))"
|
||||
;
|
||||
}
|
||||
public:
|
||||
//
|
||||
// param_type
|
||||
//
|
||||
class param_type {
|
||||
public:
|
||||
typedef binomial_distribution distribution_type;
|
||||
private:
|
||||
IntType t_;
|
||||
RealType p_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR param_type()
|
||||
: t_(1)
|
||||
, p_(0.5)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit param_type(IntType t_arg, RealType p_arg = RealType(0.5))
|
||||
: t_(arg_check(t_arg, p_arg))
|
||||
, p_(p_arg)
|
||||
{}
|
||||
SPROUT_CONSTEXPR IntType t() const {
|
||||
return t_;
|
||||
}
|
||||
SPROUT_CONSTEXPR RealType p() const {
|
||||
return p_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.t_ >> std::ws >> rhs.p_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.t_ << " " << rhs.p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
|
||||
return lhs.t_ == rhs.t_ && lhs.p_ == rhs.p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType init_t(IntType t) {
|
||||
return t;
|
||||
}
|
||||
static SPROUT_CONSTEXPR RealType init_p(RealType p) {
|
||||
return RealType(0.5) < p ? 1 - p : p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType init_m(IntType t, RealType p) {
|
||||
return static_cast<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) {
|
||||
return btrd_type {
|
||||
r,
|
||||
nr,
|
||||
npq,
|
||||
b,
|
||||
a,
|
||||
c,
|
||||
alpha,
|
||||
v_r,
|
||||
RealType(0.86) * v_r
|
||||
};
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_5(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType sqrt_npq, RealType b) {
|
||||
return init_btrd_6(t, p, r, nr, npq, b, RealType(-0.0873) + RealType(0.0248) * b + RealType(0.01) * p, t * p + RealType(0.5), (RealType(2.83) + RealType(5.1) / b) * sqrt_npq, RealType(0.92) - RealType(4.2) / b);
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_4(IntType t, RealType p, RealType r, RealType nr, RealType npq, RealType sqrt_npq) {
|
||||
return init_btrd_5(t, p, r, nr, npq, sqrt_npq, RealType(1.15) + RealType(2.53) * sqrt_npq);
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_3(IntType t, RealType p, RealType r, RealType nr, RealType npq) {
|
||||
using std::sqrt;
|
||||
return init_btrd_4(t, p, r, nr, npq, sqrt(npq));
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_2(IntType t, RealType p, RealType r) {
|
||||
return init_btrd_3(t, p, r, (t + 1) * r, t * p * (1 - p));
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd_1(IntType t, RealType p) {
|
||||
return init_btrd_2(t, p, p / (1 - p));
|
||||
}
|
||||
static SPROUT_CONSTEXPR btrd_type init_btrd(IntType t, RealType p) {
|
||||
return init_btrd_1(init_t(t), init_p(p));
|
||||
}
|
||||
static SPROUT_CONSTEXPR RealType init_q_n(IntType t, RealType p) {
|
||||
using std::pow;
|
||||
return pow(1 - init_p(p), static_cast<RealType>(init_t(t)));
|
||||
}
|
||||
static SPROUT_CONSTEXPR bool init_use_inversion(IntType t, RealType p) {
|
||||
return init_m(t, p) < 11;
|
||||
}
|
||||
static SPROUT_CONSTEXPR RealType fc_1(RealType ikp1) {
|
||||
return (RealType(1) / 12 - (RealType(1) / 360 - (RealType(1) / 1260) * (ikp1 * ikp1)) * (ikp1 * ikp1)) * ikp1;
|
||||
}
|
||||
static SPROUT_CONSTEXPR RealType fc(IntType k) {
|
||||
return k < 10
|
||||
? sprout::random::detail::binomial_table<RealType>::table[k]
|
||||
: fc_1(RealType(1) / (k + 1))
|
||||
;
|
||||
}
|
||||
private:
|
||||
IntType t_;
|
||||
RealType p_;
|
||||
IntType m_;
|
||||
btrd_type btrd_;
|
||||
RealType q_n_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR bool use_inversion() const {
|
||||
return m_ < 11;
|
||||
}
|
||||
template<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 {
|
||||
return u > r
|
||||
? 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)
|
||||
;
|
||||
}
|
||||
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 {
|
||||
return invert_4(eng, u, q, s, (t + 1) * s, q_n_);
|
||||
}
|
||||
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 {
|
||||
return invert_3(t, eng, u, q, p / q);
|
||||
}
|
||||
template<typename Engine>
|
||||
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);
|
||||
}
|
||||
template<typename Engine, typename Random>
|
||||
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());
|
||||
}
|
||||
template<typename Engine>
|
||||
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));
|
||||
}
|
||||
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 {
|
||||
return sprout::random::random_result<Engine, binomial_distribution>(t - rnd.result(), rnd.engine(), rnd.distribution());
|
||||
}
|
||||
template<typename Engine>
|
||||
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));
|
||||
}
|
||||
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 {
|
||||
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)
|
||||
? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this)
|
||||
: generate(eng)
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_9(Engine const& eng, RealType v, IntType k, IntType nm) const {
|
||||
using std::log;
|
||||
return generate_10(eng, v, k, nm, (m_ + RealType(0.5)) * log((m_ + 1) / (btrd_.r * nm)) + fc(m_) + fc(t_ - m_), t_ - k + 1);
|
||||
}
|
||||
template<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 {
|
||||
return v < t - rho ? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this)
|
||||
: v > t + rho ? generate(eng)
|
||||
: generate_9(eng, v, k, t_ - m_ + 1)
|
||||
;
|
||||
}
|
||||
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 {
|
||||
return v <= f
|
||||
? sprout::random::random_result<Engine, binomial_distribution>(k, eng, *this)
|
||||
: generate(eng)
|
||||
;
|
||||
}
|
||||
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 {
|
||||
return i != k
|
||||
? generate_7_2(eng, v * (btrd_.nr / (i + 1) - btrd_.r), k, f, i + 1)
|
||||
: generate_7_3(eng, v, k, f)
|
||||
;
|
||||
}
|
||||
template<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 {
|
||||
return i != k
|
||||
? generate_7_1(eng, v, k, f * (btrd_.nr / (i + 1) - btrd_.r), i + 1)
|
||||
: generate_7_3(eng, v, k, f)
|
||||
;
|
||||
}
|
||||
template<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 {
|
||||
return m_ < k ? generate_7_1(eng, v, k, f * (btrd_.nr / (m_ + 1) - btrd_.r), m_ + 1)
|
||||
: m_ > k ? generate_7_2(eng, v * (btrd_.nr / (k + 1) - btrd_.r), k, f, k + 1)
|
||||
: generate_7_3(eng, v, k, f)
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_6(Engine const& eng, RealType v, IntType k, RealType km) const {
|
||||
using std::log;
|
||||
return km <= 15
|
||||
? generate_7(eng, v, k)
|
||||
: generate_8(eng, log(v), k, (km / btrd_.npq) * (((km / RealType(3.0) + RealType(0.625)) * km + RealType(1.0) / 6) / btrd_.npq + RealType(0.5)), -km * km / (2 * btrd_.npq))
|
||||
;
|
||||
}
|
||||
template<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 {
|
||||
using std::abs;
|
||||
return k < 0 || k > t_
|
||||
? generate(eng)
|
||||
: generate_6(eng, v * btrd_.alpha / (btrd_.a / (us * us) + btrd_.b), k, abs(k - m_))
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_4(Engine const& eng, RealType v, RealType u, RealType us) const {
|
||||
using std::floor;
|
||||
return generate_5(eng, v, u, us, static_cast<IntType>(floor((2 * btrd_.a / us + btrd_.b) * u + btrd_.c)));
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_3(Engine const& eng, RealType v, RealType u) const {
|
||||
using std::abs;
|
||||
return generate_4(eng, v, u, 0.5 - abs(u));
|
||||
}
|
||||
template<typename Engine, typename Random>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_2(Random const& rnd, RealType v) const {
|
||||
return v >= btrd_.v_r
|
||||
? generate_3(
|
||||
rnd.engine(),
|
||||
v,
|
||||
rnd.result() - RealType(0.5)
|
||||
)
|
||||
: generate_3(
|
||||
rnd.engine(),
|
||||
rnd.result() * btrd_.v_r,
|
||||
((v / btrd_.v_r - RealType(0.93)) < 0 ? RealType(-0.5) : RealType(0.5)) - (v / btrd_.v_r - RealType(0.93))
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_1_1(Engine const& eng, RealType u) const {
|
||||
using std::floor;
|
||||
using std::abs;
|
||||
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)),
|
||||
eng,
|
||||
*this
|
||||
);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_1(Engine const& eng, RealType v) const {
|
||||
return v <= btrd_.u_rv_r
|
||||
? generate_1_1(eng, v / btrd_.v_r - RealType(0.43))
|
||||
: generate_2<Engine>(sprout::random::uniform_01<RealType>()(eng), v)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename Random>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate_0(Random const& rnd) const {
|
||||
return generate_1(rnd.engine(), rnd.result());
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate(Engine const& eng) const {
|
||||
return generate_0<Engine>(sprout::random::uniform_01<RealType>()(eng));
|
||||
}
|
||||
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 {
|
||||
return sprout::random::random_result<Engine, binomial_distribution>(t - rnd.result(), rnd.engine(), rnd.distribution());
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> generate2(IntType t, Engine const& eng) const {
|
||||
return generate2_0<Engine>(t, generate(eng));
|
||||
}
|
||||
void init() {
|
||||
m_ = init_m(t_, p_);
|
||||
if (use_inversion()) {
|
||||
q_n_ = init_q_n(t_, p_);
|
||||
} else {
|
||||
btrd_ = init_btrd(t_, p_);
|
||||
}
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR binomial_distribution()
|
||||
: t_(1)
|
||||
, p_(RealType(0.5))
|
||||
, m_(init_m(1, RealType(0.5)))
|
||||
, btrd_(!init_use_inversion(1, RealType(0.5)) ? init_btrd(1, RealType(0.5)) : btrd_type())
|
||||
, q_n_(init_use_inversion(1, RealType(0.5)) ? init_q_n(1, RealType(0.5)) : RealType())
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit binomial_distribution(IntType t_arg, RealType p_arg = RealType(0.5))
|
||||
: t_(arg_check(t_arg, p_arg))
|
||||
, p_(p_arg)
|
||||
, m_(init_m(t_arg, p_arg))
|
||||
, btrd_(!init_use_inversion(t_arg, p_arg) ? init_btrd(t_arg, p_arg) : btrd_type())
|
||||
, q_n_(init_use_inversion(t_arg, p_arg) ? init_q_n(t_arg, p_arg) : RealType())
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit binomial_distribution(param_type const& parm)
|
||||
: t_(parm.t())
|
||||
, p_(parm.p())
|
||||
, m_(init_m(parm.t(), parm.p()))
|
||||
, btrd_(!init_use_inversion(parm.t(), parm.p()) ? init_btrd(parm.t(), parm.p()) : btrd_type())
|
||||
, q_n_(init_use_inversion(parm.t(), parm.p()) ? init_q_n(parm.t(), parm.p()) : RealType())
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type t() const {
|
||||
return t_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type p() const {
|
||||
return p_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return 0;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return t_;
|
||||
}
|
||||
SPROUT_CONSTEXPR param_type param() const {
|
||||
return param_type(t_, p_);
|
||||
}
|
||||
void param(param_type const& parm) {
|
||||
t_ = parm.a();
|
||||
p_ = parm.b();
|
||||
init();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, binomial_distribution> operator()(Engine const& eng) const {
|
||||
return use_inversion() ? RealType(0.5) < p_
|
||||
? invert2(t_, 1 - p_, eng)
|
||||
: invert(t_, p_, eng)
|
||||
: RealType(0.5) < p_ ? generate2(t_, eng)
|
||||
: generate(eng)
|
||||
;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
binomial_distribution const& rhs
|
||||
)
|
||||
{
|
||||
param_type parm;
|
||||
return lhs >> parm;
|
||||
param(parm);
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
binomial_distribution const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(binomial_distribution const& lhs, binomial_distribution const& rhs) {
|
||||
return lhs.param() == rhs.param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(binomial_distribution const& lhs, binomial_distribution const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::binomial_distribution;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_BINOMIAL_DISTRIBUTION_HPP
|
||||
|
||||
|
|
|
@ -1,132 +1,132 @@
|
|||
#ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP
|
||||
#define SPROUT_RANDOM_DETAIL_CONST_MOD_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename IntType, IntType m>
|
||||
class const_mod {
|
||||
private:
|
||||
typedef typename std::make_unsigned<IntType>::type unsigned_type;
|
||||
private:
|
||||
SPROUT_STATIC_CONSTEXPR IntType suppress_warnings = m == 0;
|
||||
SPROUT_STATIC_CONSTEXPR IntType modulus = m + suppress_warnings;
|
||||
private:
|
||||
static_assert(suppress_warnings == 0, "suppress_warnings == 0");
|
||||
static_assert(modulus == m, "modulus == m");
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType pow_1(IntType a, std::uintmax_t exponent, IntType result = 1) {
|
||||
return exponent != 0
|
||||
? pow_1(mult(a, a), exponent / 2, exponent % 2 == 1 ? mult(result, a) : result)
|
||||
: result
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_small(IntType a, IntType x) {
|
||||
return a * x % (m + suppress_warnings);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_schrage_1(IntType a, IntType value, IntType q, IntType r) {
|
||||
return r < q
|
||||
? sub(a * (value % q), r * (value / q))
|
||||
: throw "assert(r < q)"
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_schrage(IntType a, IntType value) {
|
||||
return mult_schrage_1(a, value, m / a, m % a);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_general(IntType a, IntType b) {
|
||||
return std::uintmax_t(modulus) <= std::numeric_limits<std::uintmax_t>::max() / 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 SPROUT_CONSTEXPR IntType sub(IntType a, IntType b) {
|
||||
return a < b ? m - (b - a) : a - b;
|
||||
}
|
||||
static SPROUT_CONSTEXPR unsigned_type unsigned_m() {
|
||||
return m == 0 ? unsigned_type((std::numeric_limits<IntType>::max)()) + 1 : unsigned_type(m);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return n == 0 ? m - l1 : invert_euclidian_1(c, l1, l2, n, p);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return p == 0 ? l2 : invert_euclidian_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return invert_euclidian_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) {
|
||||
return c > 0
|
||||
? c == 1 ? 1 : invert_euclidian_1(c, 0, 1, c, m)
|
||||
: throw "assert(c > 0)"
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian0_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return n == 0 ? m - l1 : invert_euclidian0_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian0_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return p == 0 ? l2 : invert_euclidian0_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return std::numeric_limits<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)"
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian0(IntType c) {
|
||||
return c > 0
|
||||
? c == 1 ? 1 : invert_euclidian0_1(c, 0, 1, c, m)
|
||||
: throw "assert(c > 0)"
|
||||
;
|
||||
}
|
||||
public:
|
||||
static SPROUT_CONSTEXPR IntType apply(IntType x) {
|
||||
return ((unsigned_m() - 1) & unsigned_m()) == 0
|
||||
? (unsigned_type(x)) & (unsigned_m() - 1)
|
||||
: x % (m + suppress_warnings)
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType add(IntType x, IntType c) {
|
||||
return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1)
|
||||
: c == 0 ? x
|
||||
: x < m - c ? x + c
|
||||
: x - (m - c)
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult(IntType a, IntType x) {
|
||||
return ((unsigned_m() - 1) & unsigned_m()) == 0 ? unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1)
|
||||
: a == 0 ? 0
|
||||
: a == 1 ? x
|
||||
: m <= std::numeric_limits<IntType>::max() / a ? mult_small(a, x)
|
||||
: std::numeric_limits<IntType>::is_signed && (m % a < m / a) ? mult_schrage(a, x)
|
||||
: mult_general(a, x)
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_add(IntType a, IntType x, IntType c) {
|
||||
return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1)
|
||||
: a == 0 ? c
|
||||
: m <= (std::numeric_limits<IntType>::max() - c) / a ? (a * x + c) % (m + suppress_warnings)
|
||||
: add(mult(a, x), c)
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType pow(IntType a, std::uintmax_t exponent) {
|
||||
return pow_1(a, exponent);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert(IntType x) {
|
||||
return x == 0 ? 0
|
||||
: m == 0 ? invert_euclidian0(x)
|
||||
: invert_euclidian(x)
|
||||
;
|
||||
}
|
||||
private:
|
||||
const_mod() = delete;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace random
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP
|
||||
#define SPROUT_RANDOM_DETAIL_CONST_MOD_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename IntType, IntType m>
|
||||
class const_mod {
|
||||
private:
|
||||
typedef typename std::make_unsigned<IntType>::type unsigned_type;
|
||||
private:
|
||||
SPROUT_STATIC_CONSTEXPR IntType suppress_warnings = m == 0;
|
||||
SPROUT_STATIC_CONSTEXPR IntType modulus = m + suppress_warnings;
|
||||
private:
|
||||
static_assert(suppress_warnings == 0, "suppress_warnings == 0");
|
||||
static_assert(modulus == m, "modulus == m");
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType pow_1(IntType a, std::uintmax_t exponent, IntType result = 1) {
|
||||
return exponent != 0
|
||||
? pow_1(mult(a, a), exponent / 2, exponent % 2 == 1 ? mult(result, a) : result)
|
||||
: result
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_small(IntType a, IntType x) {
|
||||
return a * x % (m + suppress_warnings);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_schrage_1(IntType a, IntType value, IntType q, IntType r) {
|
||||
return r < q
|
||||
? sub(a * (value % q), r * (value / q))
|
||||
: throw "assert(r < q)"
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_schrage(IntType a, IntType value) {
|
||||
return mult_schrage_1(a, value, m / a, m % a);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_general(IntType a, IntType b) {
|
||||
return std::uintmax_t(modulus) <= std::numeric_limits<std::uintmax_t>::max() / 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 SPROUT_CONSTEXPR IntType sub(IntType a, IntType b) {
|
||||
return a < b ? m - (b - a) : a - b;
|
||||
}
|
||||
static SPROUT_CONSTEXPR unsigned_type unsigned_m() {
|
||||
return m == 0 ? unsigned_type((std::numeric_limits<IntType>::max)()) + 1 : unsigned_type(m);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return n == 0 ? m - l1 : invert_euclidian_1(c, l1, l2, n, p);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return p == 0 ? l2 : invert_euclidian_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return invert_euclidian_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian(IntType c) {
|
||||
return c > 0
|
||||
? c == 1 ? 1 : invert_euclidian_1(c, 0, 1, c, m)
|
||||
: throw "assert(c > 0)"
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian0_3(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return n == 0 ? m - l1 : invert_euclidian0_2(c, l1 + (p / n) * l2, l2, n, p - (p / n) * n);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian0_2(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return p == 0 ? l2 : invert_euclidian0_3(c, l1, l2 + (n / p) * l1, n - (n / p) * p, p);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian0_1(IntType c, IntType l1, IntType l2, IntType n, IntType p) {
|
||||
return std::numeric_limits<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)"
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert_euclidian0(IntType c) {
|
||||
return c > 0
|
||||
? c == 1 ? 1 : invert_euclidian0_1(c, 0, 1, c, m)
|
||||
: throw "assert(c > 0)"
|
||||
;
|
||||
}
|
||||
public:
|
||||
static SPROUT_CONSTEXPR IntType apply(IntType x) {
|
||||
return ((unsigned_m() - 1) & unsigned_m()) == 0
|
||||
? (unsigned_type(x)) & (unsigned_m() - 1)
|
||||
: x % (m + suppress_warnings)
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType add(IntType x, IntType c) {
|
||||
return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1)
|
||||
: c == 0 ? x
|
||||
: x < m - c ? x + c
|
||||
: x - (m - c)
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult(IntType a, IntType x) {
|
||||
return ((unsigned_m() - 1) & unsigned_m()) == 0 ? unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1)
|
||||
: a == 0 ? 0
|
||||
: a == 1 ? x
|
||||
: m <= std::numeric_limits<IntType>::max() / a ? mult_small(a, x)
|
||||
: std::numeric_limits<IntType>::is_signed && (m % a < m / a) ? mult_schrage(a, x)
|
||||
: mult_general(a, x)
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType mult_add(IntType a, IntType x, IntType c) {
|
||||
return ((unsigned_m() - 1) & unsigned_m()) == 0 ? (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1)
|
||||
: a == 0 ? c
|
||||
: m <= (std::numeric_limits<IntType>::max() - c) / a ? (a * x + c) % (m + suppress_warnings)
|
||||
: add(mult(a, x), c)
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType pow(IntType a, std::uintmax_t exponent) {
|
||||
return pow_1(a, exponent);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType invert(IntType x) {
|
||||
return x == 0 ? 0
|
||||
: m == 0 ? invert_euclidian0(x)
|
||||
: invert_euclidian(x)
|
||||
;
|
||||
}
|
||||
private:
|
||||
const_mod() = delete;
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace random
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_DETAIL_CONST_MOD_HPP
|
||||
|
||||
|
|
|
@ -1,73 +1,73 @@
|
|||
#ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP
|
||||
#define SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct ptr_helper {
|
||||
typedef T value_type;
|
||||
typedef T& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T const& rvalue_type;
|
||||
static reference_type ref(T& r) {
|
||||
return r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const& r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct ptr_helper<T&> {
|
||||
typedef T value_type;
|
||||
typedef T& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T& rvalue_type;
|
||||
static reference_type ref(T& r) {
|
||||
return r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const& r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct ptr_helper<T const&> {
|
||||
typedef T value_type;
|
||||
typedef T const& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T const& rvalue_type;
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const& r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct ptr_helper<T*> {
|
||||
typedef T value_type;
|
||||
typedef T& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T* rvalue_type;
|
||||
static reference_type ref(T* p) {
|
||||
return *p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const* p) {
|
||||
return *p;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct ptr_helper<T const*> {
|
||||
typedef T value_type;
|
||||
typedef T const& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T const* rvalue_type;
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const* p) {
|
||||
return *p;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace random
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP
|
||||
#define SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct ptr_helper {
|
||||
typedef T value_type;
|
||||
typedef T& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T const& rvalue_type;
|
||||
static reference_type ref(T& r) {
|
||||
return r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const& r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct ptr_helper<T&> {
|
||||
typedef T value_type;
|
||||
typedef T& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T& rvalue_type;
|
||||
static reference_type ref(T& r) {
|
||||
return r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const& r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct ptr_helper<T const&> {
|
||||
typedef T value_type;
|
||||
typedef T const& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T const& rvalue_type;
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const& r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct ptr_helper<T*> {
|
||||
typedef T value_type;
|
||||
typedef T& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T* rvalue_type;
|
||||
static reference_type ref(T* p) {
|
||||
return *p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const* p) {
|
||||
return *p;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct ptr_helper<T const*> {
|
||||
typedef T value_type;
|
||||
typedef T const& reference_type;
|
||||
typedef T const& const_reference_type;
|
||||
typedef T const* rvalue_type;
|
||||
static SPROUT_CONSTEXPR const_reference_type ref(T const* p) {
|
||||
return *p;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace random
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_DETAIL_PTR_HELPER_HPP
|
||||
|
||||
|
|
|
@ -1,63 +1,63 @@
|
|||
#ifndef SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP
|
||||
#define SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename T, bool B = std::numeric_limits<T>::is_signed>
|
||||
struct subtract {};
|
||||
template<typename T>
|
||||
struct subtract<T, false> {
|
||||
public:
|
||||
typedef T result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type operator()(T x, T y) const {
|
||||
return x - y;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct subtract<T, true> {
|
||||
public:
|
||||
typedef typename std::make_unsigned<T>::type result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type operator()(T x, T y) const {
|
||||
return y >= 0 ? result_type(x) - result_type(y)
|
||||
: x >= 0 ? result_type(x) + result_type(-(y + 1)) + 1
|
||||
: result_type(x - y)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, bool B = std::numeric_limits<T2>::is_signed>
|
||||
struct add {};
|
||||
template<typename T1, typename T2>
|
||||
struct add<T1, T2, false> {
|
||||
public:
|
||||
typedef T2 result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const {
|
||||
return T2(x) + y;
|
||||
}
|
||||
};
|
||||
template<typename T1, typename T2>
|
||||
struct add<T1, T2, true> {
|
||||
public:
|
||||
typedef T2 result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const {
|
||||
return y >= 0 ? T2(x) + y
|
||||
: x >= T1(-(y + 1)) ? T2(x - T1(-(y + 1)) - 1)
|
||||
: T2(x) + y
|
||||
;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace random
|
||||
} // namespace sprout
|
||||
|
||||
#endif // SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP
|
||||
#define SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename T, bool B = std::numeric_limits<T>::is_signed>
|
||||
struct subtract {};
|
||||
template<typename T>
|
||||
struct subtract<T, false> {
|
||||
public:
|
||||
typedef T result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type operator()(T x, T y) const {
|
||||
return x - y;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct subtract<T, true> {
|
||||
public:
|
||||
typedef typename std::make_unsigned<T>::type result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type operator()(T x, T y) const {
|
||||
return y >= 0 ? result_type(x) - result_type(y)
|
||||
: x >= 0 ? result_type(x) + result_type(-(y + 1)) + 1
|
||||
: result_type(x - y)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T1, typename T2, bool B = std::numeric_limits<T2>::is_signed>
|
||||
struct add {};
|
||||
template<typename T1, typename T2>
|
||||
struct add<T1, T2, false> {
|
||||
public:
|
||||
typedef T2 result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const {
|
||||
return T2(x) + y;
|
||||
}
|
||||
};
|
||||
template<typename T1, typename T2>
|
||||
struct add<T1, T2, true> {
|
||||
public:
|
||||
typedef T2 result_type;
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type operator()(T1 x, T2 y) const {
|
||||
return y >= 0 ? T2(x) + y
|
||||
: x >= T1(-(y + 1)) ? T2(x - T1(-(y + 1)) - 1)
|
||||
: T2(x) + y
|
||||
;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace random
|
||||
} // namespace sprout
|
||||
|
||||
#endif // SPROUT_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS_HPP
|
||||
|
||||
|
|
|
@ -1,74 +1,74 @@
|
|||
#ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
|
||||
#define SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/random/detail/generator_bits.hpp>
|
||||
#include <sprout/detail/integer.hpp>
|
||||
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT_DETAIL
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<class URNG>
|
||||
class uniform_int_float {
|
||||
public:
|
||||
typedef URNG base_type;
|
||||
typedef typename base_type::result_type base_result;
|
||||
typedef typename sprout::detail::uint_t<
|
||||
(std::numeric_limits<std::uintmax_t>::digits < std::numeric_limits<base_result>::digits)
|
||||
? std::numeric_limits<std::uintmax_t>::digits
|
||||
: std::numeric_limits<base_result>::digits
|
||||
>::fast result_type;
|
||||
private:
|
||||
base_type rng_;
|
||||
public:
|
||||
//uniform_int_float = default; // ???
|
||||
SPROUT_CONSTEXPR uniform_int_float()
|
||||
: rng_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit uniform_int_float(base_type const& rng)
|
||||
: rng_(rng)
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return 0;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return (
|
||||
result_type(2) << (
|
||||
NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(
|
||||
std::numeric_limits<result_type>::digits,
|
||||
sprout::random::detail::generator_bits<base_type>::value()
|
||||
) - 1
|
||||
)
|
||||
) - 1
|
||||
;
|
||||
}
|
||||
base_type& base() {
|
||||
return rng_;
|
||||
}
|
||||
SPROUT_CONSTEXPR base_type const& base() const {
|
||||
return rng_;
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> generate(
|
||||
sprout::random::random_result<base_type> const& rnd
|
||||
) const
|
||||
{
|
||||
return sprout::random::random_result<uniform_int_float>(
|
||||
static_cast<result_type>(rnd.result() * (static_cast<base_result>(max()) + 1)),
|
||||
uniform_int_float(rnd.engine())
|
||||
);
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> operator()() const {
|
||||
return generate(rng_());
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace random
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
|
||||
#define SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/random/detail/generator_bits.hpp>
|
||||
#include <sprout/detail/integer.hpp>
|
||||
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT_DETAIL
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<class URNG>
|
||||
class uniform_int_float {
|
||||
public:
|
||||
typedef URNG base_type;
|
||||
typedef typename base_type::result_type base_result;
|
||||
typedef typename sprout::detail::uint_t<
|
||||
(std::numeric_limits<std::uintmax_t>::digits < std::numeric_limits<base_result>::digits)
|
||||
? std::numeric_limits<std::uintmax_t>::digits
|
||||
: std::numeric_limits<base_result>::digits
|
||||
>::fast result_type;
|
||||
private:
|
||||
base_type rng_;
|
||||
public:
|
||||
//uniform_int_float = default; // ???
|
||||
SPROUT_CONSTEXPR uniform_int_float()
|
||||
: rng_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit uniform_int_float(base_type const& rng)
|
||||
: rng_(rng)
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return 0;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return (
|
||||
result_type(2) << (
|
||||
NS_SSCRISK_CEL_OR_SPROUT_DETAIL::min(
|
||||
std::numeric_limits<result_type>::digits,
|
||||
sprout::random::detail::generator_bits<base_type>::value()
|
||||
) - 1
|
||||
)
|
||||
) - 1
|
||||
;
|
||||
}
|
||||
base_type& base() {
|
||||
return rng_;
|
||||
}
|
||||
SPROUT_CONSTEXPR base_type const& base() const {
|
||||
return rng_;
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> generate(
|
||||
sprout::random::random_result<base_type> const& rnd
|
||||
) const
|
||||
{
|
||||
return sprout::random::random_result<uniform_int_float>(
|
||||
static_cast<result_type>(rnd.result() * (static_cast<base_result>(max()) + 1)),
|
||||
uniform_int_float(rnd.engine())
|
||||
);
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<uniform_int_float> operator()() const {
|
||||
return generate(rng_());
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace random
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_DETAIL_UNIFORM_INT_FLOAT_HPP
|
||||
|
||||
|
|
|
@ -1,216 +1,216 @@
|
|||
#ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP
|
||||
#define SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <ios>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/detail/const_mod.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// linear_congruential_engine
|
||||
//
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
class linear_congruential_engine {
|
||||
public:
|
||||
typedef IntType result_type;
|
||||
private:
|
||||
struct private_constructor_tag {};
|
||||
public:
|
||||
SPROUT_STATIC_CONSTEXPR IntType multiplier = a;
|
||||
SPROUT_STATIC_CONSTEXPR IntType increment = c;
|
||||
SPROUT_STATIC_CONSTEXPR IntType modulus = m;
|
||||
SPROUT_STATIC_CONSTEXPR IntType default_seed = 1;
|
||||
public:
|
||||
static_assert(std::numeric_limits<IntType>::is_integer, "std::numeric_limits<IntType>::is_integer");
|
||||
static_assert(m == 0 || a < m, "m == 0 || a < m");
|
||||
static_assert(m == 0 || c < m, "m == 0 || c < m");
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType init_seed_3(IntType const& x0) {
|
||||
return x0 >= static_min() && x0 <= static_max()
|
||||
? x0
|
||||
: throw "assert(x0 >= static_min() && x0 <= static_max())"
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType init_seed_2(IntType const& x0) {
|
||||
return init_seed_3(increment == 0 && x0 == 0 ? 1 : x0);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType init_seed_1(IntType const& x0) {
|
||||
return init_seed_2(x0 <= 0 && x0 != 0 ? x0 + modulus : x0);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType init_seed(IntType const& x0) {
|
||||
return init_seed_1(modulus == 0 ? x0 : x0 % modulus);
|
||||
}
|
||||
public:
|
||||
static SPROUT_CONSTEXPR result_type static_min() {
|
||||
return c == 0 ? 1 : 0;
|
||||
}
|
||||
static SPROUT_CONSTEXPR result_type static_max() {
|
||||
return modulus - 1;
|
||||
}
|
||||
private:
|
||||
IntType x_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR linear_congruential_engine(IntType const& x, private_constructor_tag)
|
||||
: x_(x)
|
||||
{}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> generate(result_type result) const {
|
||||
return sprout::random::random_result<linear_congruential_engine>(
|
||||
result,
|
||||
linear_congruential_engine(result, private_constructor_tag())
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR linear_congruential_engine()
|
||||
: x_(init_seed(default_seed))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit linear_congruential_engine(IntType const& x0)
|
||||
: x_(init_seed(x0))
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return static_min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return static_max();
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> operator()() const {
|
||||
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) {
|
||||
return lhs.x_ == rhs.x_;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
linear_congruential_engine const& rhs
|
||||
)
|
||||
{
|
||||
IntType x;
|
||||
if(lhs >> x) {
|
||||
if(x >= min() && x <= max()) {
|
||||
rhs.x_ = x;
|
||||
} else {
|
||||
lhs.setstate(std::ios_base::failbit);
|
||||
}
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
linear_congruential_engine const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.x_;
|
||||
}
|
||||
};
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::multiplier;
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::increment;
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::modulus;
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::default_seed;
|
||||
|
||||
//
|
||||
// minstd_rand0
|
||||
//
|
||||
typedef sprout::random::linear_congruential_engine<std::uint32_t, 16807, 0, 2147483647> minstd_rand0;
|
||||
//
|
||||
// minstd_rand
|
||||
//
|
||||
typedef sprout::random::linear_congruential_engine<std::uint32_t, 48271, 0, 2147483647> minstd_rand;
|
||||
|
||||
//
|
||||
// rand48
|
||||
//
|
||||
class rand48 {
|
||||
public:
|
||||
typedef std::uint32_t result_type;
|
||||
private:
|
||||
struct private_constructor_tag {};
|
||||
typedef sprout::random::linear_congruential_engine<
|
||||
std::uint64_t,
|
||||
std::uint64_t(0xDEECE66DUL) | (std::uint64_t(0x5) << 32),
|
||||
0xB,
|
||||
std::uint64_t(1) << 48
|
||||
> lcf_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR result_type static_min() {
|
||||
return 0;
|
||||
}
|
||||
static SPROUT_CONSTEXPR result_type static_max() {
|
||||
return 0x7FFFFFFF;
|
||||
}
|
||||
static SPROUT_CONSTEXPR std::uint64_t cnv(std::uint32_t x) {
|
||||
return (static_cast<std::uint64_t>(x) << 16) | 0x330e;
|
||||
}
|
||||
private:
|
||||
lcf_type lcf_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR rand48(lcf_type const& lcf, private_constructor_tag)
|
||||
: lcf_(lcf)
|
||||
{}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<rand48> generate(
|
||||
sprout::random::random_result<lcf_type> const& lcf_result
|
||||
) const
|
||||
{
|
||||
return sprout::random::random_result<rand48>(
|
||||
lcf_result.result() >> 17,
|
||||
rand48(lcf_result.engine(), private_constructor_tag())
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR rand48()
|
||||
: lcf_(cnv(static_cast<std::uint32_t>(1)))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit rand48(result_type const& x0)
|
||||
: lcf_(cnv(x0))
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return static_min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return static_max();
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<rand48> operator()() const {
|
||||
return generate(lcf_());
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(rand48 const& lhs, rand48 const& rhs) {
|
||||
return lhs.lcf_ == rhs.lcf_;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(rand48 const& lhs, rand48 const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
rand48 const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.lcf_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
rand48 const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.lcf_;
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::minstd_rand0;
|
||||
using sprout::random::minstd_rand;
|
||||
using sprout::random::rand48;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP
|
||||
#ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP
|
||||
#define SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <ios>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/detail/const_mod.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// linear_congruential_engine
|
||||
//
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
class linear_congruential_engine {
|
||||
public:
|
||||
typedef IntType result_type;
|
||||
private:
|
||||
struct private_constructor_tag {};
|
||||
public:
|
||||
SPROUT_STATIC_CONSTEXPR IntType multiplier = a;
|
||||
SPROUT_STATIC_CONSTEXPR IntType increment = c;
|
||||
SPROUT_STATIC_CONSTEXPR IntType modulus = m;
|
||||
SPROUT_STATIC_CONSTEXPR IntType default_seed = 1;
|
||||
public:
|
||||
static_assert(std::numeric_limits<IntType>::is_integer, "std::numeric_limits<IntType>::is_integer");
|
||||
static_assert(m == 0 || a < m, "m == 0 || a < m");
|
||||
static_assert(m == 0 || c < m, "m == 0 || c < m");
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType init_seed_3(IntType const& x0) {
|
||||
return x0 >= static_min() && x0 <= static_max()
|
||||
? x0
|
||||
: throw "assert(x0 >= static_min() && x0 <= static_max())"
|
||||
;
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType init_seed_2(IntType const& x0) {
|
||||
return init_seed_3(increment == 0 && x0 == 0 ? 1 : x0);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType init_seed_1(IntType const& x0) {
|
||||
return init_seed_2(x0 <= 0 && x0 != 0 ? x0 + modulus : x0);
|
||||
}
|
||||
static SPROUT_CONSTEXPR IntType init_seed(IntType const& x0) {
|
||||
return init_seed_1(modulus == 0 ? x0 : x0 % modulus);
|
||||
}
|
||||
public:
|
||||
static SPROUT_CONSTEXPR result_type static_min() {
|
||||
return c == 0 ? 1 : 0;
|
||||
}
|
||||
static SPROUT_CONSTEXPR result_type static_max() {
|
||||
return modulus - 1;
|
||||
}
|
||||
private:
|
||||
IntType x_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR linear_congruential_engine(IntType const& x, private_constructor_tag)
|
||||
: x_(x)
|
||||
{}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> generate(result_type result) const {
|
||||
return sprout::random::random_result<linear_congruential_engine>(
|
||||
result,
|
||||
linear_congruential_engine(result, private_constructor_tag())
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR linear_congruential_engine()
|
||||
: x_(init_seed(default_seed))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit linear_congruential_engine(IntType const& x0)
|
||||
: x_(init_seed(x0))
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return static_min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return static_max();
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<linear_congruential_engine> operator()() const {
|
||||
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) {
|
||||
return lhs.x_ == rhs.x_;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(linear_congruential_engine const& lhs, linear_congruential_engine const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
linear_congruential_engine const& rhs
|
||||
)
|
||||
{
|
||||
IntType x;
|
||||
if(lhs >> x) {
|
||||
if(x >= min() && x <= max()) {
|
||||
rhs.x_ = x;
|
||||
} else {
|
||||
lhs.setstate(std::ios_base::failbit);
|
||||
}
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
linear_congruential_engine const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.x_;
|
||||
}
|
||||
};
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::multiplier;
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::increment;
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::modulus;
|
||||
template<typename IntType, IntType a, IntType c, IntType m>
|
||||
SPROUT_CONSTEXPR IntType sprout::random::linear_congruential_engine<IntType, a, c, m>::default_seed;
|
||||
|
||||
//
|
||||
// minstd_rand0
|
||||
//
|
||||
typedef sprout::random::linear_congruential_engine<std::uint32_t, 16807, 0, 2147483647> minstd_rand0;
|
||||
//
|
||||
// minstd_rand
|
||||
//
|
||||
typedef sprout::random::linear_congruential_engine<std::uint32_t, 48271, 0, 2147483647> minstd_rand;
|
||||
|
||||
//
|
||||
// rand48
|
||||
//
|
||||
class rand48 {
|
||||
public:
|
||||
typedef std::uint32_t result_type;
|
||||
private:
|
||||
struct private_constructor_tag {};
|
||||
typedef sprout::random::linear_congruential_engine<
|
||||
std::uint64_t,
|
||||
std::uint64_t(0xDEECE66DUL) | (std::uint64_t(0x5) << 32),
|
||||
0xB,
|
||||
std::uint64_t(1) << 48
|
||||
> lcf_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR result_type static_min() {
|
||||
return 0;
|
||||
}
|
||||
static SPROUT_CONSTEXPR result_type static_max() {
|
||||
return 0x7FFFFFFF;
|
||||
}
|
||||
static SPROUT_CONSTEXPR std::uint64_t cnv(std::uint32_t x) {
|
||||
return (static_cast<std::uint64_t>(x) << 16) | 0x330e;
|
||||
}
|
||||
private:
|
||||
lcf_type lcf_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR rand48(lcf_type const& lcf, private_constructor_tag)
|
||||
: lcf_(lcf)
|
||||
{}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<rand48> generate(
|
||||
sprout::random::random_result<lcf_type> const& lcf_result
|
||||
) const
|
||||
{
|
||||
return sprout::random::random_result<rand48>(
|
||||
lcf_result.result() >> 17,
|
||||
rand48(lcf_result.engine(), private_constructor_tag())
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR rand48()
|
||||
: lcf_(cnv(static_cast<std::uint32_t>(1)))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit rand48(result_type const& x0)
|
||||
: lcf_(cnv(x0))
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return static_min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return static_max();
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<rand48> operator()() const {
|
||||
return generate(lcf_());
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(rand48 const& lhs, rand48 const& rhs) {
|
||||
return lhs.lcf_ == rhs.lcf_;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(rand48 const& lhs, rand48 const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
rand48 const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.lcf_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
rand48 const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.lcf_;
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::minstd_rand0;
|
||||
using sprout::random::minstd_rand;
|
||||
using sprout::random::rand48;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_LINEAR_CONGRUENTIAL_HPP
|
||||
|
|
|
@ -1,468 +1,468 @@
|
|||
#ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP
|
||||
#define SPROUT_RANDOM_MERSENNE_TWISTER_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <ios>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/detail/integer/integer_mask.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// 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>
|
||||
class mersenne_twister_engine {
|
||||
public:
|
||||
typedef UIntType result_type;
|
||||
private:
|
||||
struct private_constructor_tag {};
|
||||
public:
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t word_size = w;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t state_size = n;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t shift_size = m;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t mask_bits = r;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType xor_mask = a;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t tempering_u = u;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType tempering_d = d;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t tempering_s = s;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType tempering_b = b;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t tempering_t = t;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType tempering_c = c;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t tempering_l = l;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType initialization_multiplier = f;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType default_seed = 5489u;
|
||||
private:
|
||||
SPROUT_STATIC_CONSTEXPR UIntType upper_mask = (~static_cast<UIntType>(0)) << r;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType lower_mask = ~upper_mask;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t unroll_factor = 6;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra1 = (n - m) % unroll_factor;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra2 = (m - 1) % unroll_factor;
|
||||
private:
|
||||
template<typename... Args>
|
||||
static SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) + 1 == n,
|
||||
sprout::array<UIntType, n>
|
||||
>::type init_seed_1(UIntType const& value, Args const&... args) {
|
||||
return sprout::array<UIntType, n>{{args..., value}};
|
||||
}
|
||||
template<typename... Args>
|
||||
static SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) + 1 < n,
|
||||
sprout::array<UIntType, n>
|
||||
>::type init_seed_1(UIntType const& value, Args const&... args) {
|
||||
return init_seed_1(
|
||||
(f * (value ^ (value >> (w - 2))) + (sizeof...(Args) + 1)) & static_max(),
|
||||
args...,
|
||||
value
|
||||
);
|
||||
}
|
||||
static SPROUT_CONSTEXPR sprout::array<UIntType, n> init_seed(UIntType const& value) {
|
||||
return init_seed_1(value & static_max());
|
||||
}
|
||||
public:
|
||||
static SPROUT_CONSTEXPR result_type static_min() {
|
||||
return 0;
|
||||
}
|
||||
static SPROUT_CONSTEXPR result_type static_max() {
|
||||
return sprout::detail::low_bits_mask_t<w>::sig_bits;
|
||||
}
|
||||
private:
|
||||
sprout::array<UIntType, n> x_;
|
||||
std::size_t i_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR mersenne_twister_engine(sprout::array<UIntType, n> const& x, std::size_t i, private_constructor_tag)
|
||||
: x_(x)
|
||||
, i_(i)
|
||||
{}
|
||||
SPROUT_CONSTEXPR UIntType rewind_find_1(UIntType const* last, std::size_t size, std::size_t index) const {
|
||||
return index < n - size
|
||||
? x_[index]
|
||||
: *(last - (n - 1 - index))
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType rewind_find(UIntType const* last, std::size_t size, std::size_t i) const {
|
||||
return rewind_find_1(last, size, (i + n - size + n - 1) % n);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n,
|
||||
sprout::array<UIntType, n>
|
||||
>::type rewind_finish_1(sprout::array<UIntType, n> const& data, Args const&... args) const {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n,
|
||||
sprout::array<UIntType, n>
|
||||
>::type rewind_finish_1(sprout::array<UIntType, n> const& data, Args const&... args) const {
|
||||
return rewind_finish_1(data, args..., data[sizeof...(args)]);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == 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 {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < 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 {
|
||||
return &data[0] + i == last - z
|
||||
? rewind_finish_1(data, data[i], args...)
|
||||
: rewind_finish(data, last, z, i + 1, data[i], args...)
|
||||
;
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == 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 {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < 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 {
|
||||
return rewind_2(
|
||||
data,
|
||||
last,
|
||||
z,
|
||||
y1,
|
||||
i,
|
||||
(y0 & upper_mask) | (y1 & lower_mask),
|
||||
args...
|
||||
);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == 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 {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < 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 {
|
||||
return rewind_4(
|
||||
data,
|
||||
last,
|
||||
z,
|
||||
y0,
|
||||
y1 & (static_cast<UIntType>(1) << (w - 1))
|
||||
? ((y1 ^ a) << 1) | 1
|
||||
: y1 << 1
|
||||
,
|
||||
i,
|
||||
args...
|
||||
);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == 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 {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < 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 {
|
||||
return i < z
|
||||
? rewind_3(data, last, z, y0, rewind_find(last, i, m - 1) ^ rewind_find(last, i, n - 1), i, args...)
|
||||
: rewind_finish(data, last, z, 0, args...)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::array<UIntType, n> rewind_1(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0) const {
|
||||
return rewind_2(
|
||||
data,
|
||||
last,
|
||||
z,
|
||||
y0 & (static_cast<UIntType>(1) << (w - 1))
|
||||
? ((y0 ^ a) << 1) | 1
|
||||
: y0 << 1
|
||||
,
|
||||
0
|
||||
);
|
||||
}
|
||||
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]);
|
||||
}
|
||||
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
|
||||
? back[i + n - offset] != other.x_[i]
|
||||
? false
|
||||
: equal_impl_2(other, back, offset, i + 1)
|
||||
: true
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR bool equal_impl_1(mersenne_twister_engine const& other, sprout::array<UIntType, n> back, std::size_t offset, std::size_t i = 0) const {
|
||||
return i + offset < n
|
||||
? x_[i] != other.x_[i + offset]
|
||||
? false
|
||||
: equal_impl_1(other, back, offset, i + 1)
|
||||
: equal_impl_2(other, rewind(back, &back[n - 1], offset), offset)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR bool equal_impl(mersenne_twister_engine const& other) const {
|
||||
return equal_impl_1(other, sprout::array<UIntType, n>(), other.i_ - i_);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl_4(UIntType z) const {
|
||||
return z ^ (z >> l);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl_3(UIntType z) const {
|
||||
return z ^ generate_impl_4((z << t) & c);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl_2(UIntType z) const {
|
||||
return z ^ generate_impl_3((z << s) & b);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl_1(UIntType z) const {
|
||||
return z ^ generate_impl_2((z >> u) & d);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl() const {
|
||||
return generate_impl_1(x_[i_]);
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<mersenne_twister_engine> generate() const {
|
||||
return sprout::random::random_result<mersenne_twister_engine>(
|
||||
generate_impl(),
|
||||
mersenne_twister_engine(
|
||||
x_,
|
||||
i_ + 1,
|
||||
private_constructor_tag()
|
||||
)
|
||||
);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR mersenne_twister_engine twist_5(Args const&... args) const {
|
||||
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)}},
|
||||
0,
|
||||
private_constructor_tag()
|
||||
);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n - 1,
|
||||
mersenne_twister_engine
|
||||
>::type twist_4(std::size_t i, Args const&... args) const {
|
||||
return twist_5(args...);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n - 1,
|
||||
mersenne_twister_engine
|
||||
>::type twist_4(std::size_t i, Args const&... args) const {
|
||||
return twist_4(i + 1, args..., x_[i - (n - m)] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a));
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n - 1 - unroll_extra2,
|
||||
mersenne_twister_engine
|
||||
>::type twist_3(std::size_t i, Args const&... args) const {
|
||||
return twist_4(n - 1 - unroll_extra2, args...);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n - 1 - unroll_extra2,
|
||||
mersenne_twister_engine
|
||||
>::type twist_3(std::size_t i, Args const&... args) const {
|
||||
return twist_3(i + 1, args..., x_[i - (n - m)] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a));
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n - m,
|
||||
mersenne_twister_engine
|
||||
>::type twist_2(std::size_t i, Args const&... args) const {
|
||||
return twist_3(n - m, args...);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n - m,
|
||||
mersenne_twister_engine
|
||||
>::type twist_2(std::size_t i, Args const&... args) const {
|
||||
return twist_2(i + 1, args..., x_[i + m] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a));
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n - m - unroll_extra1,
|
||||
mersenne_twister_engine
|
||||
>::type twist_1(std::size_t i, Args const&... args) const {
|
||||
return twist_2(n - m - unroll_extra1, args...);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n - m - unroll_extra1,
|
||||
mersenne_twister_engine
|
||||
>::type twist_1(std::size_t i, Args const&... args) const {
|
||||
return twist_1(i + 1, args..., x_[i + m] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a));
|
||||
}
|
||||
SPROUT_CONSTEXPR mersenne_twister_engine twist() const {
|
||||
return twist_1(0);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR mersenne_twister_engine()
|
||||
: x_(init_seed(default_seed))
|
||||
, i_(n)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit mersenne_twister_engine(UIntType const& value)
|
||||
: x_(init_seed(value))
|
||||
, i_(n)
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return static_min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return static_max();
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<mersenne_twister_engine> operator()() const {
|
||||
return i_ == n
|
||||
? twist().generate()
|
||||
: generate()
|
||||
;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) {
|
||||
return lhs.i_ < lhs.i_
|
||||
? lhs.equal_impl(rhs)
|
||||
: rhs.equal_impl(lhs)
|
||||
;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
mersenne_twister_engine const& rhs
|
||||
)
|
||||
{
|
||||
sprout::array<UIntType, n> data;
|
||||
for(std::size_t i = 0; i < rhs.i_; ++i) {
|
||||
data[i + n - rhs.i_] = rhs.x_[i];
|
||||
}
|
||||
if (rhs.i_ != n) {
|
||||
data = rhs.rewind(data, &data[n - rhs.i_ - 1], n - rhs.i_);
|
||||
}
|
||||
lhs << data[0];
|
||||
for (std::size_t i = 0; i < rhs.i_; ++i) {
|
||||
lhs << ' ' << data[i];
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
mersenne_twister_engine const& rhs
|
||||
)
|
||||
{
|
||||
for (std::size_t i = 0; i < state_size; ++i) {
|
||||
lhs >> rhs.x_[i] >> std::ws;
|
||||
}
|
||||
rhs.i_ = state_size;
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
template<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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
//
|
||||
// mt11213b
|
||||
//
|
||||
typedef sprout::random::mersenne_twister_engine<
|
||||
std::uint32_t,
|
||||
32,
|
||||
351,
|
||||
175,
|
||||
19,
|
||||
0xccab8ee7,
|
||||
11,
|
||||
0xffffffff,
|
||||
7,
|
||||
0x31b6ab00,
|
||||
15,
|
||||
0xffe50000,
|
||||
17,
|
||||
1812433253
|
||||
> mt11213b;
|
||||
//
|
||||
// mt19937
|
||||
//
|
||||
typedef sprout::random::mersenne_twister_engine<
|
||||
std::uint32_t,
|
||||
32,
|
||||
624,
|
||||
397,
|
||||
31,
|
||||
0x9908b0df,
|
||||
11,
|
||||
0xffffffff,
|
||||
7,
|
||||
0x9d2c5680,
|
||||
15,
|
||||
0xefc60000,
|
||||
18,
|
||||
1812433253
|
||||
> mt19937;
|
||||
//
|
||||
// mt19937_64
|
||||
//
|
||||
typedef sprout::random::mersenne_twister_engine<
|
||||
std::uint64_t,
|
||||
64,
|
||||
312,
|
||||
156,
|
||||
31,
|
||||
UINT64_C(0xb5026f5aa96619e9),
|
||||
29,
|
||||
UINT64_C(0x5555555555555555),
|
||||
17,
|
||||
UINT64_C(0x71d67fffeda60000),
|
||||
37,
|
||||
UINT64_C(0xfff7eee000000000),
|
||||
43,
|
||||
UINT64_C(6364136223846793005)
|
||||
> mt19937_64;
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::mt11213b;
|
||||
using sprout::random::mt19937;
|
||||
using sprout::random::mt19937_64;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP
|
||||
#define SPROUT_RANDOM_MERSENNE_TWISTER_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <ios>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/array.hpp>
|
||||
#include <sprout/detail/integer/integer_mask.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// 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>
|
||||
class mersenne_twister_engine {
|
||||
public:
|
||||
typedef UIntType result_type;
|
||||
private:
|
||||
struct private_constructor_tag {};
|
||||
public:
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t word_size = w;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t state_size = n;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t shift_size = m;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t mask_bits = r;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType xor_mask = a;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t tempering_u = u;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType tempering_d = d;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t tempering_s = s;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType tempering_b = b;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t tempering_t = t;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType tempering_c = c;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t tempering_l = l;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType initialization_multiplier = f;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType default_seed = 5489u;
|
||||
private:
|
||||
SPROUT_STATIC_CONSTEXPR UIntType upper_mask = (~static_cast<UIntType>(0)) << r;
|
||||
SPROUT_STATIC_CONSTEXPR UIntType lower_mask = ~upper_mask;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t unroll_factor = 6;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra1 = (n - m) % unroll_factor;
|
||||
SPROUT_STATIC_CONSTEXPR std::size_t unroll_extra2 = (m - 1) % unroll_factor;
|
||||
private:
|
||||
template<typename... Args>
|
||||
static SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) + 1 == n,
|
||||
sprout::array<UIntType, n>
|
||||
>::type init_seed_1(UIntType const& value, Args const&... args) {
|
||||
return sprout::array<UIntType, n>{{args..., value}};
|
||||
}
|
||||
template<typename... Args>
|
||||
static SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) + 1 < n,
|
||||
sprout::array<UIntType, n>
|
||||
>::type init_seed_1(UIntType const& value, Args const&... args) {
|
||||
return init_seed_1(
|
||||
(f * (value ^ (value >> (w - 2))) + (sizeof...(Args) + 1)) & static_max(),
|
||||
args...,
|
||||
value
|
||||
);
|
||||
}
|
||||
static SPROUT_CONSTEXPR sprout::array<UIntType, n> init_seed(UIntType const& value) {
|
||||
return init_seed_1(value & static_max());
|
||||
}
|
||||
public:
|
||||
static SPROUT_CONSTEXPR result_type static_min() {
|
||||
return 0;
|
||||
}
|
||||
static SPROUT_CONSTEXPR result_type static_max() {
|
||||
return sprout::detail::low_bits_mask_t<w>::sig_bits;
|
||||
}
|
||||
private:
|
||||
sprout::array<UIntType, n> x_;
|
||||
std::size_t i_;
|
||||
private:
|
||||
SPROUT_CONSTEXPR mersenne_twister_engine(sprout::array<UIntType, n> const& x, std::size_t i, private_constructor_tag)
|
||||
: x_(x)
|
||||
, i_(i)
|
||||
{}
|
||||
SPROUT_CONSTEXPR UIntType rewind_find_1(UIntType const* last, std::size_t size, std::size_t index) const {
|
||||
return index < n - size
|
||||
? x_[index]
|
||||
: *(last - (n - 1 - index))
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType rewind_find(UIntType const* last, std::size_t size, std::size_t i) const {
|
||||
return rewind_find_1(last, size, (i + n - size + n - 1) % n);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n,
|
||||
sprout::array<UIntType, n>
|
||||
>::type rewind_finish_1(sprout::array<UIntType, n> const& data, Args const&... args) const {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n,
|
||||
sprout::array<UIntType, n>
|
||||
>::type rewind_finish_1(sprout::array<UIntType, n> const& data, Args const&... args) const {
|
||||
return rewind_finish_1(data, args..., data[sizeof...(args)]);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == 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 {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < 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 {
|
||||
return &data[0] + i == last - z
|
||||
? rewind_finish_1(data, data[i], args...)
|
||||
: rewind_finish(data, last, z, i + 1, data[i], args...)
|
||||
;
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == 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 {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < 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 {
|
||||
return rewind_2(
|
||||
data,
|
||||
last,
|
||||
z,
|
||||
y1,
|
||||
i,
|
||||
(y0 & upper_mask) | (y1 & lower_mask),
|
||||
args...
|
||||
);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == 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 {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < 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 {
|
||||
return rewind_4(
|
||||
data,
|
||||
last,
|
||||
z,
|
||||
y0,
|
||||
y1 & (static_cast<UIntType>(1) << (w - 1))
|
||||
? ((y1 ^ a) << 1) | 1
|
||||
: y1 << 1
|
||||
,
|
||||
i,
|
||||
args...
|
||||
);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == 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 {
|
||||
return sprout::array<UIntType, n>{{args...}};
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < 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 {
|
||||
return i < z
|
||||
? rewind_3(data, last, z, y0, rewind_find(last, i, m - 1) ^ rewind_find(last, i, n - 1), i, args...)
|
||||
: rewind_finish(data, last, z, 0, args...)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::array<UIntType, n> rewind_1(sprout::array<UIntType, n> const& data, UIntType const* last, std::size_t z, UIntType y0) const {
|
||||
return rewind_2(
|
||||
data,
|
||||
last,
|
||||
z,
|
||||
y0 & (static_cast<UIntType>(1) << (w - 1))
|
||||
? ((y0 ^ a) << 1) | 1
|
||||
: y0 << 1
|
||||
,
|
||||
0
|
||||
);
|
||||
}
|
||||
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]);
|
||||
}
|
||||
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
|
||||
? back[i + n - offset] != other.x_[i]
|
||||
? false
|
||||
: equal_impl_2(other, back, offset, i + 1)
|
||||
: true
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR bool equal_impl_1(mersenne_twister_engine const& other, sprout::array<UIntType, n> back, std::size_t offset, std::size_t i = 0) const {
|
||||
return i + offset < n
|
||||
? x_[i] != other.x_[i + offset]
|
||||
? false
|
||||
: equal_impl_1(other, back, offset, i + 1)
|
||||
: equal_impl_2(other, rewind(back, &back[n - 1], offset), offset)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR bool equal_impl(mersenne_twister_engine const& other) const {
|
||||
return equal_impl_1(other, sprout::array<UIntType, n>(), other.i_ - i_);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl_4(UIntType z) const {
|
||||
return z ^ (z >> l);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl_3(UIntType z) const {
|
||||
return z ^ generate_impl_4((z << t) & c);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl_2(UIntType z) const {
|
||||
return z ^ generate_impl_3((z << s) & b);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl_1(UIntType z) const {
|
||||
return z ^ generate_impl_2((z >> u) & d);
|
||||
}
|
||||
SPROUT_CONSTEXPR UIntType generate_impl() const {
|
||||
return generate_impl_1(x_[i_]);
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<mersenne_twister_engine> generate() const {
|
||||
return sprout::random::random_result<mersenne_twister_engine>(
|
||||
generate_impl(),
|
||||
mersenne_twister_engine(
|
||||
x_,
|
||||
i_ + 1,
|
||||
private_constructor_tag()
|
||||
)
|
||||
);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR mersenne_twister_engine twist_5(Args const&... args) const {
|
||||
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)}},
|
||||
0,
|
||||
private_constructor_tag()
|
||||
);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n - 1,
|
||||
mersenne_twister_engine
|
||||
>::type twist_4(std::size_t i, Args const&... args) const {
|
||||
return twist_5(args...);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n - 1,
|
||||
mersenne_twister_engine
|
||||
>::type twist_4(std::size_t i, Args const&... args) const {
|
||||
return twist_4(i + 1, args..., x_[i - (n - m)] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a));
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n - 1 - unroll_extra2,
|
||||
mersenne_twister_engine
|
||||
>::type twist_3(std::size_t i, Args const&... args) const {
|
||||
return twist_4(n - 1 - unroll_extra2, args...);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n - 1 - unroll_extra2,
|
||||
mersenne_twister_engine
|
||||
>::type twist_3(std::size_t i, Args const&... args) const {
|
||||
return twist_3(i + 1, args..., x_[i - (n - m)] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a));
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n - m,
|
||||
mersenne_twister_engine
|
||||
>::type twist_2(std::size_t i, Args const&... args) const {
|
||||
return twist_3(n - m, args...);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n - m,
|
||||
mersenne_twister_engine
|
||||
>::type twist_2(std::size_t i, Args const&... args) const {
|
||||
return twist_2(i + 1, args..., x_[i + m] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a));
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) == n - m - unroll_extra1,
|
||||
mersenne_twister_engine
|
||||
>::type twist_1(std::size_t i, Args const&... args) const {
|
||||
return twist_2(n - m - unroll_extra1, args...);
|
||||
}
|
||||
template<typename... Args>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
sizeof...(Args) < n - m - unroll_extra1,
|
||||
mersenne_twister_engine
|
||||
>::type twist_1(std::size_t i, Args const&... args) const {
|
||||
return twist_1(i + 1, args..., x_[i + m] ^ ((x_[i] & upper_mask) | (x_[i + 1] & lower_mask) >> 1) ^ ((x_[i + 1] & 1) * a));
|
||||
}
|
||||
SPROUT_CONSTEXPR mersenne_twister_engine twist() const {
|
||||
return twist_1(0);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR mersenne_twister_engine()
|
||||
: x_(init_seed(default_seed))
|
||||
, i_(n)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit mersenne_twister_engine(UIntType const& value)
|
||||
: x_(init_seed(value))
|
||||
, i_(n)
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return static_min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return static_max();
|
||||
}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<mersenne_twister_engine> operator()() const {
|
||||
return i_ == n
|
||||
? twist().generate()
|
||||
: generate()
|
||||
;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) {
|
||||
return lhs.i_ < lhs.i_
|
||||
? lhs.equal_impl(rhs)
|
||||
: rhs.equal_impl(lhs)
|
||||
;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(mersenne_twister_engine const& lhs, mersenne_twister_engine const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_istream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
mersenne_twister_engine const& rhs
|
||||
)
|
||||
{
|
||||
sprout::array<UIntType, n> data;
|
||||
for(std::size_t i = 0; i < rhs.i_; ++i) {
|
||||
data[i + n - rhs.i_] = rhs.x_[i];
|
||||
}
|
||||
if (rhs.i_ != n) {
|
||||
data = rhs.rewind(data, &data[n - rhs.i_ - 1], n - rhs.i_);
|
||||
}
|
||||
lhs << data[0];
|
||||
for (std::size_t i = 0; i < rhs.i_; ++i) {
|
||||
lhs << ' ' << data[i];
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
mersenne_twister_engine const& rhs
|
||||
)
|
||||
{
|
||||
for (std::size_t i = 0; i < state_size; ++i) {
|
||||
lhs >> rhs.x_[i] >> std::ws;
|
||||
}
|
||||
rhs.i_ = state_size;
|
||||
return lhs;
|
||||
}
|
||||
};
|
||||
template<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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
//
|
||||
// mt11213b
|
||||
//
|
||||
typedef sprout::random::mersenne_twister_engine<
|
||||
std::uint32_t,
|
||||
32,
|
||||
351,
|
||||
175,
|
||||
19,
|
||||
0xccab8ee7,
|
||||
11,
|
||||
0xffffffff,
|
||||
7,
|
||||
0x31b6ab00,
|
||||
15,
|
||||
0xffe50000,
|
||||
17,
|
||||
1812433253
|
||||
> mt11213b;
|
||||
//
|
||||
// mt19937
|
||||
//
|
||||
typedef sprout::random::mersenne_twister_engine<
|
||||
std::uint32_t,
|
||||
32,
|
||||
624,
|
||||
397,
|
||||
31,
|
||||
0x9908b0df,
|
||||
11,
|
||||
0xffffffff,
|
||||
7,
|
||||
0x9d2c5680,
|
||||
15,
|
||||
0xefc60000,
|
||||
18,
|
||||
1812433253
|
||||
> mt19937;
|
||||
//
|
||||
// mt19937_64
|
||||
//
|
||||
typedef sprout::random::mersenne_twister_engine<
|
||||
std::uint64_t,
|
||||
64,
|
||||
312,
|
||||
156,
|
||||
31,
|
||||
UINT64_C(0xb5026f5aa96619e9),
|
||||
29,
|
||||
UINT64_C(0x5555555555555555),
|
||||
17,
|
||||
UINT64_C(0x71d67fffeda60000),
|
||||
37,
|
||||
UINT64_C(0xfff7eee000000000),
|
||||
43,
|
||||
UINT64_C(6364136223846793005)
|
||||
> mt19937_64;
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::mt11213b;
|
||||
using sprout::random::mt19937;
|
||||
using sprout::random::mt19937_64;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_MERSENNE_TWISTER_HPP
|
||||
|
||||
|
|
|
@ -1,326 +1,326 @@
|
|||
#ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP
|
||||
#define SPROUT_RANDOM_RANDOM_ITERATOR_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/next.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// random_iterator
|
||||
//
|
||||
template<typename Engine, typename Distribution = void, typename Enable = void>
|
||||
class random_iterator;
|
||||
|
||||
template<typename Engine, typename Distribution>
|
||||
class random_iterator<
|
||||
Engine,
|
||||
Distribution,
|
||||
typename std::enable_if<!std::is_same<Distribution, void>::value>::type
|
||||
>
|
||||
: 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> >::value_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> >::reference
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef sprout::random::random_result<Engine, Distribution> random_result_type;
|
||||
typedef typename random_result_type::engine_type engine_type;
|
||||
typedef typename random_result_type::distribution_type distribution_type;
|
||||
typedef typename random_result_type::result_type result_type;
|
||||
typedef typename std::iterator_traits<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>::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<random_result_type>::pointer pointer;
|
||||
typedef typename std::iterator_traits<random_result_type>::reference reference;
|
||||
private:
|
||||
random_result_type random_;
|
||||
difference_type count_;
|
||||
public:
|
||||
//random_iterator() = default; // ???
|
||||
SPROUT_CONSTEXPR random_iterator()
|
||||
: random_()
|
||||
, count_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_iterator(
|
||||
engine_type const& engine,
|
||||
distribution_type const& distribution,
|
||||
difference_type count = -1
|
||||
)
|
||||
: random_(distribution(engine))
|
||||
, count_(count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit random_iterator(
|
||||
random_result_type const& random,
|
||||
difference_type count = -1
|
||||
)
|
||||
: random_(random)
|
||||
, count_(count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_iterator operator()() const {
|
||||
return count_ != 0
|
||||
? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_)
|
||||
: throw "assert(count_ != 0)"
|
||||
;
|
||||
}
|
||||
random_result_type& random_result() {
|
||||
return random_;
|
||||
}
|
||||
SPROUT_CONSTEXPR random_result_type const& random_result() const {
|
||||
return random_;
|
||||
}
|
||||
result_type& result() {
|
||||
return random_.result();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type const& result() const {
|
||||
return random_.result();
|
||||
}
|
||||
engine_type& engine() {
|
||||
return random_.engine();
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_type const& engine() const {
|
||||
return random_.engine();
|
||||
}
|
||||
distribution_type& distribution() {
|
||||
return random_.distribution();
|
||||
}
|
||||
SPROUT_CONSTEXPR distribution_type const& distribution() const {
|
||||
return random_.distribution();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return random_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return random_.max();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type count() const {
|
||||
return count_;
|
||||
}
|
||||
void swap(random_iterator& other) {
|
||||
using std::swap;
|
||||
swap(random_, other.random_);
|
||||
swap(count_, other.count_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) {
|
||||
return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator*() const {
|
||||
return count_ != 0
|
||||
? random_.result()
|
||||
: (throw "assert(count_ != 0)", random_.result())
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR pointer operator->() const {
|
||||
return count_ != 0
|
||||
? &random_.result()
|
||||
: throw "assert(count_ != 0)"
|
||||
;
|
||||
}
|
||||
random_iterator& operator++() {
|
||||
random_iterator temp((*this)());
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
random_iterator operator++(int) {
|
||||
random_iterator result(*this);
|
||||
++*this;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
template<typename Engine, typename Distribution>
|
||||
class random_iterator<
|
||||
Engine,
|
||||
Distribution,
|
||||
typename std::enable_if<std::is_same<Distribution, void>::value>::type
|
||||
>
|
||||
: public std::iterator<
|
||||
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> >::difference_type,
|
||||
typename std::iterator_traits<sprout::random::random_result<Engine> >::pointer,
|
||||
typename std::iterator_traits<sprout::random::random_result<Engine> >::reference
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef sprout::random::random_result<Engine> random_result_type;
|
||||
typedef typename random_result_type::engine_type engine_type;
|
||||
typedef typename random_result_type::result_type result_type;
|
||||
typedef typename std::iterator_traits<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>::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<random_result_type>::pointer pointer;
|
||||
typedef typename std::iterator_traits<random_result_type>::reference reference;
|
||||
private:
|
||||
random_result_type random_;
|
||||
difference_type count_;
|
||||
public:
|
||||
//random_iterator() = default; // ???
|
||||
SPROUT_CONSTEXPR random_iterator()
|
||||
: random_()
|
||||
, count_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_iterator(
|
||||
engine_type const& engine,
|
||||
difference_type count = -1
|
||||
)
|
||||
: random_(engine())
|
||||
, count_(count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit random_iterator(
|
||||
random_result_type const& random,
|
||||
difference_type count = -1
|
||||
)
|
||||
: random_(random)
|
||||
, count_(count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_iterator operator()() const {
|
||||
return count_ != 0
|
||||
? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_)
|
||||
: throw "assert(count_ != 0)"
|
||||
;
|
||||
}
|
||||
random_result_type& random_result() {
|
||||
return random_;
|
||||
}
|
||||
SPROUT_CONSTEXPR random_result_type const& random_result() const {
|
||||
return random_;
|
||||
}
|
||||
result_type& result() {
|
||||
return random_.result();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type const& result() const {
|
||||
return random_.result();
|
||||
}
|
||||
engine_type& engine() {
|
||||
return random_.engine();
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_type const& engine() const {
|
||||
return random_.engine();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return random_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return random_.max();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type count() const {
|
||||
return count_;
|
||||
}
|
||||
void swap(random_iterator& other) {
|
||||
using std::swap;
|
||||
swap(random_, other.random_);
|
||||
swap(count_, other.count_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) {
|
||||
return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator*() const {
|
||||
return count_ != 0
|
||||
? random_.result()
|
||||
: (throw "assert(count_ != 0)", random_.result())
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR pointer operator->() const {
|
||||
return count_ > 0
|
||||
? &random_.result()
|
||||
: throw "assert(count_ != 0)"
|
||||
;
|
||||
}
|
||||
random_iterator& operator++() {
|
||||
random_iterator temp((*this)());
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
random_iterator operator++(int) {
|
||||
random_iterator result(*this);
|
||||
++*this;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
//
|
||||
// swap
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
void swap(
|
||||
sprout::random::random_iterator<Engine, Distribution>& lhs,
|
||||
sprout::random::random_iterator<Engine, Distribution>& rhs
|
||||
)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
//
|
||||
// begin
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!std::is_integral<Distribution>::value,
|
||||
sprout::random::random_iterator<Engine, Distribution>
|
||||
>::type begin(
|
||||
Engine const& engine,
|
||||
Distribution const& distribution,
|
||||
typename sprout::random::random_iterator<Engine, Distribution>::difference_type count = -1
|
||||
)
|
||||
{
|
||||
return sprout::random::random_iterator<Engine, Distribution>(engine, distribution, count);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine> begin(
|
||||
Engine const& engine,
|
||||
typename sprout::random::random_iterator<Engine>::difference_type count = -1
|
||||
)
|
||||
{
|
||||
return sprout::random::random_iterator<Engine>(engine, count);
|
||||
}
|
||||
|
||||
//
|
||||
// end
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine, Distribution> end(
|
||||
Engine const& engine,
|
||||
Distribution const& distribution
|
||||
)
|
||||
{
|
||||
return sprout::random::random_iterator<Engine, Distribution>();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine> end(
|
||||
Engine const& engine
|
||||
)
|
||||
{
|
||||
return sprout::random::random_iterator<Engine>();
|
||||
}
|
||||
|
||||
//
|
||||
// next
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine, Distribution> next(
|
||||
sprout::random::random_iterator<Engine, Distribution> const& it
|
||||
)
|
||||
{
|
||||
return it();
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::random_iterator;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP
|
||||
#define SPROUT_RANDOM_RANDOM_ITERATOR_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/next.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// random_iterator
|
||||
//
|
||||
template<typename Engine, typename Distribution = void, typename Enable = void>
|
||||
class random_iterator;
|
||||
|
||||
template<typename Engine, typename Distribution>
|
||||
class random_iterator<
|
||||
Engine,
|
||||
Distribution,
|
||||
typename std::enable_if<!std::is_same<Distribution, void>::value>::type
|
||||
>
|
||||
: 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> >::value_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> >::reference
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef sprout::random::random_result<Engine, Distribution> random_result_type;
|
||||
typedef typename random_result_type::engine_type engine_type;
|
||||
typedef typename random_result_type::distribution_type distribution_type;
|
||||
typedef typename random_result_type::result_type result_type;
|
||||
typedef typename std::iterator_traits<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>::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<random_result_type>::pointer pointer;
|
||||
typedef typename std::iterator_traits<random_result_type>::reference reference;
|
||||
private:
|
||||
random_result_type random_;
|
||||
difference_type count_;
|
||||
public:
|
||||
//random_iterator() = default; // ???
|
||||
SPROUT_CONSTEXPR random_iterator()
|
||||
: random_()
|
||||
, count_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_iterator(
|
||||
engine_type const& engine,
|
||||
distribution_type const& distribution,
|
||||
difference_type count = -1
|
||||
)
|
||||
: random_(distribution(engine))
|
||||
, count_(count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit random_iterator(
|
||||
random_result_type const& random,
|
||||
difference_type count = -1
|
||||
)
|
||||
: random_(random)
|
||||
, count_(count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_iterator operator()() const {
|
||||
return count_ != 0
|
||||
? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_)
|
||||
: throw "assert(count_ != 0)"
|
||||
;
|
||||
}
|
||||
random_result_type& random_result() {
|
||||
return random_;
|
||||
}
|
||||
SPROUT_CONSTEXPR random_result_type const& random_result() const {
|
||||
return random_;
|
||||
}
|
||||
result_type& result() {
|
||||
return random_.result();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type const& result() const {
|
||||
return random_.result();
|
||||
}
|
||||
engine_type& engine() {
|
||||
return random_.engine();
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_type const& engine() const {
|
||||
return random_.engine();
|
||||
}
|
||||
distribution_type& distribution() {
|
||||
return random_.distribution();
|
||||
}
|
||||
SPROUT_CONSTEXPR distribution_type const& distribution() const {
|
||||
return random_.distribution();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return random_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return random_.max();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type count() const {
|
||||
return count_;
|
||||
}
|
||||
void swap(random_iterator& other) {
|
||||
using std::swap;
|
||||
swap(random_, other.random_);
|
||||
swap(count_, other.count_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) {
|
||||
return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator*() const {
|
||||
return count_ != 0
|
||||
? random_.result()
|
||||
: (throw "assert(count_ != 0)", random_.result())
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR pointer operator->() const {
|
||||
return count_ != 0
|
||||
? &random_.result()
|
||||
: throw "assert(count_ != 0)"
|
||||
;
|
||||
}
|
||||
random_iterator& operator++() {
|
||||
random_iterator temp((*this)());
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
random_iterator operator++(int) {
|
||||
random_iterator result(*this);
|
||||
++*this;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
template<typename Engine, typename Distribution>
|
||||
class random_iterator<
|
||||
Engine,
|
||||
Distribution,
|
||||
typename std::enable_if<std::is_same<Distribution, void>::value>::type
|
||||
>
|
||||
: public std::iterator<
|
||||
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> >::difference_type,
|
||||
typename std::iterator_traits<sprout::random::random_result<Engine> >::pointer,
|
||||
typename std::iterator_traits<sprout::random::random_result<Engine> >::reference
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef sprout::random::random_result<Engine> random_result_type;
|
||||
typedef typename random_result_type::engine_type engine_type;
|
||||
typedef typename random_result_type::result_type result_type;
|
||||
typedef typename std::iterator_traits<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>::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<random_result_type>::pointer pointer;
|
||||
typedef typename std::iterator_traits<random_result_type>::reference reference;
|
||||
private:
|
||||
random_result_type random_;
|
||||
difference_type count_;
|
||||
public:
|
||||
//random_iterator() = default; // ???
|
||||
SPROUT_CONSTEXPR random_iterator()
|
||||
: random_()
|
||||
, count_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_iterator(
|
||||
engine_type const& engine,
|
||||
difference_type count = -1
|
||||
)
|
||||
: random_(engine())
|
||||
, count_(count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit random_iterator(
|
||||
random_result_type const& random,
|
||||
difference_type count = -1
|
||||
)
|
||||
: random_(random)
|
||||
, count_(count)
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_iterator operator()() const {
|
||||
return count_ != 0
|
||||
? random_iterator(random_(), count_ > 0 ? count_ - 1 : count_)
|
||||
: throw "assert(count_ != 0)"
|
||||
;
|
||||
}
|
||||
random_result_type& random_result() {
|
||||
return random_;
|
||||
}
|
||||
SPROUT_CONSTEXPR random_result_type const& random_result() const {
|
||||
return random_;
|
||||
}
|
||||
result_type& result() {
|
||||
return random_.result();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type const& result() const {
|
||||
return random_.result();
|
||||
}
|
||||
engine_type& engine() {
|
||||
return random_.engine();
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_type const& engine() const {
|
||||
return random_.engine();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return random_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return random_.max();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type count() const {
|
||||
return count_;
|
||||
}
|
||||
void swap(random_iterator& other) {
|
||||
using std::swap;
|
||||
swap(random_, other.random_);
|
||||
swap(count_, other.count_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(random_iterator const& lhs, random_iterator const& rhs) {
|
||||
return lhs.count_ == rhs.count_ && (lhs.count_ == 0 || lhs.random_ == rhs.random_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(random_iterator const& lhs, random_iterator const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator*() const {
|
||||
return count_ != 0
|
||||
? random_.result()
|
||||
: (throw "assert(count_ != 0)", random_.result())
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR pointer operator->() const {
|
||||
return count_ > 0
|
||||
? &random_.result()
|
||||
: throw "assert(count_ != 0)"
|
||||
;
|
||||
}
|
||||
random_iterator& operator++() {
|
||||
random_iterator temp((*this)());
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
random_iterator operator++(int) {
|
||||
random_iterator result(*this);
|
||||
++*this;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
//
|
||||
// swap
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
void swap(
|
||||
sprout::random::random_iterator<Engine, Distribution>& lhs,
|
||||
sprout::random::random_iterator<Engine, Distribution>& rhs
|
||||
)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
//
|
||||
// begin
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR typename std::enable_if<
|
||||
!std::is_integral<Distribution>::value,
|
||||
sprout::random::random_iterator<Engine, Distribution>
|
||||
>::type begin(
|
||||
Engine const& engine,
|
||||
Distribution const& distribution,
|
||||
typename sprout::random::random_iterator<Engine, Distribution>::difference_type count = -1
|
||||
)
|
||||
{
|
||||
return sprout::random::random_iterator<Engine, Distribution>(engine, distribution, count);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine> begin(
|
||||
Engine const& engine,
|
||||
typename sprout::random::random_iterator<Engine>::difference_type count = -1
|
||||
)
|
||||
{
|
||||
return sprout::random::random_iterator<Engine>(engine, count);
|
||||
}
|
||||
|
||||
//
|
||||
// end
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine, Distribution> end(
|
||||
Engine const& engine,
|
||||
Distribution const& distribution
|
||||
)
|
||||
{
|
||||
return sprout::random::random_iterator<Engine, Distribution>();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine> end(
|
||||
Engine const& engine
|
||||
)
|
||||
{
|
||||
return sprout::random::random_iterator<Engine>();
|
||||
}
|
||||
|
||||
//
|
||||
// next
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR sprout::random::random_iterator<Engine, Distribution> next(
|
||||
sprout::random::random_iterator<Engine, Distribution> const& it
|
||||
)
|
||||
{
|
||||
return it();
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::random_iterator;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_RANDOM_ITERATOR_HPP
|
||||
|
||||
|
|
|
@ -1,263 +1,263 @@
|
|||
#ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP
|
||||
#define SPROUT_RANDOM_RANDOM_RESULT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/next.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// random_result
|
||||
//
|
||||
template<typename Engine, typename Distribution = void, typename Enable = void>
|
||||
class random_result;
|
||||
|
||||
template<typename Engine, typename Distribution>
|
||||
class random_result<
|
||||
Engine,
|
||||
Distribution,
|
||||
typename std::enable_if<!std::is_same<Distribution, void>::value>::type
|
||||
>
|
||||
: public std::iterator<
|
||||
std::input_iterator_tag,
|
||||
typename Distribution::result_type,
|
||||
std::ptrdiff_t,
|
||||
typename Distribution::result_type const*,
|
||||
typename Distribution::result_type const&
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef Engine engine_type;
|
||||
typedef Distribution distribution_type;
|
||||
typedef typename distribution_type::result_type result_type;
|
||||
private:
|
||||
typedef std::iterator<
|
||||
std::input_iterator_tag,
|
||||
result_type,
|
||||
std::ptrdiff_t,
|
||||
result_type const*,
|
||||
result_type const&
|
||||
> base_type;
|
||||
public:
|
||||
typedef typename base_type::iterator_category iterator_category;
|
||||
typedef typename base_type::value_type value_type;
|
||||
typedef typename base_type::difference_type difference_type;
|
||||
typedef typename base_type::pointer pointer;
|
||||
typedef typename base_type::reference reference;
|
||||
private:
|
||||
result_type result_;
|
||||
engine_type engine_;
|
||||
distribution_type distribution_;
|
||||
public:
|
||||
//random_result() = default; // ???
|
||||
SPROUT_CONSTEXPR random_result()
|
||||
: result_()
|
||||
, engine_()
|
||||
, distribution_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_result(
|
||||
result_type result,
|
||||
engine_type const& engine,
|
||||
distribution_type const& distribution
|
||||
)
|
||||
: result_(result)
|
||||
, engine_(engine)
|
||||
, distribution_(distribution)
|
||||
{}
|
||||
SPROUT_CONSTEXPR operator result_type() const {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR random_result operator()() const {
|
||||
return distribution_(engine_);
|
||||
}
|
||||
result_type& result() {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type const& result() const {
|
||||
return result_;
|
||||
}
|
||||
engine_type& engine() {
|
||||
return engine_;
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_type const& engine() const {
|
||||
return engine_;
|
||||
}
|
||||
distribution_type& distribution() {
|
||||
return distribution_;
|
||||
}
|
||||
SPROUT_CONSTEXPR distribution_type const& distribution() const {
|
||||
return distribution_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return distribution_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return distribution_.max();
|
||||
}
|
||||
void swap(random_result& other) {
|
||||
using std::swap;
|
||||
swap(result_, other.result_);
|
||||
swap(engine_, other.engine_);
|
||||
swap(distribution_, other.distribution_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) {
|
||||
return lhs.result_ == rhs.result_
|
||||
&& lhs.engine_ == rhs.engine_
|
||||
&& lhs.distribution_ == rhs.distribution_
|
||||
;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator*() const {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR pointer operator->() const {
|
||||
return &result_;
|
||||
}
|
||||
random_result& operator++() {
|
||||
random_result temp((*this)());
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
random_result operator++(int) {
|
||||
random_result result(*this);
|
||||
++*this;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
template<typename Engine, typename Distribution>
|
||||
class random_result<
|
||||
Engine,
|
||||
Distribution,
|
||||
typename std::enable_if<std::is_same<Distribution, void>::value>::type
|
||||
>
|
||||
: public std::iterator<
|
||||
std::input_iterator_tag,
|
||||
typename Engine::result_type,
|
||||
std::ptrdiff_t,
|
||||
typename Engine::result_type const*,
|
||||
typename Engine::result_type const&
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef Engine engine_type;
|
||||
typedef typename engine_type::result_type result_type;
|
||||
private:
|
||||
typedef std::iterator<
|
||||
std::input_iterator_tag,
|
||||
result_type,
|
||||
std::ptrdiff_t,
|
||||
result_type const*,
|
||||
result_type const&
|
||||
> base_type;
|
||||
public:
|
||||
typedef typename base_type::iterator_category iterator_category;
|
||||
typedef typename base_type::value_type value_type;
|
||||
typedef typename base_type::difference_type difference_type;
|
||||
typedef typename base_type::pointer pointer;
|
||||
typedef typename base_type::reference reference;
|
||||
private:
|
||||
result_type result_;
|
||||
engine_type engine_;
|
||||
public:
|
||||
//random_result() = default; // ???
|
||||
SPROUT_CONSTEXPR random_result()
|
||||
: result_()
|
||||
, engine_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_result(
|
||||
result_type result,
|
||||
engine_type const& engine
|
||||
)
|
||||
: result_(result)
|
||||
, engine_(engine)
|
||||
{}
|
||||
SPROUT_CONSTEXPR operator result_type() const {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR random_result operator()() const {
|
||||
return engine_();
|
||||
}
|
||||
result_type& result() {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type const& result() const {
|
||||
return result_;
|
||||
}
|
||||
engine_type& engine() {
|
||||
return engine_;
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_type const& engine() const {
|
||||
return engine_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return engine_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return engine_.max();
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) {
|
||||
return lhs.result_ == rhs.result_
|
||||
&& lhs.engine_ == rhs.engine_
|
||||
;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
void swap(random_result& other) {
|
||||
using std::swap;
|
||||
swap(result_, other.result_);
|
||||
swap(engine_, other.engine_);
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator*() const {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR pointer operator->() const {
|
||||
return &result_;
|
||||
}
|
||||
random_result& operator++() {
|
||||
random_result temp((*this)());
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
random_result operator++(int) {
|
||||
random_result result(*this);
|
||||
random_result temp((*this)());
|
||||
temp.swap(*this);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
//
|
||||
// swap
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
void swap(
|
||||
sprout::random::random_result<Engine, Distribution>& lhs,
|
||||
sprout::random::random_result<Engine, Distribution>& rhs
|
||||
)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
//
|
||||
// next
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, Distribution> next(
|
||||
sprout::random::random_result<Engine, Distribution> const& it
|
||||
)
|
||||
{
|
||||
return it();
|
||||
}
|
||||
|
||||
using sprout::random::random_result;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP
|
||||
#define SPROUT_RANDOM_RANDOM_RESULT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/iterator/next.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// random_result
|
||||
//
|
||||
template<typename Engine, typename Distribution = void, typename Enable = void>
|
||||
class random_result;
|
||||
|
||||
template<typename Engine, typename Distribution>
|
||||
class random_result<
|
||||
Engine,
|
||||
Distribution,
|
||||
typename std::enable_if<!std::is_same<Distribution, void>::value>::type
|
||||
>
|
||||
: public std::iterator<
|
||||
std::input_iterator_tag,
|
||||
typename Distribution::result_type,
|
||||
std::ptrdiff_t,
|
||||
typename Distribution::result_type const*,
|
||||
typename Distribution::result_type const&
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef Engine engine_type;
|
||||
typedef Distribution distribution_type;
|
||||
typedef typename distribution_type::result_type result_type;
|
||||
private:
|
||||
typedef std::iterator<
|
||||
std::input_iterator_tag,
|
||||
result_type,
|
||||
std::ptrdiff_t,
|
||||
result_type const*,
|
||||
result_type const&
|
||||
> base_type;
|
||||
public:
|
||||
typedef typename base_type::iterator_category iterator_category;
|
||||
typedef typename base_type::value_type value_type;
|
||||
typedef typename base_type::difference_type difference_type;
|
||||
typedef typename base_type::pointer pointer;
|
||||
typedef typename base_type::reference reference;
|
||||
private:
|
||||
result_type result_;
|
||||
engine_type engine_;
|
||||
distribution_type distribution_;
|
||||
public:
|
||||
//random_result() = default; // ???
|
||||
SPROUT_CONSTEXPR random_result()
|
||||
: result_()
|
||||
, engine_()
|
||||
, distribution_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_result(
|
||||
result_type result,
|
||||
engine_type const& engine,
|
||||
distribution_type const& distribution
|
||||
)
|
||||
: result_(result)
|
||||
, engine_(engine)
|
||||
, distribution_(distribution)
|
||||
{}
|
||||
SPROUT_CONSTEXPR operator result_type() const {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR random_result operator()() const {
|
||||
return distribution_(engine_);
|
||||
}
|
||||
result_type& result() {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type const& result() const {
|
||||
return result_;
|
||||
}
|
||||
engine_type& engine() {
|
||||
return engine_;
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_type const& engine() const {
|
||||
return engine_;
|
||||
}
|
||||
distribution_type& distribution() {
|
||||
return distribution_;
|
||||
}
|
||||
SPROUT_CONSTEXPR distribution_type const& distribution() const {
|
||||
return distribution_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return distribution_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return distribution_.max();
|
||||
}
|
||||
void swap(random_result& other) {
|
||||
using std::swap;
|
||||
swap(result_, other.result_);
|
||||
swap(engine_, other.engine_);
|
||||
swap(distribution_, other.distribution_);
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) {
|
||||
return lhs.result_ == rhs.result_
|
||||
&& lhs.engine_ == rhs.engine_
|
||||
&& lhs.distribution_ == rhs.distribution_
|
||||
;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator*() const {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR pointer operator->() const {
|
||||
return &result_;
|
||||
}
|
||||
random_result& operator++() {
|
||||
random_result temp((*this)());
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
random_result operator++(int) {
|
||||
random_result result(*this);
|
||||
++*this;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
template<typename Engine, typename Distribution>
|
||||
class random_result<
|
||||
Engine,
|
||||
Distribution,
|
||||
typename std::enable_if<std::is_same<Distribution, void>::value>::type
|
||||
>
|
||||
: public std::iterator<
|
||||
std::input_iterator_tag,
|
||||
typename Engine::result_type,
|
||||
std::ptrdiff_t,
|
||||
typename Engine::result_type const*,
|
||||
typename Engine::result_type const&
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef Engine engine_type;
|
||||
typedef typename engine_type::result_type result_type;
|
||||
private:
|
||||
typedef std::iterator<
|
||||
std::input_iterator_tag,
|
||||
result_type,
|
||||
std::ptrdiff_t,
|
||||
result_type const*,
|
||||
result_type const&
|
||||
> base_type;
|
||||
public:
|
||||
typedef typename base_type::iterator_category iterator_category;
|
||||
typedef typename base_type::value_type value_type;
|
||||
typedef typename base_type::difference_type difference_type;
|
||||
typedef typename base_type::pointer pointer;
|
||||
typedef typename base_type::reference reference;
|
||||
private:
|
||||
result_type result_;
|
||||
engine_type engine_;
|
||||
public:
|
||||
//random_result() = default; // ???
|
||||
SPROUT_CONSTEXPR random_result()
|
||||
: result_()
|
||||
, engine_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR random_result(
|
||||
result_type result,
|
||||
engine_type const& engine
|
||||
)
|
||||
: result_(result)
|
||||
, engine_(engine)
|
||||
{}
|
||||
SPROUT_CONSTEXPR operator result_type() const {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR random_result operator()() const {
|
||||
return engine_();
|
||||
}
|
||||
result_type& result() {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type const& result() const {
|
||||
return result_;
|
||||
}
|
||||
engine_type& engine() {
|
||||
return engine_;
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_type const& engine() const {
|
||||
return engine_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return engine_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return engine_.max();
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator==(random_result const& lhs, random_result const& rhs) {
|
||||
return lhs.result_ == rhs.result_
|
||||
&& lhs.engine_ == rhs.engine_
|
||||
;
|
||||
}
|
||||
friend SPROUT_CONSTEXPR bool operator!=(random_result const& lhs, random_result const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
void swap(random_result& other) {
|
||||
using std::swap;
|
||||
swap(result_, other.result_);
|
||||
swap(engine_, other.engine_);
|
||||
}
|
||||
SPROUT_CONSTEXPR reference operator*() const {
|
||||
return result_;
|
||||
}
|
||||
SPROUT_CONSTEXPR pointer operator->() const {
|
||||
return &result_;
|
||||
}
|
||||
random_result& operator++() {
|
||||
random_result temp((*this)());
|
||||
temp.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
random_result operator++(int) {
|
||||
random_result result(*this);
|
||||
random_result temp((*this)());
|
||||
temp.swap(*this);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
//
|
||||
// swap
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
void swap(
|
||||
sprout::random::random_result<Engine, Distribution>& lhs,
|
||||
sprout::random::random_result<Engine, Distribution>& rhs
|
||||
)
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
//
|
||||
// next
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, Distribution> next(
|
||||
sprout::random::random_result<Engine, Distribution> const& it
|
||||
)
|
||||
{
|
||||
return it();
|
||||
}
|
||||
|
||||
using sprout::random::random_result;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_RANDOM_RESULT_HPP
|
||||
|
||||
|
|
|
@ -1,92 +1,92 @@
|
|||
#ifndef SPROUT_RANDOM_UNIFORM_01_HPP
|
||||
#define SPROUT_RANDOM_UNIFORM_01_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <istream>
|
||||
#include <limits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// uniform_01
|
||||
//
|
||||
template<typename RealType = double>
|
||||
class uniform_01 {
|
||||
public:
|
||||
typedef RealType input_type;
|
||||
typedef RealType result_type;
|
||||
private:
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> generate_1(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
result_type result
|
||||
) const
|
||||
{
|
||||
return result < result_type(1)
|
||||
? sprout::random::random_result<Engine, uniform_01>(result, rnd.engine(), *this)
|
||||
: operator()(rnd.engine())
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> generate(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine> const& rnd
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate_1(
|
||||
eng,
|
||||
rnd,
|
||||
result_type(rnd.result() - eng.min()) * (
|
||||
result_type(1) / (
|
||||
result_type(eng.max() - eng.min()) + result_type(
|
||||
std::numeric_limits<base_result>::is_integer ? 1 : 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return result_type(0);
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return result_type(1);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> operator()(Engine const& eng) const {
|
||||
return generate(eng, eng());
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
uniform_01 const& rhs
|
||||
)
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
uniform_01 const& rhs
|
||||
)
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(uniform_01 const& lhs, uniform_01 const& rhs) {
|
||||
return true;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(uniform_01 const& lhs, uniform_01 const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::uniform_01;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_UNIFORM_01_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_UNIFORM_01_HPP
|
||||
#define SPROUT_RANDOM_UNIFORM_01_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <istream>
|
||||
#include <limits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// uniform_01
|
||||
//
|
||||
template<typename RealType = double>
|
||||
class uniform_01 {
|
||||
public:
|
||||
typedef RealType input_type;
|
||||
typedef RealType result_type;
|
||||
private:
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> generate_1(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
result_type result
|
||||
) const
|
||||
{
|
||||
return result < result_type(1)
|
||||
? sprout::random::random_result<Engine, uniform_01>(result, rnd.engine(), *this)
|
||||
: operator()(rnd.engine())
|
||||
;
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> generate(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine> const& rnd
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate_1(
|
||||
eng,
|
||||
rnd,
|
||||
result_type(rnd.result() - eng.min()) * (
|
||||
result_type(1) / (
|
||||
result_type(eng.max() - eng.min()) + result_type(
|
||||
std::numeric_limits<base_result>::is_integer ? 1 : 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return result_type(0);
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return result_type(1);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_01> operator()(Engine const& eng) const {
|
||||
return generate(eng, eng());
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
uniform_01 const& rhs
|
||||
)
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
uniform_01 const& rhs
|
||||
)
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(uniform_01 const& lhs, uniform_01 const& rhs) {
|
||||
return true;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(uniform_01 const& lhs, uniform_01 const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::uniform_01;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_UNIFORM_01_HPP
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,319 +1,319 @@
|
|||
#ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
||||
#define SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
||||
|
||||
#include <ios>
|
||||
#include <istream>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/detail/signed_unsigned_tools.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename T, typename Engine>
|
||||
struct generate_uniform_real_result {
|
||||
public:
|
||||
T result;
|
||||
Engine engine;
|
||||
};
|
||||
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_1(
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
T min_value,
|
||||
T max_value
|
||||
);
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_3(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
T result
|
||||
)
|
||||
{
|
||||
return result < max_value
|
||||
? sprout::random::detail::generate_uniform_real_result<T, Engine>{result, eng}
|
||||
: sprout::random::detail::generate_uniform_real_false_1(eng(), min_value, max_value)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_2(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
T numerator,
|
||||
T divisor
|
||||
)
|
||||
{
|
||||
return divisor > 0
|
||||
? numerator >= 0 && numerator <= divisor
|
||||
? sprout::random::detail::generate_uniform_real_false_3(
|
||||
eng,
|
||||
min_value,
|
||||
max_value,
|
||||
numerator / divisor * (max_value - min_value) + min_value
|
||||
)
|
||||
: throw "assert(numerator >= 0 && numerator <= divisor)"
|
||||
: throw "assert(divisor > 0)"
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_1(
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
T min_value,
|
||||
T max_value
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_real_false_2(
|
||||
rnd.engine(),
|
||||
min_value,
|
||||
max_value,
|
||||
static_cast<T>(rnd.result() - rnd.engine().min()),
|
||||
static_cast<T>(rnd.engine().max() - rnd.engine().min())
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
std::false_type
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_real_false_1(
|
||||
eng(),
|
||||
min_value,
|
||||
max_value
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_1(
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
T min_value,
|
||||
T max_value
|
||||
);
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_3(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
T result
|
||||
)
|
||||
{
|
||||
return result < max_value
|
||||
? sprout::random::detail::generate_uniform_real_result<T, Engine>{result, eng}
|
||||
: sprout::random::detail::generate_uniform_real_true_1(eng(), min_value, max_value)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_2(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
T numerator,
|
||||
T divisor
|
||||
)
|
||||
{
|
||||
return divisor > 0
|
||||
? numerator >= 0 && numerator <= divisor
|
||||
? sprout::random::detail::generate_uniform_real_true_3(
|
||||
eng,
|
||||
min_value,
|
||||
max_value,
|
||||
numerator / divisor * (max_value - min_value) + min_value
|
||||
)
|
||||
: throw "assert(numerator >= 0 && numerator <= divisor)"
|
||||
: throw "assert(divisor > 0)"
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_1(
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
T min_value,
|
||||
T max_value
|
||||
)
|
||||
{
|
||||
typedef T result_type;
|
||||
typedef typename Engine::result_type base_result;
|
||||
return sprout::random::detail::generate_uniform_real_true_2(
|
||||
rnd.engine(),
|
||||
min_value,
|
||||
max_value,
|
||||
static_cast<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
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
std::true_type
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_real_true_1(
|
||||
eng(),
|
||||
min_value,
|
||||
max_value
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_real(
|
||||
eng,
|
||||
min_value,
|
||||
max_value,
|
||||
std::is_integral<typename Engine::result_type>()
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
//
|
||||
// uniform_real_distribution
|
||||
//
|
||||
template<typename RealType = double>
|
||||
class uniform_real_distribution {
|
||||
public:
|
||||
typedef RealType input_type;
|
||||
typedef RealType result_type;
|
||||
private:
|
||||
static SPROUT_CONSTEXPR RealType arg_check(RealType min_arg, RealType max_arg) {
|
||||
return min_arg <= max_arg
|
||||
? min_arg
|
||||
: throw "assert(min_arg <= max_arg)"
|
||||
;
|
||||
}
|
||||
public:
|
||||
//
|
||||
// param_type
|
||||
//
|
||||
class param_type {
|
||||
public:
|
||||
typedef uniform_real_distribution distribution_type;
|
||||
private:
|
||||
RealType min_;
|
||||
RealType max_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR param_type()
|
||||
: min_(RealType(0.0))
|
||||
, max_(RealType(1.0))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit param_type(RealType min_arg, RealType max_arg = RealType(1.0))
|
||||
: min_(arg_check(min_arg, max_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
SPROUT_CONSTEXPR RealType a() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR RealType b() const {
|
||||
return max_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.min_ >> std::ws >> rhs.max_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.min_ << " " << rhs.max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
|
||||
return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
private:
|
||||
result_type min_;
|
||||
result_type max_;
|
||||
private:
|
||||
template<typename Engine, typename Result>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_real_distribution> generate(Result const& rnd) const {
|
||||
return sprout::random::random_result<Engine, uniform_real_distribution>(
|
||||
rnd.result,
|
||||
rnd.engine,
|
||||
*this
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR uniform_real_distribution()
|
||||
: min_(RealType(0.0))
|
||||
, max_(RealType(1.0))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit uniform_real_distribution(RealType min_arg, RealType max_arg = RealType(1.0))
|
||||
: min_(arg_check(min_arg, max_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
explicit uniform_real_distribution(param_type const& parm)
|
||||
: min_(parm.a())
|
||||
, max_(parm.b())
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type a() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type b() const {
|
||||
return max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR param_type param() const {
|
||||
return param_type(min_, max_);
|
||||
}
|
||||
void param(param_type const& parm) {
|
||||
min_ = parm.a();
|
||||
max_ = parm.b();
|
||||
}
|
||||
template<typename Engine>
|
||||
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_));
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
uniform_real_distribution const& rhs
|
||||
)
|
||||
{
|
||||
param_type parm;
|
||||
return lhs >> parm;
|
||||
param(parm);
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
uniform_real_distribution const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) {
|
||||
return lhs.param() == rhs.param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::uniform_real_distribution;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
||||
#define SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
||||
|
||||
#include <ios>
|
||||
#include <istream>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/detail/signed_unsigned_tools.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
namespace detail {
|
||||
template<typename T, typename Engine>
|
||||
struct generate_uniform_real_result {
|
||||
public:
|
||||
T result;
|
||||
Engine engine;
|
||||
};
|
||||
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_1(
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
T min_value,
|
||||
T max_value
|
||||
);
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_3(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
T result
|
||||
)
|
||||
{
|
||||
return result < max_value
|
||||
? sprout::random::detail::generate_uniform_real_result<T, Engine>{result, eng}
|
||||
: sprout::random::detail::generate_uniform_real_false_1(eng(), min_value, max_value)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_2(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
T numerator,
|
||||
T divisor
|
||||
)
|
||||
{
|
||||
return divisor > 0
|
||||
? numerator >= 0 && numerator <= divisor
|
||||
? sprout::random::detail::generate_uniform_real_false_3(
|
||||
eng,
|
||||
min_value,
|
||||
max_value,
|
||||
numerator / divisor * (max_value - min_value) + min_value
|
||||
)
|
||||
: throw "assert(numerator >= 0 && numerator <= divisor)"
|
||||
: throw "assert(divisor > 0)"
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_false_1(
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
T min_value,
|
||||
T max_value
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_real_false_2(
|
||||
rnd.engine(),
|
||||
min_value,
|
||||
max_value,
|
||||
static_cast<T>(rnd.result() - rnd.engine().min()),
|
||||
static_cast<T>(rnd.engine().max() - rnd.engine().min())
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
std::false_type
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_real_false_1(
|
||||
eng(),
|
||||
min_value,
|
||||
max_value
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_1(
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
T min_value,
|
||||
T max_value
|
||||
);
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_3(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
T result
|
||||
)
|
||||
{
|
||||
return result < max_value
|
||||
? sprout::random::detail::generate_uniform_real_result<T, Engine>{result, eng}
|
||||
: sprout::random::detail::generate_uniform_real_true_1(eng(), min_value, max_value)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_2(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
T numerator,
|
||||
T divisor
|
||||
)
|
||||
{
|
||||
return divisor > 0
|
||||
? numerator >= 0 && numerator <= divisor
|
||||
? sprout::random::detail::generate_uniform_real_true_3(
|
||||
eng,
|
||||
min_value,
|
||||
max_value,
|
||||
numerator / divisor * (max_value - min_value) + min_value
|
||||
)
|
||||
: throw "assert(numerator >= 0 && numerator <= divisor)"
|
||||
: throw "assert(divisor > 0)"
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real_true_1(
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
T min_value,
|
||||
T max_value
|
||||
)
|
||||
{
|
||||
typedef T result_type;
|
||||
typedef typename Engine::result_type base_result;
|
||||
return sprout::random::detail::generate_uniform_real_true_2(
|
||||
rnd.engine(),
|
||||
min_value,
|
||||
max_value,
|
||||
static_cast<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
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value,
|
||||
std::true_type
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_real_true_1(
|
||||
eng(),
|
||||
min_value,
|
||||
max_value
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename T>
|
||||
SPROUT_CONSTEXPR sprout::random::detail::generate_uniform_real_result<T, Engine> generate_uniform_real(
|
||||
Engine const& eng,
|
||||
T min_value,
|
||||
T max_value
|
||||
)
|
||||
{
|
||||
return sprout::random::detail::generate_uniform_real(
|
||||
eng,
|
||||
min_value,
|
||||
max_value,
|
||||
std::is_integral<typename Engine::result_type>()
|
||||
);
|
||||
}
|
||||
} // namespace detail
|
||||
//
|
||||
// uniform_real_distribution
|
||||
//
|
||||
template<typename RealType = double>
|
||||
class uniform_real_distribution {
|
||||
public:
|
||||
typedef RealType input_type;
|
||||
typedef RealType result_type;
|
||||
private:
|
||||
static SPROUT_CONSTEXPR RealType arg_check(RealType min_arg, RealType max_arg) {
|
||||
return min_arg <= max_arg
|
||||
? min_arg
|
||||
: throw "assert(min_arg <= max_arg)"
|
||||
;
|
||||
}
|
||||
public:
|
||||
//
|
||||
// param_type
|
||||
//
|
||||
class param_type {
|
||||
public:
|
||||
typedef uniform_real_distribution distribution_type;
|
||||
private:
|
||||
RealType min_;
|
||||
RealType max_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR param_type()
|
||||
: min_(RealType(0.0))
|
||||
, max_(RealType(1.0))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit param_type(RealType min_arg, RealType max_arg = RealType(1.0))
|
||||
: min_(arg_check(min_arg, max_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
SPROUT_CONSTEXPR RealType a() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR RealType b() const {
|
||||
return max_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.min_ >> std::ws >> rhs.max_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.min_ << " " << rhs.max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
|
||||
return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
private:
|
||||
result_type min_;
|
||||
result_type max_;
|
||||
private:
|
||||
template<typename Engine, typename Result>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_real_distribution> generate(Result const& rnd) const {
|
||||
return sprout::random::random_result<Engine, uniform_real_distribution>(
|
||||
rnd.result,
|
||||
rnd.engine,
|
||||
*this
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR uniform_real_distribution()
|
||||
: min_(RealType(0.0))
|
||||
, max_(RealType(1.0))
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit uniform_real_distribution(RealType min_arg, RealType max_arg = RealType(1.0))
|
||||
: min_(arg_check(min_arg, max_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
explicit uniform_real_distribution(param_type const& parm)
|
||||
: min_(parm.a())
|
||||
, max_(parm.b())
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type a() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type b() const {
|
||||
return max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR param_type param() const {
|
||||
return param_type(min_, max_);
|
||||
}
|
||||
void param(param_type const& parm) {
|
||||
min_ = parm.a();
|
||||
max_ = parm.b();
|
||||
}
|
||||
template<typename Engine>
|
||||
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_));
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
uniform_real_distribution const& rhs
|
||||
)
|
||||
{
|
||||
param_type parm;
|
||||
return lhs >> parm;
|
||||
param(parm);
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
uniform_real_distribution const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) {
|
||||
return lhs.param() == rhs.param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(uniform_real_distribution const& lhs, uniform_real_distribution const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::uniform_real_distribution;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_UNIFORM_REAL_DISTRIBUTION_HPP
|
||||
|
||||
|
|
|
@ -1,255 +1,255 @@
|
|||
#ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP
|
||||
#define SPROUT_RANDOM_UNIFORM_SMALLINT_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <istream>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/detail/signed_unsigned_tools.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/random/uniform_01.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// uniform_smallint
|
||||
//
|
||||
template<typename IntType = int>
|
||||
class uniform_smallint {
|
||||
public:
|
||||
typedef IntType input_type;
|
||||
typedef IntType result_type;
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType arg_check(IntType min_arg, IntType max_arg) {
|
||||
return min_arg <= max_arg
|
||||
? min_arg
|
||||
: throw "assert(min_arg <= max_arg)"
|
||||
;
|
||||
}
|
||||
public:
|
||||
//
|
||||
// param_type
|
||||
//
|
||||
class param_type {
|
||||
public:
|
||||
typedef uniform_smallint distribution_type;
|
||||
private:
|
||||
IntType min_;
|
||||
IntType max_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR param_type()
|
||||
: min_(0)
|
||||
, max_(9)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit param_type(IntType min_arg, IntType max_arg = 9)
|
||||
: min_(arg_check(min_arg, max_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
SPROUT_CONSTEXPR IntType a() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR IntType b() const {
|
||||
return max_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.min_ >> std::ws >> rhs.max_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.min_ << " " << rhs.max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
|
||||
return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
private:
|
||||
result_type min_;
|
||||
result_type max_;
|
||||
private:
|
||||
template<typename Engine, typename RangeType, typename BaseUnsigned>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_2(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
RangeType range,
|
||||
BaseUnsigned base_range,
|
||||
BaseUnsigned val
|
||||
) const
|
||||
{
|
||||
return range >= base_range
|
||||
? sprout::random::random_result<Engine, uniform_smallint>(
|
||||
sprout::random::detail::add<RangeType, result_type>()(static_cast<RangeType>(val), min_),
|
||||
rnd.engine(),
|
||||
*this
|
||||
)
|
||||
: sprout::random::random_result<Engine, uniform_smallint>(
|
||||
sprout::random::detail::add<RangeType, result_type>()(static_cast<RangeType>(val % (static_cast<BaseUnsigned>(range) + 1)), min_),
|
||||
rnd.engine(),
|
||||
*this
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename RangeType, typename BaseUnsigned>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_1(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
RangeType range,
|
||||
BaseUnsigned base_range
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate_true_2(
|
||||
eng,
|
||||
rnd,
|
||||
range,
|
||||
base_range,
|
||||
BaseUnsigned(sprout::random::detail::subtract<base_result>()(rnd.result(), eng.min()))
|
||||
);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate(
|
||||
Engine const& eng,
|
||||
std::true_type
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
typedef typename std::make_unsigned<base_result>::type base_unsigned;
|
||||
typedef typename std::make_unsigned<result_type>::type range_type;
|
||||
return generate_true_1(
|
||||
eng,
|
||||
eng(),
|
||||
range_type(sprout::random::detail::subtract<result_type>()(max_, min_)),
|
||||
base_unsigned(sprout::random::detail::subtract<result_type>()(eng.max(), eng.min()))
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename RangeType>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_false_2(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine, sprout::random::uniform_01<typename Engine::result_type> > const& rnd,
|
||||
RangeType range,
|
||||
RangeType offset
|
||||
) const
|
||||
{
|
||||
return offset > range
|
||||
? sprout::random::random_result<Engine, uniform_smallint>(
|
||||
max_,
|
||||
rnd.engine(),
|
||||
*this
|
||||
)
|
||||
: sprout::random::random_result<Engine, uniform_smallint>(
|
||||
sprout::random::detail::add<RangeType, result_type>()(offset , min_),
|
||||
rnd.engine(),
|
||||
*this
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename RangeType>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_false_1(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine, sprout::random::uniform_01<typename Engine::result_type> > const& rnd,
|
||||
RangeType range
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate_false_2(
|
||||
eng,
|
||||
rnd,
|
||||
RangeType(sprout::random::detail::subtract<result_type>()(max_, min_)),
|
||||
RangeType(static_cast<RangeType>(rnd.result() * (static_cast<base_result>(range) + 1)))
|
||||
);
|
||||
}
|
||||
template<class Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate(
|
||||
Engine const& eng,
|
||||
std::false_type
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
typedef typename std::make_unsigned<result_type>::type range_type;
|
||||
return generate_false_1(
|
||||
eng,
|
||||
sprout::random::uniform_01<base_result>()(eng),
|
||||
range_type(sprout::random::detail::subtract<result_type>()(max_, min_))
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR uniform_smallint()
|
||||
: min_(0)
|
||||
, max_(9)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit uniform_smallint(IntType min_arg, IntType max_arg = 9)
|
||||
: min_(arg_check(min_arg, max_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
explicit uniform_smallint(param_type const& parm)
|
||||
: min_(parm.a())
|
||||
, max_(parm.b())
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type a() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type b() const {
|
||||
return max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR param_type param() const {
|
||||
return param_type(min_, max_);
|
||||
}
|
||||
void param(param_type const& parm) {
|
||||
min_ = parm.a();
|
||||
max_ = parm.b();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> operator()(Engine const& eng) const {
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate(eng, typename std::is_integral<base_result>::type());
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
uniform_smallint const& rhs
|
||||
)
|
||||
{
|
||||
param_type parm;
|
||||
return lhs >> parm;
|
||||
param(parm);
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
uniform_smallint const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(uniform_smallint const& lhs, uniform_smallint const& rhs) {
|
||||
return lhs.param() == rhs.param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(uniform_smallint const& lhs, uniform_smallint const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::uniform_smallint;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP
|
||||
#define SPROUT_RANDOM_UNIFORM_SMALLINT_HPP
|
||||
|
||||
#include <iosfwd>
|
||||
#include <istream>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/random/detail/signed_unsigned_tools.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
#include <sprout/random/uniform_01.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// uniform_smallint
|
||||
//
|
||||
template<typename IntType = int>
|
||||
class uniform_smallint {
|
||||
public:
|
||||
typedef IntType input_type;
|
||||
typedef IntType result_type;
|
||||
private:
|
||||
static SPROUT_CONSTEXPR IntType arg_check(IntType min_arg, IntType max_arg) {
|
||||
return min_arg <= max_arg
|
||||
? min_arg
|
||||
: throw "assert(min_arg <= max_arg)"
|
||||
;
|
||||
}
|
||||
public:
|
||||
//
|
||||
// param_type
|
||||
//
|
||||
class param_type {
|
||||
public:
|
||||
typedef uniform_smallint distribution_type;
|
||||
private:
|
||||
IntType min_;
|
||||
IntType max_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR param_type()
|
||||
: min_(0)
|
||||
, max_(9)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit param_type(IntType min_arg, IntType max_arg = 9)
|
||||
: min_(arg_check(min_arg, max_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
SPROUT_CONSTEXPR IntType a() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR IntType b() const {
|
||||
return max_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs >> rhs.min_ >> std::ws >> rhs.max_;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
param_type const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << rhs.min_ << " " << rhs.max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(param_type const& lhs, param_type const& rhs) {
|
||||
return lhs.min_ == rhs.min_ && lhs.max_ == rhs.max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(param_type const& lhs, param_type const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
private:
|
||||
result_type min_;
|
||||
result_type max_;
|
||||
private:
|
||||
template<typename Engine, typename RangeType, typename BaseUnsigned>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_2(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
RangeType range,
|
||||
BaseUnsigned base_range,
|
||||
BaseUnsigned val
|
||||
) const
|
||||
{
|
||||
return range >= base_range
|
||||
? sprout::random::random_result<Engine, uniform_smallint>(
|
||||
sprout::random::detail::add<RangeType, result_type>()(static_cast<RangeType>(val), min_),
|
||||
rnd.engine(),
|
||||
*this
|
||||
)
|
||||
: sprout::random::random_result<Engine, uniform_smallint>(
|
||||
sprout::random::detail::add<RangeType, result_type>()(static_cast<RangeType>(val % (static_cast<BaseUnsigned>(range) + 1)), min_),
|
||||
rnd.engine(),
|
||||
*this
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename RangeType, typename BaseUnsigned>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_true_1(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine> const& rnd,
|
||||
RangeType range,
|
||||
BaseUnsigned base_range
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate_true_2(
|
||||
eng,
|
||||
rnd,
|
||||
range,
|
||||
base_range,
|
||||
BaseUnsigned(sprout::random::detail::subtract<base_result>()(rnd.result(), eng.min()))
|
||||
);
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate(
|
||||
Engine const& eng,
|
||||
std::true_type
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
typedef typename std::make_unsigned<base_result>::type base_unsigned;
|
||||
typedef typename std::make_unsigned<result_type>::type range_type;
|
||||
return generate_true_1(
|
||||
eng,
|
||||
eng(),
|
||||
range_type(sprout::random::detail::subtract<result_type>()(max_, min_)),
|
||||
base_unsigned(sprout::random::detail::subtract<result_type>()(eng.max(), eng.min()))
|
||||
);
|
||||
}
|
||||
template<typename Engine, typename RangeType>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_false_2(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine, sprout::random::uniform_01<typename Engine::result_type> > const& rnd,
|
||||
RangeType range,
|
||||
RangeType offset
|
||||
) const
|
||||
{
|
||||
return offset > range
|
||||
? sprout::random::random_result<Engine, uniform_smallint>(
|
||||
max_,
|
||||
rnd.engine(),
|
||||
*this
|
||||
)
|
||||
: sprout::random::random_result<Engine, uniform_smallint>(
|
||||
sprout::random::detail::add<RangeType, result_type>()(offset , min_),
|
||||
rnd.engine(),
|
||||
*this
|
||||
)
|
||||
;
|
||||
}
|
||||
template<typename Engine, typename RangeType>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate_false_1(
|
||||
Engine const& eng,
|
||||
sprout::random::random_result<Engine, sprout::random::uniform_01<typename Engine::result_type> > const& rnd,
|
||||
RangeType range
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate_false_2(
|
||||
eng,
|
||||
rnd,
|
||||
RangeType(sprout::random::detail::subtract<result_type>()(max_, min_)),
|
||||
RangeType(static_cast<RangeType>(rnd.result() * (static_cast<base_result>(range) + 1)))
|
||||
);
|
||||
}
|
||||
template<class Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> generate(
|
||||
Engine const& eng,
|
||||
std::false_type
|
||||
) const
|
||||
{
|
||||
typedef typename Engine::result_type base_result;
|
||||
typedef typename std::make_unsigned<result_type>::type range_type;
|
||||
return generate_false_1(
|
||||
eng,
|
||||
sprout::random::uniform_01<base_result>()(eng),
|
||||
range_type(sprout::random::detail::subtract<result_type>()(max_, min_))
|
||||
);
|
||||
}
|
||||
public:
|
||||
SPROUT_CONSTEXPR uniform_smallint()
|
||||
: min_(0)
|
||||
, max_(9)
|
||||
{}
|
||||
SPROUT_CONSTEXPR explicit uniform_smallint(IntType min_arg, IntType max_arg = 9)
|
||||
: min_(arg_check(min_arg, max_arg))
|
||||
, max_(max_arg)
|
||||
{}
|
||||
explicit uniform_smallint(param_type const& parm)
|
||||
: min_(parm.a())
|
||||
, max_(parm.b())
|
||||
{}
|
||||
SPROUT_CONSTEXPR result_type a() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type b() const {
|
||||
return max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return min_;
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return max_;
|
||||
}
|
||||
SPROUT_CONSTEXPR param_type param() const {
|
||||
return param_type(min_, max_);
|
||||
}
|
||||
void param(param_type const& parm) {
|
||||
min_ = parm.a();
|
||||
max_ = parm.b();
|
||||
}
|
||||
template<typename Engine>
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<Engine, uniform_smallint> operator()(Engine const& eng) const {
|
||||
typedef typename Engine::result_type base_result;
|
||||
return generate(eng, typename std::is_integral<base_result>::type());
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator>>(
|
||||
std::basic_istream<Elem, Traits>& lhs,
|
||||
uniform_smallint const& rhs
|
||||
)
|
||||
{
|
||||
param_type parm;
|
||||
return lhs >> parm;
|
||||
param(parm);
|
||||
return lhs;
|
||||
}
|
||||
template<typename Elem, typename Traits>
|
||||
friend std::basic_ostream<Elem, Traits>& operator<<(
|
||||
std::basic_ostream<Elem, Traits>& lhs,
|
||||
uniform_smallint const& rhs
|
||||
)
|
||||
{
|
||||
return lhs << param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator==(uniform_smallint const& lhs, uniform_smallint const& rhs) {
|
||||
return lhs.param() == rhs.param();
|
||||
}
|
||||
SPROUT_CONSTEXPR friend bool operator!=(uniform_smallint const& lhs, uniform_smallint const& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
};
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::uniform_smallint;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_UNIFORM_SMALLINT_HPP
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP
|
||||
#define SPROUT_RANDOM_UNIQUE_SEED_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sprout/preprocessor/unique_string.hpp>
|
||||
|
||||
//
|
||||
// SPROUT_UNIQUE_SEED
|
||||
//
|
||||
#define SPROUT_UNIQUE_SEED (::sprout::hash_value(SPROUT_PP_UNIQUE_STRING))
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP
|
||||
#define SPROUT_RANDOM_UNIQUE_SEED_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/functional/hash/hash.hpp>
|
||||
#include <sprout/preprocessor/unique_string.hpp>
|
||||
|
||||
//
|
||||
// SPROUT_UNIQUE_SEED
|
||||
//
|
||||
#define SPROUT_UNIQUE_SEED (::sprout::hash_value(SPROUT_PP_UNIQUE_STRING))
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_UNIQUE_SEED_HPP
|
||||
|
||||
|
|
|
@ -1,84 +1,84 @@
|
|||
#ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP
|
||||
#define SPROUT_RANDOM_VARIATE_GENERATOR_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/detail/if.hpp>
|
||||
#include <sprout/random/detail/ptr_helper.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// variate_generator
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
class variate_generator {
|
||||
private:
|
||||
typedef sprout::random::detail::ptr_helper<Engine> engine_helper_type;
|
||||
typedef sprout::random::detail::ptr_helper<Distribution> distribution_helper_type;
|
||||
public:
|
||||
typedef typename engine_helper_type::value_type engine_value_type;
|
||||
typedef typename distribution_helper_type::value_type distribution_value_type;
|
||||
typedef typename engine_helper_type::reference_type engine_reference_type;
|
||||
typedef typename distribution_helper_type::reference_type distribution_reference_type;
|
||||
typedef typename engine_helper_type::const_reference_type engine_const_reference_type;
|
||||
typedef typename distribution_helper_type::const_reference_type distribution_const_reference_type;
|
||||
typedef typename engine_helper_type::rvalue_type engine_param_type;
|
||||
typedef typename distribution_helper_type::rvalue_type distribution_param_type;
|
||||
public:
|
||||
typedef Engine engine_type;
|
||||
typedef Distribution distribution_type;
|
||||
typedef typename distribution_value_type::result_type result_type;
|
||||
private:
|
||||
engine_type engine_;
|
||||
distribution_type distribution_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR variate_generator(
|
||||
engine_param_type engine,
|
||||
distribution_param_type distribution
|
||||
)
|
||||
: engine_(engine)
|
||||
, distribution_(distribution)
|
||||
{}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<engine_value_type, distribution_value_type> operator()() const {
|
||||
return distribution_(engine_);
|
||||
}
|
||||
engine_reference_type engine() {
|
||||
return engine_helper_type::ref(engine_);
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_const_reference_type engine() const {
|
||||
return engine_helper_type::ref(engine_);
|
||||
}
|
||||
distribution_reference_type distribution() {
|
||||
return distribution_helper_type::ref(distribution_);
|
||||
}
|
||||
SPROUT_CONSTEXPR distribution_const_reference_type distribution() const {
|
||||
return distribution_helper_type::ref(distribution_);
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return distribution_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return distribution_.max();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// combine
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR sprout::random::variate_generator<Engine const&, Distribution const&> combine(
|
||||
Engine const& engine,
|
||||
Distribution const& distribution
|
||||
)
|
||||
{
|
||||
return sprout::random::variate_generator<Engine const&, Distribution const&>(engine, distribution);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::variate_generator;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP
|
||||
|
||||
#ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP
|
||||
#define SPROUT_RANDOM_VARIATE_GENERATOR_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/detail/if.hpp>
|
||||
#include <sprout/random/detail/ptr_helper.hpp>
|
||||
#include <sprout/random/random_result.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace random {
|
||||
//
|
||||
// variate_generator
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
class variate_generator {
|
||||
private:
|
||||
typedef sprout::random::detail::ptr_helper<Engine> engine_helper_type;
|
||||
typedef sprout::random::detail::ptr_helper<Distribution> distribution_helper_type;
|
||||
public:
|
||||
typedef typename engine_helper_type::value_type engine_value_type;
|
||||
typedef typename distribution_helper_type::value_type distribution_value_type;
|
||||
typedef typename engine_helper_type::reference_type engine_reference_type;
|
||||
typedef typename distribution_helper_type::reference_type distribution_reference_type;
|
||||
typedef typename engine_helper_type::const_reference_type engine_const_reference_type;
|
||||
typedef typename distribution_helper_type::const_reference_type distribution_const_reference_type;
|
||||
typedef typename engine_helper_type::rvalue_type engine_param_type;
|
||||
typedef typename distribution_helper_type::rvalue_type distribution_param_type;
|
||||
public:
|
||||
typedef Engine engine_type;
|
||||
typedef Distribution distribution_type;
|
||||
typedef typename distribution_value_type::result_type result_type;
|
||||
private:
|
||||
engine_type engine_;
|
||||
distribution_type distribution_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR variate_generator(
|
||||
engine_param_type engine,
|
||||
distribution_param_type distribution
|
||||
)
|
||||
: engine_(engine)
|
||||
, distribution_(distribution)
|
||||
{}
|
||||
SPROUT_CONSTEXPR sprout::random::random_result<engine_value_type, distribution_value_type> operator()() const {
|
||||
return distribution_(engine_);
|
||||
}
|
||||
engine_reference_type engine() {
|
||||
return engine_helper_type::ref(engine_);
|
||||
}
|
||||
SPROUT_CONSTEXPR engine_const_reference_type engine() const {
|
||||
return engine_helper_type::ref(engine_);
|
||||
}
|
||||
distribution_reference_type distribution() {
|
||||
return distribution_helper_type::ref(distribution_);
|
||||
}
|
||||
SPROUT_CONSTEXPR distribution_const_reference_type distribution() const {
|
||||
return distribution_helper_type::ref(distribution_);
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type min() const {
|
||||
return distribution_.min();
|
||||
}
|
||||
SPROUT_CONSTEXPR result_type max() const {
|
||||
return distribution_.max();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// combine
|
||||
//
|
||||
template<typename Engine, typename Distribution>
|
||||
SPROUT_CONSTEXPR sprout::random::variate_generator<Engine const&, Distribution const&> combine(
|
||||
Engine const& engine,
|
||||
Distribution const& distribution
|
||||
)
|
||||
{
|
||||
return sprout::random::variate_generator<Engine const&, Distribution const&>(engine, distribution);
|
||||
}
|
||||
} // namespace random
|
||||
|
||||
using sprout::random::variate_generator;
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_RANDOM_VARIATE_GENERATOR_HPP
|
||||
|
||||
|
|
|
@ -1,160 +1,160 @@
|
|||
#ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP
|
||||
#define SPROUT_UTILITY_VALUE_HOLDER_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct holder_helper {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T const& mutable_or_const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T const* mutable_or_const_pointer;
|
||||
typedef T const& param_type;
|
||||
typedef T holder_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR holder_type const& hold(param_type p) {
|
||||
return p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR reference ref(holder_type& r) {
|
||||
return r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) {
|
||||
return r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR pointer ptr(holder_type& r) {
|
||||
return &r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) {
|
||||
return &r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct holder_helper<T const> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T const& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T const& mutable_or_const_reference;
|
||||
typedef T const* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T const* mutable_or_const_pointer;
|
||||
typedef T const& param_type;
|
||||
typedef T holder_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR holder_type const& hold(param_type p) {
|
||||
return &p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR reference ref(holder_type& r) {
|
||||
return *r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) {
|
||||
return *r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR pointer ptr(holder_type& r) {
|
||||
return &r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) {
|
||||
return &r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct holder_helper<T&> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T& mutable_or_const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T* mutable_or_const_pointer;
|
||||
typedef T& param_type;
|
||||
typedef T* holder_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR holder_type hold(param_type p) {
|
||||
return &p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR reference ref(holder_type r) {
|
||||
return *r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR pointer ptr(holder_type r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct holder_helper<T const&> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T const& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T const& mutable_or_const_reference;
|
||||
typedef T const* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T const* mutable_or_const_pointer;
|
||||
typedef T const& param_type;
|
||||
typedef T const* holder_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR holder_type hold(param_type p) {
|
||||
return &p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR reference ref(holder_type r) {
|
||||
return *r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR pointer ptr(holder_type r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
//
|
||||
// value_holder
|
||||
//
|
||||
template<typename T>
|
||||
class value_holder {
|
||||
public:
|
||||
typedef T type;
|
||||
private:
|
||||
typedef sprout::detail::holder_helper<type> helper_type;
|
||||
typedef typename helper_type::holder_type holder_type;
|
||||
public:
|
||||
typedef typename helper_type::value_type value_type;
|
||||
typedef typename helper_type::reference reference;
|
||||
typedef typename helper_type::const_reference const_reference;
|
||||
typedef typename helper_type::mutable_or_const_reference mutable_or_const_reference;
|
||||
typedef typename helper_type::pointer pointer;
|
||||
typedef typename helper_type::const_pointer const_pointer;
|
||||
typedef typename helper_type::mutable_or_const_pointer mutable_or_const_pointer;
|
||||
typedef typename helper_type::param_type param_type;
|
||||
private:
|
||||
holder_type holder_;
|
||||
public:
|
||||
value_holder() = default;
|
||||
SPROUT_CONSTEXPR explicit value_holder(param_type p)
|
||||
: holder_(helper_type::hold(p))
|
||||
{}
|
||||
operator reference() {
|
||||
return helper_type::ref(holder_);
|
||||
}
|
||||
SPROUT_CONSTEXPR operator const_reference() const {
|
||||
return helper_type::ref(holder_);
|
||||
}
|
||||
reference get() {
|
||||
return helper_type::ref(holder_);
|
||||
}
|
||||
SPROUT_CONSTEXPR mutable_or_const_reference get() const {
|
||||
return helper_type::ref(holder_);
|
||||
}
|
||||
pointer get_pointer() {
|
||||
return helper_type::ptr(holder_);
|
||||
}
|
||||
SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer() const {
|
||||
return helper_type::ptr(holder_);
|
||||
}
|
||||
};
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP
|
||||
#ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP
|
||||
#define SPROUT_UTILITY_VALUE_HOLDER_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
struct holder_helper {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T const& mutable_or_const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T const* mutable_or_const_pointer;
|
||||
typedef T const& param_type;
|
||||
typedef T holder_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR holder_type const& hold(param_type p) {
|
||||
return p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR reference ref(holder_type& r) {
|
||||
return r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) {
|
||||
return r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR pointer ptr(holder_type& r) {
|
||||
return &r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) {
|
||||
return &r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct holder_helper<T const> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T const& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T const& mutable_or_const_reference;
|
||||
typedef T const* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T const* mutable_or_const_pointer;
|
||||
typedef T const& param_type;
|
||||
typedef T holder_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR holder_type const& hold(param_type p) {
|
||||
return &p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR reference ref(holder_type& r) {
|
||||
return *r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) {
|
||||
return *r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR pointer ptr(holder_type& r) {
|
||||
return &r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) {
|
||||
return &r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct holder_helper<T&> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T& mutable_or_const_reference;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T* mutable_or_const_pointer;
|
||||
typedef T& param_type;
|
||||
typedef T* holder_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR holder_type hold(param_type p) {
|
||||
return &p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR reference ref(holder_type r) {
|
||||
return *r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR pointer ptr(holder_type r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
template<typename T>
|
||||
struct holder_helper<T const&> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T const& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T const& mutable_or_const_reference;
|
||||
typedef T const* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T const* mutable_or_const_pointer;
|
||||
typedef T const& param_type;
|
||||
typedef T const* holder_type;
|
||||
public:
|
||||
static SPROUT_CONSTEXPR holder_type hold(param_type p) {
|
||||
return &p;
|
||||
}
|
||||
static SPROUT_CONSTEXPR reference ref(holder_type r) {
|
||||
return *r;
|
||||
}
|
||||
static SPROUT_CONSTEXPR pointer ptr(holder_type r) {
|
||||
return r;
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
//
|
||||
// value_holder
|
||||
//
|
||||
template<typename T>
|
||||
class value_holder {
|
||||
public:
|
||||
typedef T type;
|
||||
private:
|
||||
typedef sprout::detail::holder_helper<type> helper_type;
|
||||
typedef typename helper_type::holder_type holder_type;
|
||||
public:
|
||||
typedef typename helper_type::value_type value_type;
|
||||
typedef typename helper_type::reference reference;
|
||||
typedef typename helper_type::const_reference const_reference;
|
||||
typedef typename helper_type::mutable_or_const_reference mutable_or_const_reference;
|
||||
typedef typename helper_type::pointer pointer;
|
||||
typedef typename helper_type::const_pointer const_pointer;
|
||||
typedef typename helper_type::mutable_or_const_pointer mutable_or_const_pointer;
|
||||
typedef typename helper_type::param_type param_type;
|
||||
private:
|
||||
holder_type holder_;
|
||||
public:
|
||||
value_holder() = default;
|
||||
SPROUT_CONSTEXPR explicit value_holder(param_type p)
|
||||
: holder_(helper_type::hold(p))
|
||||
{}
|
||||
operator reference() {
|
||||
return helper_type::ref(holder_);
|
||||
}
|
||||
SPROUT_CONSTEXPR operator const_reference() const {
|
||||
return helper_type::ref(holder_);
|
||||
}
|
||||
reference get() {
|
||||
return helper_type::ref(holder_);
|
||||
}
|
||||
SPROUT_CONSTEXPR mutable_or_const_reference get() const {
|
||||
return helper_type::ref(holder_);
|
||||
}
|
||||
pointer get_pointer() {
|
||||
return helper_type::ptr(holder_);
|
||||
}
|
||||
SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer() const {
|
||||
return helper_type::ptr(holder_);
|
||||
}
|
||||
};
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_UTILITY_VALUE_HOLDER_HPP
|
||||
|
|
Loading…
Add table
Reference in a new issue