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
 |