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