discard_block_engine.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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. #ifndef _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H
  9. #define _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H
  10. #include <__config>
  11. #include <__random/is_seed_sequence.h>
  12. #include <__type_traits/enable_if.h>
  13. #include <__type_traits/is_convertible.h>
  14. #include <__utility/move.h>
  15. #include <cstddef>
  16. #include <iosfwd>
  17. #include <limits>
  18. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  19. # pragma GCC system_header
  20. #endif
  21. _LIBCPP_PUSH_MACROS
  22. #include <__undef_macros>
  23. _LIBCPP_BEGIN_NAMESPACE_STD
  24. template<class _Engine, size_t __p, size_t __r>
  25. class _LIBCPP_TEMPLATE_VIS discard_block_engine
  26. {
  27. _Engine __e_;
  28. int __n_;
  29. static_assert( 0 < __r, "discard_block_engine invalid parameters");
  30. static_assert(__r <= __p, "discard_block_engine invalid parameters");
  31. #ifndef _LIBCPP_CXX03_LANG // numeric_limits::max() is not constexpr in C++03
  32. static_assert(__r <= numeric_limits<int>::max(), "discard_block_engine invalid parameters");
  33. #endif
  34. public:
  35. // types
  36. typedef typename _Engine::result_type result_type;
  37. // engine characteristics
  38. static _LIBCPP_CONSTEXPR const size_t block_size = __p;
  39. static _LIBCPP_CONSTEXPR const size_t used_block = __r;
  40. #ifdef _LIBCPP_CXX03_LANG
  41. static const result_type _Min = _Engine::_Min;
  42. static const result_type _Max = _Engine::_Max;
  43. #else
  44. static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min();
  45. static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max();
  46. #endif
  47. _LIBCPP_INLINE_VISIBILITY
  48. static _LIBCPP_CONSTEXPR result_type min() { return _Engine::min(); }
  49. _LIBCPP_INLINE_VISIBILITY
  50. static _LIBCPP_CONSTEXPR result_type max() { return _Engine::max(); }
  51. // constructors and seeding functions
  52. _LIBCPP_INLINE_VISIBILITY
  53. discard_block_engine() : __n_(0) {}
  54. _LIBCPP_INLINE_VISIBILITY
  55. explicit discard_block_engine(const _Engine& __e)
  56. : __e_(__e), __n_(0) {}
  57. #ifndef _LIBCPP_CXX03_LANG
  58. _LIBCPP_INLINE_VISIBILITY
  59. explicit discard_block_engine(_Engine&& __e)
  60. : __e_(_VSTD::move(__e)), __n_(0) {}
  61. #endif // _LIBCPP_CXX03_LANG
  62. _LIBCPP_INLINE_VISIBILITY
  63. explicit discard_block_engine(result_type __sd) : __e_(__sd), __n_(0) {}
  64. template<class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, discard_block_engine>::value &&
  65. !is_convertible<_Sseq, _Engine>::value, int> = 0>
  66. _LIBCPP_INLINE_VISIBILITY
  67. explicit discard_block_engine(_Sseq& __q)
  68. : __e_(__q), __n_(0) {}
  69. _LIBCPP_INLINE_VISIBILITY
  70. void seed() {__e_.seed(); __n_ = 0;}
  71. _LIBCPP_INLINE_VISIBILITY
  72. void seed(result_type __sd) {__e_.seed(__sd); __n_ = 0;}
  73. template<class _Sseq, __enable_if_t<__is_seed_sequence<_Sseq, discard_block_engine>::value, int> = 0>
  74. _LIBCPP_INLINE_VISIBILITY
  75. void
  76. seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;}
  77. // generating functions
  78. _LIBCPP_HIDE_FROM_ABI result_type operator()();
  79. _LIBCPP_INLINE_VISIBILITY
  80. void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
  81. // property functions
  82. _LIBCPP_INLINE_VISIBILITY
  83. const _Engine& base() const _NOEXCEPT {return __e_;}
  84. template<class _Eng, size_t _Pp, size_t _Rp>
  85. friend
  86. bool
  87. operator==(
  88. const discard_block_engine<_Eng, _Pp, _Rp>& __x,
  89. const discard_block_engine<_Eng, _Pp, _Rp>& __y);
  90. template<class _Eng, size_t _Pp, size_t _Rp>
  91. friend
  92. bool
  93. operator!=(
  94. const discard_block_engine<_Eng, _Pp, _Rp>& __x,
  95. const discard_block_engine<_Eng, _Pp, _Rp>& __y);
  96. template <class _CharT, class _Traits,
  97. class _Eng, size_t _Pp, size_t _Rp>
  98. friend
  99. basic_ostream<_CharT, _Traits>&
  100. operator<<(basic_ostream<_CharT, _Traits>& __os,
  101. const discard_block_engine<_Eng, _Pp, _Rp>& __x);
  102. template <class _CharT, class _Traits,
  103. class _Eng, size_t _Pp, size_t _Rp>
  104. friend
  105. basic_istream<_CharT, _Traits>&
  106. operator>>(basic_istream<_CharT, _Traits>& __is,
  107. discard_block_engine<_Eng, _Pp, _Rp>& __x);
  108. };
  109. template<class _Engine, size_t __p, size_t __r>
  110. _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::block_size;
  111. template<class _Engine, size_t __p, size_t __r>
  112. _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::used_block;
  113. template<class _Engine, size_t __p, size_t __r>
  114. typename discard_block_engine<_Engine, __p, __r>::result_type
  115. discard_block_engine<_Engine, __p, __r>::operator()()
  116. {
  117. if (__n_ >= static_cast<int>(__r))
  118. {
  119. __e_.discard(__p - __r);
  120. __n_ = 0;
  121. }
  122. ++__n_;
  123. return __e_();
  124. }
  125. template<class _Eng, size_t _Pp, size_t _Rp>
  126. inline _LIBCPP_INLINE_VISIBILITY
  127. bool
  128. operator==(const discard_block_engine<_Eng, _Pp, _Rp>& __x,
  129. const discard_block_engine<_Eng, _Pp, _Rp>& __y)
  130. {
  131. return __x.__n_ == __y.__n_ && __x.__e_ == __y.__e_;
  132. }
  133. template<class _Eng, size_t _Pp, size_t _Rp>
  134. inline _LIBCPP_INLINE_VISIBILITY
  135. bool
  136. operator!=(const discard_block_engine<_Eng, _Pp, _Rp>& __x,
  137. const discard_block_engine<_Eng, _Pp, _Rp>& __y)
  138. {
  139. return !(__x == __y);
  140. }
  141. template <class _CharT, class _Traits,
  142. class _Eng, size_t _Pp, size_t _Rp>
  143. _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
  144. operator<<(basic_ostream<_CharT, _Traits>& __os,
  145. const discard_block_engine<_Eng, _Pp, _Rp>& __x)
  146. {
  147. __save_flags<_CharT, _Traits> __lx(__os);
  148. typedef basic_ostream<_CharT, _Traits> _Ostream;
  149. __os.flags(_Ostream::dec | _Ostream::left);
  150. _CharT __sp = __os.widen(' ');
  151. __os.fill(__sp);
  152. return __os << __x.__e_ << __sp << __x.__n_;
  153. }
  154. template <class _CharT, class _Traits,
  155. class _Eng, size_t _Pp, size_t _Rp>
  156. _LIBCPP_HIDE_FROM_ABI basic_istream<_CharT, _Traits>&
  157. operator>>(basic_istream<_CharT, _Traits>& __is,
  158. discard_block_engine<_Eng, _Pp, _Rp>& __x)
  159. {
  160. __save_flags<_CharT, _Traits> __lx(__is);
  161. typedef basic_istream<_CharT, _Traits> _Istream;
  162. __is.flags(_Istream::dec | _Istream::skipws);
  163. _Eng __e;
  164. int __n;
  165. __is >> __e >> __n;
  166. if (!__is.fail())
  167. {
  168. __x.__e_ = __e;
  169. __x.__n_ = __n;
  170. }
  171. return __is;
  172. }
  173. _LIBCPP_END_NAMESPACE_STD
  174. _LIBCPP_POP_MACROS
  175. #endif // _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H