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

改行コード統一

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

View file

@ -1,8 +1,8 @@
#ifndef SPROUT_FUNCTIONAL_HASH_HPP
#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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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