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
13 #include <__cstddef/size_t.h>
14 #include <__random/is_seed_sequence.h>
15 #include <__type_traits/enable_if.h>
16 #include <__type_traits/is_convertible.h>
17 #include <__utility/move.h>
21 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
22 # pragma GCC system_header
26 #include <__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 inline _LIBCPP_CONSTEXPR
const size_t block_size
= __p
;
47 static inline _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 typename discard_block_engine
<_Engine
, __p
, __r
>::result_type discard_block_engine
<_Engine
, __p
, __r
>::operator()() {
115 if (__n_
>= static_cast<int>(__r
)) {
116 __e_
.discard(__p
- __r
);
123 template <class _Eng
, size_t _Pp
, size_t _Rp
>
124 inline _LIBCPP_HIDE_FROM_ABI
bool
125 operator==(const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
, const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __y
) {
126 return __x
.__n_
== __y
.__n_
&& __x
.__e_
== __y
.__e_
;
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
== __y
);
135 template <class _CharT
, class _Traits
, class _Eng
, size_t _Pp
, size_t _Rp
>
136 _LIBCPP_HIDE_FROM_ABI basic_ostream
<_CharT
, _Traits
>&
137 operator<<(basic_ostream
<_CharT
, _Traits
>& __os
, const discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
) {
138 __save_flags
<_CharT
, _Traits
> __lx(__os
);
139 typedef basic_ostream
<_CharT
, _Traits
> _Ostream
;
140 __os
.flags(_Ostream::dec
| _Ostream::left
);
141 _CharT __sp
= __os
.widen(' ');
143 return __os
<< __x
.__e_
<< __sp
<< __x
.__n_
;
146 template <class _CharT
, class _Traits
, class _Eng
, size_t _Pp
, size_t _Rp
>
147 _LIBCPP_HIDE_FROM_ABI basic_istream
<_CharT
, _Traits
>&
148 operator>>(basic_istream
<_CharT
, _Traits
>& __is
, discard_block_engine
<_Eng
, _Pp
, _Rp
>& __x
) {
149 __save_flags
<_CharT
, _Traits
> __lx(__is
);
150 typedef basic_istream
<_CharT
, _Traits
> _Istream
;
151 __is
.flags(_Istream::dec
| _Istream::skipws
);
162 _LIBCPP_END_NAMESPACE_STD
166 #endif // _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H