1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___RANDOM_SEED_SEQ_H 10 #define _LIBCPP___RANDOM_SEED_SEQ_H 11 12 #include <__algorithm/copy.h> 13 #include <__algorithm/fill.h> 14 #include <__algorithm/max.h> 15 #include <__config> 16 #include <initializer_list> 17 #include <vector> 18 19 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20 #pragma GCC system_header 21 #endif 22 23 _LIBCPP_PUSH_MACROS 24 #include <__undef_macros> 25 26 _LIBCPP_BEGIN_NAMESPACE_STD 27 28 class _LIBCPP_TEMPLATE_VIS seed_seq 29 { 30 public: 31 // types 32 typedef uint32_t result_type; 33 34 private: 35 vector<result_type> __v_; 36 37 template<class _InputIterator> 38 void init(_InputIterator __first, _InputIterator __last); 39 public: 40 // constructors 41 _LIBCPP_INLINE_VISIBILITY 42 seed_seq() _NOEXCEPT {} 43 #ifndef _LIBCPP_CXX03_LANG 44 template<class _Tp> 45 _LIBCPP_INLINE_VISIBILITY 46 seed_seq(initializer_list<_Tp> __il) {init(__il.begin(), __il.end());} 47 #endif // _LIBCPP_CXX03_LANG 48 49 template<class _InputIterator> 50 _LIBCPP_INLINE_VISIBILITY 51 seed_seq(_InputIterator __first, _InputIterator __last) 52 {init(__first, __last);} 53 54 // generating functions 55 template<class _RandomAccessIterator> 56 void generate(_RandomAccessIterator __first, _RandomAccessIterator __last); 57 58 // property functions 59 _LIBCPP_INLINE_VISIBILITY 60 size_t size() const _NOEXCEPT {return __v_.size();} 61 template<class _OutputIterator> 62 _LIBCPP_INLINE_VISIBILITY 63 void param(_OutputIterator __dest) const 64 {_VSTD::copy(__v_.begin(), __v_.end(), __dest);} 65 66 seed_seq(const seed_seq&) = delete; 67 void operator=(const seed_seq&) = delete; 68 69 _LIBCPP_INLINE_VISIBILITY 70 static result_type _Tp(result_type __x) {return __x ^ (__x >> 27);} 71 }; 72 73 template<class _InputIterator> 74 void 75 seed_seq::init(_InputIterator __first, _InputIterator __last) 76 { 77 for (_InputIterator __s = __first; __s != __last; ++__s) 78 __v_.push_back(*__s & 0xFFFFFFFF); 79 } 80 81 template<class _RandomAccessIterator> 82 void 83 seed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last) 84 { 85 if (__first != __last) 86 { 87 _VSTD::fill(__first, __last, 0x8b8b8b8b); 88 const size_t __n = static_cast<size_t>(__last - __first); 89 const size_t __s = __v_.size(); 90 const size_t __t = (__n >= 623) ? 11 91 : (__n >= 68) ? 7 92 : (__n >= 39) ? 5 93 : (__n >= 7) ? 3 94 : (__n - 1) / 2; 95 const size_t __p = (__n - __t) / 2; 96 const size_t __q = __p + __t; 97 const size_t __m = _VSTD::max(__s + 1, __n); 98 // __k = 0; 99 { 100 result_type __r = 1664525 * _Tp(__first[0] ^ __first[__p] 101 ^ __first[__n - 1]); 102 __first[__p] += __r; 103 __r += __s; 104 __first[__q] += __r; 105 __first[0] = __r; 106 } 107 for (size_t __k = 1; __k <= __s; ++__k) 108 { 109 const size_t __kmodn = __k % __n; 110 const size_t __kpmodn = (__k + __p) % __n; 111 result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] 112 ^ __first[(__k - 1) % __n]); 113 __first[__kpmodn] += __r; 114 __r += __kmodn + __v_[__k-1]; 115 __first[(__k + __q) % __n] += __r; 116 __first[__kmodn] = __r; 117 } 118 for (size_t __k = __s + 1; __k < __m; ++__k) 119 { 120 const size_t __kmodn = __k % __n; 121 const size_t __kpmodn = (__k + __p) % __n; 122 result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn] 123 ^ __first[(__k - 1) % __n]); 124 __first[__kpmodn] += __r; 125 __r += __kmodn; 126 __first[(__k + __q) % __n] += __r; 127 __first[__kmodn] = __r; 128 } 129 for (size_t __k = __m; __k < __m + __n; ++__k) 130 { 131 const size_t __kmodn = __k % __n; 132 const size_t __kpmodn = (__k + __p) % __n; 133 result_type __r = 1566083941 * _Tp(__first[__kmodn] + 134 __first[__kpmodn] + 135 __first[(__k - 1) % __n]); 136 __first[__kpmodn] ^= __r; 137 __r -= __kmodn; 138 __first[(__k + __q) % __n] ^= __r; 139 __first[__kmodn] = __r; 140 } 141 } 142 } 143 144 _LIBCPP_END_NAMESPACE_STD 145 146 _LIBCPP_POP_MACROS 147 148 #endif // _LIBCPP___RANDOM_SEED_SEQ_H 149