// TJP COPYRIGHT HEADER #pragma once #include #include #include #include #define HAS_CPP_11 #ifdef HAS_CPP_11 #include #else #include namespace std { class default_random_engine { public: char operator ()() { return random(); } void seed(int seed=0) {} } ; typedef default_random_engine random_device; } #endif namespace tjp { namespace core { namespace random_detail { template T abs_(T t) { return std::abs(t); } template<> inline s128 abs_(s128 t) { return t > 0 ? t : -t; } template<> inline constexpr u64 abs_(u64 t) { return t; } template<> inline constexpr u32 abs_(u32 t) { return t; } template<> inline constexpr u16 abs_(u16 t) { return t; } template<> inline constexpr u8 abs_(u8 t) { return t; } #if defined(SYS_APPLE) || defined(SYS_IOS) template<> inline constexpr size_t abs_(size_t t) { return t; } #endif } // template class Random { public: using Generator = G; Generator generator; template T next () { T t; char *begin = (char *)&t; char *end = begin + sizeof(T); fill(begin, end); return t; } public: Random() {}; Random(Generator &&generator_) : generator(generator_) { } auto generate() { return generator(); } char nextChar () { return next(); } template T nextIndex (T r) { return nextInt() % r; } template T nextInt () { return random_detail::abs_(next()); } template T nextInt (T l, T r) { auto d = r - l + 1; return (random_detail::abs_(next()) % d) + l; } template T nextReal (T min=0, T max=1) { auto d = max - min; constexpr auto random_max = numeric_limits_ext::random_max; auto l = T(nextInt(0, random_max)); auto r = T(random_max); auto v = l/r * d + min; return v; } template T nextPositiveBits (size_t numBits) { auto v = next(); auto zeroBits = sizeof(v) * 8 - numBits; v = (v << zeroBits) >> zeroBits; return random_detail::abs_(v); } template T nextBits (size_t numBits) { auto v = next(); auto zeroBits = sizeof(v) * 8 - numBits; v = (v << zeroBits) >> zeroBits; return v; } void fill (char *begin, char *end) { if (begin == end) return; auto *i = begin; while (true) { auto v = generate(); for (auto j=0; j> 8; if (i == end) return; } } } }; template class RandomGeneratorSeeded { public: using Generator = T; Generator random; public: RandomGeneratorSeeded () : random(std::random_device()()) { } RandomGeneratorSeeded(int seed) : random(seed) { } auto operator()() { return random(); } } ; using ReliableRandom = Random>; using RealRandom = ReliableRandom; using FastRandom = Random>; using StandardRandomAdapter = FastRandom; extern StandardRandomAdapter StandardRandom; extern RealRandom StandardRealRandom; #if 1 template void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { std::random_device rd; std::mt19937 g(rd()); std::shuffle(__first, __last, g); } #else template void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) { std::random_shuffle(__first, __last); } #endif } // namespace } // namespace #ifdef TJP_CORE_HEADER_ONLY_SINGLE_FILE #include "Random.cpp" #endif