Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:39

0001 //===----------------------------------------------------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef _LIBCPP___CXX03___RANDOM_SHUFFLE_ORDER_ENGINE_H
0010 #define _LIBCPP___CXX03___RANDOM_SHUFFLE_ORDER_ENGINE_H
0011 
0012 #include <__cxx03/__algorithm/equal.h>
0013 #include <__cxx03/__config>
0014 #include <__cxx03/__random/is_seed_sequence.h>
0015 #include <__cxx03/__type_traits/enable_if.h>
0016 #include <__cxx03/__type_traits/integral_constant.h>
0017 #include <__cxx03/__type_traits/is_convertible.h>
0018 #include <__cxx03/__utility/move.h>
0019 #include <__cxx03/cstddef>
0020 #include <__cxx03/cstdint>
0021 #include <__cxx03/iosfwd>
0022 
0023 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0024 #  pragma GCC system_header
0025 #endif
0026 
0027 _LIBCPP_PUSH_MACROS
0028 #include <__cxx03/__undef_macros>
0029 
0030 _LIBCPP_BEGIN_NAMESPACE_STD
0031 
0032 template <uint64_t _Xp, uint64_t _Yp>
0033 struct __ugcd {
0034   static _LIBCPP_CONSTEXPR const uint64_t value = __ugcd<_Yp, _Xp % _Yp>::value;
0035 };
0036 
0037 template <uint64_t _Xp>
0038 struct __ugcd<_Xp, 0> {
0039   static _LIBCPP_CONSTEXPR const uint64_t value = _Xp;
0040 };
0041 
0042 template <uint64_t _Np, uint64_t _Dp>
0043 class __uratio {
0044   static_assert(_Dp != 0, "__uratio divide by 0");
0045   static _LIBCPP_CONSTEXPR const uint64_t __gcd = __ugcd<_Np, _Dp>::value;
0046 
0047 public:
0048   static _LIBCPP_CONSTEXPR const uint64_t num = _Np / __gcd;
0049   static _LIBCPP_CONSTEXPR const uint64_t den = _Dp / __gcd;
0050 
0051   typedef __uratio<num, den> type;
0052 };
0053 
0054 template <class _Engine, size_t __k>
0055 class _LIBCPP_TEMPLATE_VIS shuffle_order_engine {
0056   static_assert(0 < __k, "shuffle_order_engine invalid parameters");
0057 
0058 public:
0059   // types
0060   typedef typename _Engine::result_type result_type;
0061 
0062 private:
0063   _Engine __e_;
0064   result_type __v_[__k];
0065   result_type __y_;
0066 
0067 public:
0068   // engine characteristics
0069   static _LIBCPP_CONSTEXPR const size_t table_size = __k;
0070 
0071 #ifdef _LIBCPP_CXX03_LANG
0072   static const result_type _Min = _Engine::_Min;
0073   static const result_type _Max = _Engine::_Max;
0074 #else
0075   static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min();
0076   static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max();
0077 #endif
0078   static_assert(_Min < _Max, "shuffle_order_engine invalid parameters");
0079   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
0080   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
0081 
0082   static _LIBCPP_CONSTEXPR const unsigned long long _Rp = _Max - _Min + 1ull;
0083 
0084   // constructors and seeding functions
0085   _LIBCPP_HIDE_FROM_ABI shuffle_order_engine() { __init(); }
0086   _LIBCPP_HIDE_FROM_ABI explicit shuffle_order_engine(const _Engine& __e) : __e_(__e) { __init(); }
0087 #ifndef _LIBCPP_CXX03_LANG
0088   _LIBCPP_HIDE_FROM_ABI explicit shuffle_order_engine(_Engine&& __e) : __e_(std::move(__e)) { __init(); }
0089 #endif // _LIBCPP_CXX03_LANG
0090   _LIBCPP_HIDE_FROM_ABI explicit shuffle_order_engine(result_type __sd) : __e_(__sd) { __init(); }
0091   template <
0092       class _Sseq,
0093       __enable_if_t<__is_seed_sequence<_Sseq, shuffle_order_engine>::value && !is_convertible<_Sseq, _Engine>::value,
0094                     int> = 0>
0095   _LIBCPP_HIDE_FROM_ABI explicit shuffle_order_engine(_Sseq& __q) : __e_(__q) {
0096     __init();
0097   }
0098   _LIBCPP_HIDE_FROM_ABI void seed() {
0099     __e_.seed();
0100     __init();
0101   }
0102   _LIBCPP_HIDE_FROM_ABI void seed(result_type __sd) {
0103     __e_.seed(__sd);
0104     __init();
0105   }
0106   template <class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, shuffle_order_engine>::value, int> = 0>
0107   _LIBCPP_HIDE_FROM_ABI void seed(_Sseq& __q) {
0108     __e_.seed(__q);
0109     __init();
0110   }
0111 
0112   // generating functions
0113   _LIBCPP_HIDE_FROM_ABI result_type operator()() { return __eval(integral_constant<bool, _Rp != 0>()); }
0114   _LIBCPP_HIDE_FROM_ABI void discard(unsigned long long __z) {
0115     for (; __z; --__z)
0116       operator()();
0117   }
0118 
0119   // property functions
0120   _LIBCPP_HIDE_FROM_ABI const _Engine& base() const _NOEXCEPT { return __e_; }
0121 
0122 private:
0123   template <class _Eng, size_t _Kp>
0124   friend bool operator==(const shuffle_order_engine<_Eng, _Kp>& __x, const shuffle_order_engine<_Eng, _Kp>& __y);
0125 
0126   template <class _Eng, size_t _Kp>
0127   friend bool operator!=(const shuffle_order_engine<_Eng, _Kp>& __x, const shuffle_order_engine<_Eng, _Kp>& __y);
0128 
0129   template <class _CharT, class _Traits, class _Eng, size_t _Kp>
0130   friend basic_ostream<_CharT, _Traits>&
0131   operator<<(basic_ostream<_CharT, _Traits>& __os, const shuffle_order_engine<_Eng, _Kp>& __x);
0132 
0133   template <class _CharT, class _Traits, class _Eng, size_t _Kp>
0134   friend basic_istream<_CharT, _Traits>&
0135   operator>>(basic_istream<_CharT, _Traits>& __is, shuffle_order_engine<_Eng, _Kp>& __x);
0136 
0137   _LIBCPP_HIDE_FROM_ABI void __init() {
0138     for (size_t __i = 0; __i < __k; ++__i)
0139       __v_[__i] = __e_();
0140     __y_ = __e_();
0141   }
0142 
0143   _LIBCPP_HIDE_FROM_ABI result_type __eval(false_type) { return __eval2(integral_constant<bool, __k & 1>()); }
0144   _LIBCPP_HIDE_FROM_ABI result_type __eval(true_type) { return __eval(__uratio<__k, _Rp>()); }
0145 
0146   _LIBCPP_HIDE_FROM_ABI result_type __eval2(false_type) { return __eval(__uratio<__k / 2, 0x8000000000000000ull>()); }
0147   _LIBCPP_HIDE_FROM_ABI result_type __eval2(true_type) { return __evalf<__k, 0>(); }
0148 
0149   template <uint64_t _Np,
0150             uint64_t _Dp,
0151             __enable_if_t<(__uratio<_Np, _Dp>::num > 0xFFFFFFFFFFFFFFFFull / (_Max - _Min)), int> = 0>
0152   _LIBCPP_HIDE_FROM_ABI result_type __eval(__uratio<_Np, _Dp>) {
0153     return __evalf<__uratio<_Np, _Dp>::num, __uratio<_Np, _Dp>::den>();
0154   }
0155 
0156   template <uint64_t _Np,
0157             uint64_t _Dp,
0158             __enable_if_t<__uratio<_Np, _Dp>::num <= 0xFFFFFFFFFFFFFFFFull / (_Max - _Min), int> = 0>
0159   _LIBCPP_HIDE_FROM_ABI result_type __eval(__uratio<_Np, _Dp>) {
0160     const size_t __j = static_cast<size_t>(__uratio<_Np, _Dp>::num * (__y_ - _Min) / __uratio<_Np, _Dp>::den);
0161     __y_             = __v_[__j];
0162     __v_[__j]        = __e_();
0163     return __y_;
0164   }
0165 
0166   template <uint64_t __n, uint64_t __d>
0167   _LIBCPP_HIDE_FROM_ABI result_type __evalf() {
0168     const double __fp = __d == 0 ? __n / (2. * 0x8000000000000000ull) : __n / (double)__d;
0169     const size_t __j  = static_cast<size_t>(__fp * (__y_ - _Min));
0170     __y_              = __v_[__j];
0171     __v_[__j]         = __e_();
0172     return __y_;
0173   }
0174 };
0175 
0176 template <class _Engine, size_t __k>
0177 _LIBCPP_CONSTEXPR const size_t shuffle_order_engine<_Engine, __k>::table_size;
0178 
0179 template <class _Eng, size_t _Kp>
0180 _LIBCPP_HIDE_FROM_ABI bool
0181 operator==(const shuffle_order_engine<_Eng, _Kp>& __x, const shuffle_order_engine<_Eng, _Kp>& __y) {
0182   return __x.__y_ == __y.__y_ && std::equal(__x.__v_, __x.__v_ + _Kp, __y.__v_) && __x.__e_ == __y.__e_;
0183 }
0184 
0185 template <class _Eng, size_t _Kp>
0186 inline _LIBCPP_HIDE_FROM_ABI bool
0187 operator!=(const shuffle_order_engine<_Eng, _Kp>& __x, const shuffle_order_engine<_Eng, _Kp>& __y) {
0188   return !(__x == __y);
0189 }
0190 
0191 template <class _CharT, class _Traits, class _Eng, size_t _Kp>
0192 _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
0193 operator<<(basic_ostream<_CharT, _Traits>& __os, const shuffle_order_engine<_Eng, _Kp>& __x) {
0194   __save_flags<_CharT, _Traits> __lx(__os);
0195   typedef basic_ostream<_CharT, _Traits> _Ostream;
0196   __os.flags(_Ostream::dec | _Ostream::left);
0197   _CharT __sp = __os.widen(' ');
0198   __os.fill(__sp);
0199   __os << __x.__e_ << __sp << __x.__v_[0];
0200   for (size_t __i = 1; __i < _Kp; ++__i)
0201     __os << __sp << __x.__v_[__i];
0202   return __os << __sp << __x.__y_;
0203 }
0204 
0205 template <class _CharT, class _Traits, class _Eng, size_t _Kp>
0206 _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
0207 operator>>(basic_istream<_CharT, _Traits>& __is, shuffle_order_engine<_Eng, _Kp>& __x) {
0208   typedef typename shuffle_order_engine<_Eng, _Kp>::result_type result_type;
0209   __save_flags<_CharT, _Traits> __lx(__is);
0210   typedef basic_istream<_CharT, _Traits> _Istream;
0211   __is.flags(_Istream::dec | _Istream::skipws);
0212   _Eng __e;
0213   result_type __vp[_Kp + 1];
0214   __is >> __e;
0215   for (size_t __i = 0; __i < _Kp + 1; ++__i)
0216     __is >> __vp[__i];
0217   if (!__is.fail()) {
0218     __x.__e_ = __e;
0219     for (size_t __i = 0; __i < _Kp; ++__i)
0220       __x.__v_[__i] = __vp[__i];
0221     __x.__y_ = __vp[_Kp];
0222   }
0223   return __is;
0224 }
0225 
0226 _LIBCPP_END_NAMESPACE_STD
0227 
0228 _LIBCPP_POP_MACROS
0229 
0230 #endif // _LIBCPP___CXX03___RANDOM_SHUFFLE_ORDER_ENGINE_H