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