
This commit reverts 5aaefa51 (and also partly 7f285f48e77 and b6d75682f9, which were related to the original commit). As landed, 5aaefa51 had unintended consequences on some downstream bots and didn't have proper coverage upstream due to a few subtle things. Implementing this is something we should do in libc++, however we'll first need to address a few issues listed in https://reviews.llvm.org/D106124#3349710. Differential Revision: https://reviews.llvm.org/D120683
204 lines
6.3 KiB
C++
204 lines
6.3 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H
|
|
#define _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H
|
|
|
|
#include <__config>
|
|
#include <__random/is_seed_sequence.h>
|
|
#include <__utility/move.h>
|
|
#include <climits>
|
|
#include <iosfwd>
|
|
#include <type_traits>
|
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
|
# pragma GCC system_header
|
|
#endif
|
|
|
|
_LIBCPP_PUSH_MACROS
|
|
#include <__undef_macros>
|
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
template<class _Engine, size_t __p, size_t __r>
|
|
class _LIBCPP_TEMPLATE_VIS discard_block_engine
|
|
{
|
|
_Engine __e_;
|
|
int __n_;
|
|
|
|
static_assert( 0 < __r, "discard_block_engine invalid parameters");
|
|
static_assert(__r <= __p, "discard_block_engine invalid parameters");
|
|
static_assert(__r <= INT_MAX, "discard_block_engine invalid parameters");
|
|
public:
|
|
// types
|
|
typedef typename _Engine::result_type result_type;
|
|
|
|
// engine characteristics
|
|
static _LIBCPP_CONSTEXPR const size_t block_size = __p;
|
|
static _LIBCPP_CONSTEXPR const size_t used_block = __r;
|
|
|
|
#ifdef _LIBCPP_CXX03_LANG
|
|
static const result_type _Min = _Engine::_Min;
|
|
static const result_type _Max = _Engine::_Max;
|
|
#else
|
|
static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min();
|
|
static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max();
|
|
#endif
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
static _LIBCPP_CONSTEXPR result_type min() { return _Engine::min(); }
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
static _LIBCPP_CONSTEXPR result_type max() { return _Engine::max(); }
|
|
|
|
// constructors and seeding functions
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
discard_block_engine() : __n_(0) {}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
explicit discard_block_engine(const _Engine& __e)
|
|
: __e_(__e), __n_(0) {}
|
|
#ifndef _LIBCPP_CXX03_LANG
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
explicit discard_block_engine(_Engine&& __e)
|
|
: __e_(_VSTD::move(__e)), __n_(0) {}
|
|
#endif // _LIBCPP_CXX03_LANG
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
explicit discard_block_engine(result_type __sd) : __e_(__sd), __n_(0) {}
|
|
template<class _Sseq>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
explicit discard_block_engine(_Sseq& __q,
|
|
typename enable_if<__is_seed_sequence<_Sseq, discard_block_engine>::value &&
|
|
!is_convertible<_Sseq, _Engine>::value>::type* = 0)
|
|
: __e_(__q), __n_(0) {}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
void seed() {__e_.seed(); __n_ = 0;}
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
void seed(result_type __sd) {__e_.seed(__sd); __n_ = 0;}
|
|
template<class _Sseq>
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
typename enable_if
|
|
<
|
|
__is_seed_sequence<_Sseq, discard_block_engine>::value,
|
|
void
|
|
>::type
|
|
seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;}
|
|
|
|
// generating functions
|
|
result_type operator()();
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
|
|
|
|
// property functions
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
const _Engine& base() const _NOEXCEPT {return __e_;}
|
|
|
|
template<class _Eng, size_t _Pp, size_t _Rp>
|
|
friend
|
|
bool
|
|
operator==(
|
|
const discard_block_engine<_Eng, _Pp, _Rp>& __x,
|
|
const discard_block_engine<_Eng, _Pp, _Rp>& __y);
|
|
|
|
template<class _Eng, size_t _Pp, size_t _Rp>
|
|
friend
|
|
bool
|
|
operator!=(
|
|
const discard_block_engine<_Eng, _Pp, _Rp>& __x,
|
|
const discard_block_engine<_Eng, _Pp, _Rp>& __y);
|
|
|
|
template <class _CharT, class _Traits,
|
|
class _Eng, size_t _Pp, size_t _Rp>
|
|
friend
|
|
basic_ostream<_CharT, _Traits>&
|
|
operator<<(basic_ostream<_CharT, _Traits>& __os,
|
|
const discard_block_engine<_Eng, _Pp, _Rp>& __x);
|
|
|
|
template <class _CharT, class _Traits,
|
|
class _Eng, size_t _Pp, size_t _Rp>
|
|
friend
|
|
basic_istream<_CharT, _Traits>&
|
|
operator>>(basic_istream<_CharT, _Traits>& __is,
|
|
discard_block_engine<_Eng, _Pp, _Rp>& __x);
|
|
};
|
|
|
|
template<class _Engine, size_t __p, size_t __r>
|
|
_LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::block_size;
|
|
|
|
template<class _Engine, size_t __p, size_t __r>
|
|
_LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::used_block;
|
|
|
|
template<class _Engine, size_t __p, size_t __r>
|
|
typename discard_block_engine<_Engine, __p, __r>::result_type
|
|
discard_block_engine<_Engine, __p, __r>::operator()()
|
|
{
|
|
if (__n_ >= static_cast<int>(__r))
|
|
{
|
|
__e_.discard(__p - __r);
|
|
__n_ = 0;
|
|
}
|
|
++__n_;
|
|
return __e_();
|
|
}
|
|
|
|
template<class _Eng, size_t _Pp, size_t _Rp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator==(const discard_block_engine<_Eng, _Pp, _Rp>& __x,
|
|
const discard_block_engine<_Eng, _Pp, _Rp>& __y)
|
|
{
|
|
return __x.__n_ == __y.__n_ && __x.__e_ == __y.__e_;
|
|
}
|
|
|
|
template<class _Eng, size_t _Pp, size_t _Rp>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
bool
|
|
operator!=(const discard_block_engine<_Eng, _Pp, _Rp>& __x,
|
|
const discard_block_engine<_Eng, _Pp, _Rp>& __y)
|
|
{
|
|
return !(__x == __y);
|
|
}
|
|
|
|
template <class _CharT, class _Traits,
|
|
class _Eng, size_t _Pp, size_t _Rp>
|
|
basic_ostream<_CharT, _Traits>&
|
|
operator<<(basic_ostream<_CharT, _Traits>& __os,
|
|
const discard_block_engine<_Eng, _Pp, _Rp>& __x)
|
|
{
|
|
__save_flags<_CharT, _Traits> __lx(__os);
|
|
typedef basic_ostream<_CharT, _Traits> _Ostream;
|
|
__os.flags(_Ostream::dec | _Ostream::left);
|
|
_CharT __sp = __os.widen(' ');
|
|
__os.fill(__sp);
|
|
return __os << __x.__e_ << __sp << __x.__n_;
|
|
}
|
|
|
|
template <class _CharT, class _Traits,
|
|
class _Eng, size_t _Pp, size_t _Rp>
|
|
basic_istream<_CharT, _Traits>&
|
|
operator>>(basic_istream<_CharT, _Traits>& __is,
|
|
discard_block_engine<_Eng, _Pp, _Rp>& __x)
|
|
{
|
|
__save_flags<_CharT, _Traits> __lx(__is);
|
|
typedef basic_istream<_CharT, _Traits> _Istream;
|
|
__is.flags(_Istream::dec | _Istream::skipws);
|
|
_Eng __e;
|
|
int __n;
|
|
__is >> __e >> __n;
|
|
if (!__is.fail())
|
|
{
|
|
__x.__e_ = __e;
|
|
__x.__n_ = __n;
|
|
}
|
|
return __is;
|
|
}
|
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
_LIBCPP_POP_MACROS
|
|
|
|
#endif // _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H
|