1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H
10 #define _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H
12 #include <__cxx03/__config>
13 #include <__cxx03/__random/is_seed_sequence.h>
14 #include <__cxx03/__type_traits/enable_if.h>
15 #include <__cxx03/__type_traits/is_convertible.h>
16 #include <__cxx03/__utility/move.h>
17 #include <__cxx03/cstddef>
18 #include <__cxx03/iosfwd>
19 #include <__cxx03/limits>
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 # pragma GCC system_header
26 #include <__cxx03/__undef_macros>
28 _LIBCPP_BEGIN_NAMESPACE_STD
30 template <class _Engine
, size_t __p
, size_t __r
>
31 class _LIBCPP_TEMPLATE_VIS discard_block_engine
{
35 static_assert(0 < __r
, "discard_block_engine invalid parameters");
36 static_assert(__r
<= __p
, "discard_block_engine invalid parameters");
37 #ifndef _LIBCPP_CXX03_LANG // numeric_limits::max() is not constexpr in C++03
38 static_assert(__r
<= numeric_limits
<int>::max(), "discard_block_engine invalid parameters");
43 typedef typename
_Engine::result_type result_type
;
45 // engine characteristics
46 static _LIBCPP_CONSTEXPR
const size_t block_size
= __p
;
47 static _LIBCPP_CONSTEXPR
const size_t used_block
= __r
;
49 #ifdef _LIBCPP_CXX03_LANG
50 static const result_type _Min
= _Engine::_Min
;
51 static const result_type _Max
= _Engine::_Max
;
53 static constexpr result_type _Min
= _Engine::min();
54 static constexpr result_type _Max
= _Engine::max();
57 _LIBCPP_HIDE_FROM_ABI
static _LIBCPP_CONSTEXPR result_type
min() { return _Engine::min(); }
58 _LIBCPP_HIDE_FROM_ABI
static _LIBCPP_CONSTEXPR result_type
max() { return _Engine::max(); }
60 // constructors and seeding functions
61 _LIBCPP_HIDE_FROM_ABI
discard_block_engine() : __n_(0) {}
62 _LIBCPP_HIDE_FROM_ABI
explicit discard_block_engine(const _Engine
& __e
) : __e_(__e
), __n_(0) {}
63 #ifndef _LIBCPP_CXX03_LANG
64 _LIBCPP_HIDE_FROM_ABI
explicit discard_block_engine(_Engine
&& __e
) : __e_(std::move(__e
)), __n_(0) {}
65 #endif // _LIBCPP_CXX03_LANG
66 _LIBCPP_HIDE_FROM_ABI
explicit discard_block_engine(result_type __sd
) : __e_(__sd
), __n_(0) {}
69 __enable_if_t
<__is_seed_sequence
<_Sseq
, discard_block_engine
>::value
&& !is_convertible
<_Sseq
, _Engine
>::value
,
71 _LIBCPP_HIDE_FROM_ABI
explicit discard_block_engine(_Sseq
& __q
) : __e_(__q
), __n_(0) {}
72 _LIBCPP_HIDE_FROM_ABI
void seed() {
76 _LIBCPP_HIDE_FROM_ABI
void seed(result_type __sd
) {
80 template <class _Sseq
, __enable_if_t
<__is_seed_sequence
<_Sseq
, discard_block_engine
>::value
, int> = 0>
81 _LIBCPP_HIDE_FROM_ABI
void seed(_Sseq
& __q
) {
86 // generating functions
87 _LIBCPP_HIDE_FROM_ABI result_type
operator()();
88 _LIBCPP_HIDE_FROM_ABI
void discard(unsigned long long __z
) {
94 _LIBCPP_HIDE_FROM_ABI
const _Engine
& base() const _NOEXCEPT
{ return __e_
; }
96 template <class _Eng
, size_t _Pp
, size_t _Rp
>
98 operator==(const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
, const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __y
);
100 template <class _Eng
, size_t _Pp
, size_t _Rp
>
102 operator!=(const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
, const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __y
);
104 template <class _CharT
, class _Traits
, class _Eng
, size_t _Pp
, size_t _Rp
>
105 friend basic_ostream
<_CharT
, _Traits
>&
106 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
, const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
);
108 template <class _CharT
, class _Traits
, class _Eng
, size_t _Pp
, size_t _Rp
>
109 friend basic_istream
<_CharT
, _Traits
>&
110 operator>>(basic_istream
<_CharT
, _Traits
>& __is
, discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
);
113 template <class _Engine
, size_t __p
, size_t __r
>
114 _LIBCPP_CONSTEXPR
const size_t discard_block_engine
<_Engine
, __p
, __r
>::block_size
;
116 template <class _Engine
, size_t __p
, size_t __r
>
117 _LIBCPP_CONSTEXPR
const size_t discard_block_engine
<_Engine
, __p
, __r
>::used_block
;
119 template <class _Engine
, size_t __p
, size_t __r
>
120 typename discard_block_engine
<_Engine
, __p
, __r
>::result_type discard_block_engine
<_Engine
, __p
, __r
>::operator()() {
121 if (__n_
>= static_cast<int>(__r
)) {
122 __e_
.discard(__p
- __r
);
129 template <class _Eng
, size_t _Pp
, size_t _Rp
>
130 inline _LIBCPP_HIDE_FROM_ABI
bool
131 operator==(const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
, const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __y
) {
132 return __x
.__n_
== __y
.__n_
&& __x
.__e_
== __y
.__e_
;
135 template <class _Eng
, size_t _Pp
, size_t _Rp
>
136 inline _LIBCPP_HIDE_FROM_ABI
bool
137 operator!=(const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
, const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __y
) {
138 return !(__x
== __y
);
141 template <class _CharT
, class _Traits
, class _Eng
, size_t _Pp
, size_t _Rp
>
142 _LIBCPP_HIDE_FROM_ABI basic_ostream
<_CharT
, _Traits
>&
143 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
, const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
) {
144 __save_flags
<_CharT
, _Traits
> __lx(__os
);
145 typedef basic_ostream
<_CharT
, _Traits
> _Ostream
;
146 __os
.flags(_Ostream::dec
| _Ostream::left
);
147 _CharT __sp
= __os
.widen(' ');
149 return __os
<< __x
.__e_
<< __sp
<< __x
.__n_
;
152 template <class _CharT
, class _Traits
, class _Eng
, size_t _Pp
, size_t _Rp
>
153 _LIBCPP_HIDE_FROM_ABI basic_istream
<_CharT
, _Traits
>&
154 operator>>(basic_istream
<_CharT
, _Traits
>& __is
, discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
) {
155 __save_flags
<_CharT
, _Traits
> __lx(__is
);
156 typedef basic_istream
<_CharT
, _Traits
> _Istream
;
157 __is
.flags(_Istream::dec
| _Istream::skipws
);
168 _LIBCPP_END_NAMESPACE_STD
172 #endif // _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H