#pragma once
#ifndef _FUNCTIONAL_
#define _FUNCTIONAL_
#ifndef RC_INVOKED
#include <exception>
#include <tuple>
#include <typeinfo>
#include <xstddef>
#include <xstring>
#if _HAS_CXX17
#include <memory>
#include <unordered_map>
#endif /* _HAS_CXX17 */
#pragma pack(push,_CRT_PACKING)
#pragma warning(push,_STL_WARNING_LEVEL)
#pragma warning(disable: _STL_DISABLED_WARNINGS)
#pragma warning(disable:
4455
4494
4619
4643
4702
4984
4988
)
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;
constexpr
(
const
&
,
const
&
)
const
{
return
(
/
);
}
};
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;
constexpr
(
const
&
,
const
&
)
const
{
return
(
%
);
}
};
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;
constexpr
(
const
&
)
const
{
return
(-
);
}
};
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool result_type;
constexpr
bool
(
const
&
,
const
&
)
const
{
return
(
&&
);
}
};
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool result_type;
constexpr
bool
(
const
&
,
const
&
)
const
{
return
(
||
);
}
};
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool result_type;
constexpr
bool
(
const
&
)
const
{
return
(!
);
}
};
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;
constexpr
(
const
&
,
const
&
)
const
{
return
(
&
);
}
};
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;
constexpr
(
const
&
,
const
&
)
const
{
return
(
|
);
}
};
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;
constexpr
(
const
&
,
const
&
)
const
{
return
(
^
);
}
};
template
<
class
=
void
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty argument_type;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;
constexpr
(
const
&
)
const
{
return
(~
);
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
,
class
>
constexpr
auto
(
&&
,
&&
)
const
-> decltype(_STD forward<_Ty1>(_Left) / _STD forward<_Ty2>(_Right))
->
decltype
(::
std
::
<
>(
) / ::
std
::
<
>(
))
{
return (_STD forward<_Ty1>(_Left) / _STD forward<_Ty2>(_Right));
return
(::
std
::
<
>(
) / ::
std
::
<
>(
));
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
,
class
>
constexpr
auto
(
&&
,
&&
)
const
-> decltype(_STD forward<_Ty1>(_Left) % _STD forward<_Ty2>(_Right))
->
decltype
(::
std
::
<
>(
) % ::
std
::
<
>(
))
{
return (_STD forward<_Ty1>(_Left) % _STD forward<_Ty2>(_Right));
return
(::
std
::
<
>(
) % ::
std
::
<
>(
));
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
>
constexpr
auto
(
&&
)
const
-> decltype(-_STD forward<_Ty>(_Left))
->
decltype
(-::
std
::
<
>(
))
{
return (-_STD forward<_Ty>(_Left));
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
,
class
>
constexpr
auto
(
&&
,
&&
)
const
-> decltype(_STD forward<_Ty1>(_Left) && _STD forward<_Ty2>(_Right))
->
decltype
(::
std
::
<
>(
) && ::
std
::
<
>(
))
{
return (_STD forward<_Ty1>(_Left) && _STD forward<_Ty2>(_Right));
return
(::
std
::
<
>(
) && ::
std
::
<
>(
));
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
,
class
>
constexpr
auto
(
&&
,
&&
)
const
-> decltype(_STD forward<_Ty1>(_Left) || _STD forward<_Ty2>(_Right))
->
decltype
(::
std
::
<
>(
) || ::
std
::
<
>(
))
{
return (_STD forward<_Ty1>(_Left) || _STD forward<_Ty2>(_Right));
return
(::
std
::
<
>(
) || ::
std
::
<
>(
));
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
>
constexpr
auto
(
&&
)
const
-> decltype(!_STD forward<_Ty>(_Left))
->
decltype
(!::
std
::
<
>(
))
{
return (!_STD forward<_Ty>(_Left));
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
,
class
>
constexpr
auto
(
&&
,
&&
)
const
-> decltype(_STD forward<_Ty1>(_Left) & _STD forward<_Ty2>(_Right))
->
decltype
(::
std
::
<
>(
) & ::
std
::
<
>(
))
{
return (_STD forward<_Ty1>(_Left) & _STD forward<_Ty2>(_Right));
return
(::
std
::
<
>(
) & ::
std
::
<
>(
));
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
,
class
>
constexpr
auto
(
&&
,
&&
)
const
-> decltype(_STD forward<_Ty1>(_Left) | _STD forward<_Ty2>(_Right))
->
decltype
(::
std
::
<
>(
) | ::
std
::
<
>(
))
{
return (_STD forward<_Ty1>(_Left) | _STD forward<_Ty2>(_Right));
return
(::
std
::
<
>(
) | ::
std
::
<
>(
));
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
,
class
>
constexpr
auto
(
&&
,
&&
)
const
-> decltype(_STD forward<_Ty1>(_Left) ^ _STD forward<_Ty2>(_Right))
->
decltype
(::
std
::
<
>(
) ^ ::
std
::
<
>(
))
{
return (_STD forward<_Ty1>(_Left) ^ _STD forward<_Ty2>(_Right));
return
(::
std
::
<
>(
) ^ ::
std
::
<
>(
));
}
};
template
<>
struct
<
void
>
{
typedef
int
;
template
<
class
>
constexpr
auto
(
&&
)
const
-> decltype(~_STD forward<_Ty>(_Left))
->
decltype
(~::
std
::
<
>(
))
{
return (~_STD forward<_Ty>(_Left));
}
};
#pragma warning(push)
#pragma warning(disable: 4996) // was declared deprecated
#pragma warning(disable:
4996
)
template
<
class
>
class _CXX17_DEPRECATE_NEGATORS unary_negate
{
public
:
typedef
typename
::argument_type
;
typedef
bool
;
constexpr
explicit
(
const
&
)
: _Functor(
)
{
}
constexpr
bool
(
const
&
)
const
{
return
(!
(
));
}
private
:
;
};
template
<
class
>
_NODISCARD _CXX17_DEPRECATE_NEGATORS constexpr unary_negate<_Fn> not1(const _Fn& _Func)
{
return
(
<
>(
));
}
template
<
class
>
class _CXX17_DEPRECATE_NEGATORS binary_negate
{
public
:
typedef
typename
::first_argument_type
;
typedef
typename
::second_argument_type
;
typedef
bool
;
constexpr
explicit
(
const
&
)
: _Functor(
)
{
}
constexpr
bool
(
const
&
,
const
&
)
const
{
return
(!
(
,
));
}
private
:
;
};
template
<
class
>
_NODISCARD _CXX17_DEPRECATE_NEGATORS constexpr binary_negate<_Fn> not2(const _Fn& _Func)
{
return
(
<
>(
));
}
#pragma warning(pop)
#if _HAS_AUTO_PTR_ETC
#pragma warning(push)
#pragma warning(disable: 4996) // was declared deprecated
#pragma warning(disable:
4996
)
template
<
class
>
class
:
public
<
typename
::second_argument_type,
typename
::result_type>
{
public
:
typedef
<
typename
::second_argument_type,
typename
::result_type>
;
typedef
typename
::
;
typedef
typename
::
;
(
const
&
,
const
typename
::first_argument_type&
)
: op(
), value(
)
{
}
(
const
&
)
const
{
return
(
(
,
));
}
(
&
)
const
{
return
(
(
,
));
}
protected
:
;
typename
::first_argument_type
;
};
template
<
class
,
class
>
_NODISCARD inline binder1st<_Fn> bind1st(const _Fn& _Func, const _Ty& _Left)
inline
<
>
(
const
&
,
const
&
)
{
typename
::first_argument_type
(
);
return
(
<
>(
,
_Val
));
}
template
<
class
>
class
:
public
<
typename
::first_argument_type,
typename
::result_type>
{
public
:
typedef
<
typename
::first_argument_type,
typename
::result_type>
;
typedef
typename
::
;
typedef
typename
::
;
(
const
&
,
const
typename
::second_argument_type&
)
: op(
), value(
)
{
}
(
const
&
)
const
{
return
(
(
,
));
}
(
&
)
const
{
return
(
(
,
));
}
protected
:
;
typename
::second_argument_type
;
};
template
<
class
,
class
>
_NODISCARD inline binder2nd<_Fn> bind2nd(const _Fn& _Func, const _Ty& _Right)
inline
<
>
(
const
&
,
const
&
)
{
typename
::second_argument_type
(
);
return
(
<
>(
,
_Val
));
}
#pragma warning(pop)
template
<
class
,
class
,
class
=
(*)(
)>
class
pointer_to_unary_function
:
public
<
,
>
{
public
:
explicit
pointer_to_unary_function
(
)
: _Pfun(
)
{
}
(
)
const
{
return
(
(
));
}
protected
:
;
};
template
<
class
,
class
,
class
,
class
=
(*)(
,
)>
class
pointer_to_binary_function
:
public
<
,
,
>
{
public
:
explicit
pointer_to_binary_function
(
)
: _Pfun(
)
{
}
(
,
)
const
{
return
(
(
,
));
}
protected
:
;
};
#define _PTR_FUN(CALL_OPT, X1, X2, X3) \
template<class _Arg, \
class _Result> \
_NODISCARD inline pointer_to_unary_function<_Arg, _Result, _Result (CALL_OPT *)(_Arg)> \
ptr_fun(_Result (CALL_OPT *_Left)(_Arg)) \
{ /* return pointer_to_unary_function functor adapter */ \
return (pointer_to_unary_function<_Arg, _Result, _Result (CALL_OPT *)(_Arg)>(_Left)); \
} \
template<class _Arg1, \
class _Arg2, \
class _Result> \
_NODISCARD inline pointer_to_binary_function<_Arg1, _Arg2, _Result, _Result (CALL_OPT *)(_Arg1, _Arg2)> \
ptr_fun(_Result (CALL_OPT *_Left)(_Arg1, _Arg2)) \
{ /* return pointer_to_binary_function functor adapter */ \
return (pointer_to_binary_function<_Arg1, _Arg2, _Result, _Result (CALL_OPT *)(_Arg1, _Arg2)>(_Left)); \
}
_NON_MEMBER_CALL(_PTR_FUN, X1, X2, X3)
template
<
class
,
class
>
inline
pointer_to_unary_function
<
,
,
(
__cdecl
*)(
)>
(
(
__cdecl
*
)(
)) {
return
(
pointer_to_unary_function
<
,
,
(
__cdecl
*)(
)>(
)); }
template
<
class
,
class
,
class
>
inline
pointer_to_binary_function
<
,
,
,
(
__cdecl
*)(
,
)>
(
(
__cdecl
*
)(
,
)) {
return
(
pointer_to_binary_function
<
,
,
,
(
__cdecl
*)(
,
)>(
)); }
template
<
class
,
class
>
inline
pointer_to_unary_function
<
,
,
(
__fastcall
*)(
)>
(
(
__fastcall
*
)(
)) {
return
(
pointer_to_unary_function
<
,
,
(
__fastcall
*)(
)>(
)); }
template
<
class
,
class
,
class
>
inline
pointer_to_binary_function
<
,
,
,
(
__fastcall
*)(
,
)>
(
(
__fastcall
*
)(
,
)) {
return
(
pointer_to_binary_function
<
,
,
,
(
__fastcall
*)(
,
)>(
)); }
template
<
class
,
class
>
inline
pointer_to_unary_function
<
,
,
(
__stdcall
*)(
)>
(
(
__stdcall
*
)(
)) {
return
(
pointer_to_unary_function
<
,
,
(
__stdcall
*)(
)>(
)); }
template
<
class
,
class
,
class
>
inline
pointer_to_binary_function
<
,
,
,
(
__stdcall
*)(
,
)>
(
(
__stdcall
*
)(
,
)) {
return
(
pointer_to_binary_function
<
,
,
,
(
__stdcall
*)(
,
)>(
)); }
template
<
class
,
class
>
inline
pointer_to_unary_function
<
,
,
(
__vectorcall
*)(
)>
(
(
__vectorcall
*
)(
)) {
return
(
pointer_to_unary_function
<
,
,
(
__vectorcall
*)(
)>(
)); }
template
<
class
,
class
,
class
>
inline
pointer_to_binary_function
<
,
,
,
(
__vectorcall
*)(
,
)>
(
(
__vectorcall
*
)(
,
)) {
return
(
pointer_to_binary_function
<
,
,
,
(
__vectorcall
*)(
,
)>(
)); }
#undef _PTR_FUN
template
<
class
,
class
>
class
:
public
<
*,
>
{
public
:
explicit
(
(
::*
)())
: _Pmemfun(
)
{
}
(
*
)
const
{
return
((
->*
)());
}
private
:
(
::*
)();
};
template
<
class
,
class
,
class
>
class
:
public
<
*,
,
>
{
public
:
explicit
(
(
::*
)(
))
: _Pmemfun(
)
{
}
(
*
,
)
const
{
return
((
->*
)(
));
}
private
:
(
::*
)(
);
};
template
<
class
,
class
>
class
:
public
<
const
*,
>
{
public
:
explicit
(
(
::*
)()
const
)
: _Pmemfun(
)
{
}
(
const
*
)
const
{
return
((
->*
)());
}
private
:
(
::*
)()
const
;
};
template
<
class
,
class
,
class
>
class
:
public
<
const
*,
,
>
{
public
:
explicit
(
(
::*
)(
)
const
)
: _Pmemfun(
)
{
}
(
const
*
,
)
const
{
return
((
->*
)(
));
}
private
:
(
::*
)(
)
const
;
};
template
<
class
,
class
>
_NODISCARD inline mem_fun_t<_Result, _Ty> mem_fun(_Result (_Ty::*_Pm)())
{
return
(
<
,
>(
));
}
template
<
class
,
class
,
class
>
_NODISCARD inline mem_fun1_t<_Result, _Ty, _Arg> mem_fun(_Result (_Ty::*_Pm)(_Arg))
{
return
(
<
,
,
>(
));
}
template
<
class
,
class
>
_NODISCARD inline const_mem_fun_t<_Result, _Ty> mem_fun(_Result (_Ty::*_Pm)() const)
inline
<
,
>
(
(
::*
)()
const
)
{
return
(
<
,
>(
));
}
template
<
class
,
class
,
class
>
_NODISCARD inline const_mem_fun1_t<_Result, _Ty, _Arg> mem_fun(_Result (_Ty::*_Pm)(_Arg) const)
inline
<
,
,
>
(
(
::*
)(
)
const
)
{
return
(
<
,
,
>(
));
}
template
<
class
,
class
>
class
:
public
<
,
>
{
public
:
explicit
(
(
::*
)())
: _Pmemfun(
)
{
}
(
&
)
const
{
return
((
.*
)());
}
private
:
(
::*
)();
};
template
<
class
,
class
,
class
>
class
:
public
<
,
,
>
{
public
:
explicit
(
(
::*
)(
))
: _Pmemfun(
)
{
}
(
&
,
)
const
{
return
((
.*
)(
));
}
private
:
(
::*
)(
);
};
template
<
class
,
class
>
class
:
public
<
,
>
{
public
:
explicit
(
(
::*
)()
const
)
: _Pmemfun(
)
{
}
(
const
&
)
const
{
return
((
.*
)());
}
private
:
(
::*
)()
const
;
};
template
<
class
,
class
,
class
>
class
:
public
<
,
,
>
{
public
:
explicit
(
(
::*
)(
)
const
)
: _Pmemfun(
)
{
}
(
const
&
,
)
const
{
return
((
.*
)(
));
}
private
:
(
::*
)(
)
const
;
};
template
<
class
,
class
>
_NODISCARD inline mem_fun_ref_t<_Result, _Ty> mem_fun_ref(_Result (_Ty::*_Pm)())
{
return
(
<
,
>(
));
}
template
<
class
,
class
,
class
>
_NODISCARD inline mem_fun1_ref_t<_Result, _Ty, _Arg> mem_fun_ref(_Result (_Ty::*_Pm)(_Arg))
{
return
(
<
,
,
>(
));
}
template
<
class
,
class
>
_NODISCARD inline const_mem_fun_ref_t<_Result, _Ty> mem_fun_ref(_Result (_Ty::*_Pm)() const)
inline
<
,
>
(
(
::*
)()
const
)
{
return
(
<
,
>(
));
}
template
<
class
,
class
,
class
>
_NODISCARD inline const_mem_fun1_ref_t<_Result, _Ty, _Arg> mem_fun_ref(_Result (_Ty::*_Pm)(_Arg) const)
inline
<
,
,
>
(
(
::*
)(
)
const
)
{
return
(
<
,
,
>(
));
}
#endif /* _HAS_AUTO_PTR_ETC */
template
<
class
>
class
:
public
<
>::
{
private
:
;
public
:
explicit
(
)
noexcept
: _Pm(
)
{
}
template
<
class
...
>
auto
(
&&...
)
const
_NOEXCEPT_COND(_NOEXCEPT_OPER(_STD invoke(_Pm, _STD forward<_Types>(_Args)...))) // strengthened
noexcept
(
noexcept
(::
std
::
(
, ::
std
::
<
>(
)...)))
-> decltype(_STD invoke(_Pm, _STD forward<_Types>(_Args)...))
->
decltype
(::
std
::
(
, ::
std
::
<
>(
)...))
{
return (_STD invoke(_Pm, _STD forward<_Types>(_Args)...));
return
(::
std
::
(
, ::
std
::
<
>(
)...));
}
};
template
<
class
,
class
>
_NODISCARD inline _Mem_fn<_Rx _Ty::*> mem_fn(_Rx _Ty::* _Pm) noexcept
inline
<
::*>
(
::*
)
noexcept
{
return
(
<
::*>(
));
}
#if _HAS_CXX17
// CLASS TEMPLATE _Ebco_base
template<class _Ty,
bool = is_empty_v<_Ty> && !is_final_v<_Ty>>
class _Ebco_base
: private _Ty
{ // Empty Base Class Optimization, active
private:
using _Mybase = _Ty; // for visualization
protected:
template<class _Other,
enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Other>>, _Ebco_base>, int> = 0>
explicit _Ebco_base(_Other&& _Val) _NOEXCEPT_COND(is_nothrow_constructible_v<_Ty, _Other>)
: _Ty(_STD forward<_Other>(_Val))
{
}
_Ty& _Get_val() noexcept
{
return (*this);
}
const _Ty& _Get_val() const noexcept
{
return (*this);
}
};
template<class _Ty>
class _Ebco_base<_Ty, false>
{ // Empty Base Class Optimization, inactive
private:
_Ty _Myval;
protected:
template<class _Other,
enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Other>>, _Ebco_base>, int> = 0>
explicit _Ebco_base(_Other&& _Val) _NOEXCEPT_COND(is_nothrow_constructible_v<_Ty, _Other>)
: _Myval(_STD forward<_Other>(_Val))
{
}
_Ty& _Get_val() noexcept
{
return (_Myval);
}
const _Ty& _Get_val() const noexcept
{
return (_Myval);
}
};
// FUNCTION TEMPLATE not_fn
struct _Not_fn_tag
{
};
template<class _Decayed>
class _Not_fn
: private _Ebco_base<_Decayed>
{ // wrap a callable object to be negated
private:
using _Mybase = _Ebco_base<_Decayed>;
public:
template<class _Callable,
class _Tag,
enable_if_t<is_same_v<_Tag, _Not_fn_tag>, int> = 0>
explicit _Not_fn(_Callable&& _Obj, _Tag)
_NOEXCEPT_COND(is_nothrow_constructible_v<_Decayed, _Callable>) // strengthened
: _Mybase(_STD forward<_Callable>(_Obj))
{ // store a callable object
}
_Not_fn(const _Not_fn&) = default;
_Not_fn(_Not_fn&&) = default;
template<class... _Types>
auto operator()(_Types&&... _Args) &
#ifndef __EDG__ // TRANSITION, VSO#604398
_NOEXCEPT_COND(_NOEXCEPT_OPER(!_STD invoke(this->_Get_val(),
_STD forward<_Types>(_Args)...))) // strengthened
#endif /* __EDG__ */
-> decltype(!_STD declval<invoke_result_t<_Decayed&, _Types...>>())
{ // call modifiable lvalue
return (!_STD invoke(this->_Get_val(), _STD forward<_Types>(_Args)...));
}
template<class... _Types>
auto operator()(_Types&&... _Args) const &
#ifndef __EDG__ // TRANSITION, VSO#604398
_NOEXCEPT_COND(_NOEXCEPT_OPER(!_STD invoke(this->_Get_val(),
_STD forward<_Types>(_Args)...))) // strengthened
#endif /* __EDG__ */
-> decltype(!_STD declval<invoke_result_t<const _Decayed&, _Types...>>())
{ // call const lvalue
return (!_STD invoke(this->_Get_val(), _STD forward<_Types>(_Args)...));
}
template<class... _Types>
auto operator()(_Types&&... _Args) &&
#ifndef __EDG__ // TRANSITION, VSO#604398
_NOEXCEPT_COND(_NOEXCEPT_OPER(!_STD invoke(_STD move(this->_Get_val()),
_STD forward<_Types>(_Args)...))) // strengthened
#endif /* __EDG__ */
-> decltype(!_STD declval<invoke_result_t<_Decayed, _Types...>>())
{ // call modifiable rvalue
return (!_STD invoke(_STD move(this->_Get_val()), _STD forward<_Types>(_Args)...));
}
template<class... _Types>
auto operator()(_Types&&... _Args) const &&
#ifndef __EDG__ // TRANSITION, VSO#604398
_NOEXCEPT_COND(_NOEXCEPT_OPER(!_STD invoke(_STD move(this->_Get_val()),
_STD forward<_Types>(_Args)...))) // strengthened
#endif /* __EDG__ */
-> decltype(!_STD declval<invoke_result_t<const _Decayed, _Types...>>())
{ // call const rvalue
return (!_STD invoke(_STD move(this->_Get_val()), _STD forward<_Types>(_Args)...));
}
};
template<class _Callable>
_NODISCARD _Not_fn<decay_t<_Callable>> not_fn(_Callable&& _Obj)
_NOEXCEPT_COND(is_nothrow_constructible_v<decay_t<_Callable>, _Callable>) // strengthened
{ // wrap a callable object to be negated
return (_Not_fn<decay_t<_Callable>>(_STD forward<_Callable>(_Obj), _Not_fn_tag{}));
}
#endif /* _HAS_CXX17 */
class
:
public
{
public
:
()
noexcept
{
}
_NODISCARD virtual const char * __CLR_OR_THIS_CALL what() const noexcept override
virtual
const
char
*
()
const
noexcept
override
{
return
(
"bad function call"
);
}
};
[[noreturn]] _CRTIMP2_PURE void __CLRCALL_PURE_OR_CDECL _Xbad_function_call();
[[noreturn]]
void
__cdecl
();
template
<
class
>
class
;
template
<
class
>
inline
bool
(
const
&
,
)
noexcept
{
return
(!!
);
}
template
<
class
>
inline
bool
(
const
&,
)
noexcept
{
return
(
true
);
}
template
<
class
>
inline
bool
(
const
&
)
noexcept
{
<
<
> || (
<
>
&&
<
<
>>)>
;
return
(
(
,
_Testable
));
}
template
<
class
>
inline
bool
(
const
<
>&
)
noexcept
{
return
(!!
);
}
#pragma warning(push)
#pragma warning(disable: 4265) // class has virtual functions, but destructor is not virtual
#pragma warning(disable:
4265
)
template
<
class
,
class
...
>
class
__declspec
(novtable)
{
public
:
virtual
*
(
void
*)
const
=
0
;
virtual
*
(
void
*) =
0
;
virtual
(
&&...) =
0
;
virtual
const
&
()
const
noexcept
=
0
;
virtual
void
(
bool
)
noexcept
=
0
;
#if _HAS_STATIC_RTTI
const
void
*
(
const
&
)
const
noexcept
{
return
(
()
?
() :
nullptr
);
}
#endif /* _HAS_STATIC_RTTI */
() =
default
;
(
const
&) =
delete
;
&
(
const
&) =
delete
;
private
:
virtual
const
void
*
()
const
noexcept
=
0
;
};
#pragma warning(pop)
constexpr
= (
_Small_object_num_ptrs
-
1
) *
sizeof
(
void
*);
template
<
class
>
struct
:
<
_Space_size
sizeof
(
)
|| !
::_Nothrow_move::value>
{
};
#pragma warning(push)
#pragma warning(disable: 4265) // class has virtual functions, but destructor is not virtual
#pragma warning(disable:
4265
)
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
template
<
class
,
class
,
class
,
class
...
>
class
final
:
public
<
,
...>
{
public
:
typedef
<
,
...>
;
typedef
<
,
>
;
typedef
<
>
;
typedef
is_nothrow_move_constructible
<
>
;
template
<
class
,
class
>
(
&&
,
&&
)
: _Mypair(
_One_then_variadic_args_t
(),
_STD forward<_Other2>(_Ax), _STD forward<_Other1>(_Val))
::
std
::
<
>(
), ::
std
::
<
>(
))
{
}
private
:
virtual
*
(
void
*
)
const
override
{
return
(
(
,
<
>()));
}
*
(
void
*,
)
const
{
(
());
const
auto
=
::
(
_Al
,
1
);
::
(
_Al
,
(
_Ptr
),
(),
());
::
(
_Al
,
_Ptr
,
1
);
return
(
(
_Ptr
));
}
*
(
void
*
,
)
const
{
(
());
*
=
static_cast
<
*>(
);
::
(
_Al
,
_Ptr
,
(),
());
return
(
_Ptr
);
}
virtual
*
(
void
*
)
override
{
(
());
*
=
static_cast
<
*>(
);
_Myalty_traits::construct(_Al, _Ptr, _STD move(_Callee()), _STD move(_Myax()));
::
(
_Al
,
_Ptr
, ::
std
::
(
()), ::
std
::
(
()));
return
(
_Ptr
);
}
virtual
(
&&...
)
override
;
virtual
const
&
()
const
noexcept
override
{
#if _HAS_STATIC_RTTI
return
(
typeid
(
));
#else /* _HAS_STATIC_RTTI */
return (typeid(void));
#endif /* _HAS_STATIC_RTTI */
}
virtual
const
void
*
()
const
noexcept
override
{
return (_STD addressof(_Callee()));
}
virtual
void
(
bool
)
noexcept
override
{
(
());
::
(
_Al
,
this
);
if
(
)
{
(
_Al
,
this
);
}
}
<
,
>
;
&
()
noexcept
{
return
(
.
());
}
const
&
()
const
noexcept
{
return
(
.
());
}
&
()
noexcept
{
return
(
.
());
}
const
&
()
const
noexcept
{
return
(
.
());
}
};
#endif /* _HAS_FUNCTION_ALLOCATOR_SUPPORT */
template
<
class
,
class
,
class
...
>
class
final
:
public
<
,
...>
{
public
:
typedef
<
,
...>
;
typedef
is_nothrow_move_constructible
<
>
;
template
<
class
,
class
=
<!
<
,
<
>>>>
explicit
(
&&
)
: _Callee(_STD forward<_Other>(_Val))
{
}
private
:
virtual
*
(
void
*
)
const
override
{
return
(
(
,
<
>()));
}
*
(
void
*,
)
const
{
return
(
<
>(
));
}
*
(
void
*
,
)
const
{
return
(::
new
(
)
(
));
}
virtual
*
(
void
*
)
override
{
return (::new (_Where) _Func_impl_no_alloc(_STD move(_Callee)));
return
(::
new
(
)
(::
std
::
(
)));
}
virtual
(
&&...
)
override
;
virtual
const
&
()
const
noexcept
override
{
#if _HAS_STATIC_RTTI
return
(
typeid
(
));
#else /* _HAS_STATIC_RTTI */
return (typeid(void));
#endif /* _HAS_STATIC_RTTI */
}
virtual
const
void
*
()
const
noexcept
override
{
return (_STD addressof(_Callee));
}
virtual
void
(
bool
)
noexcept
override
{
this
->
();
if
(
)
{
<alignof(
)>(
this
,
sizeof
(
));
}
}
;
};
#pragma warning(pop)
template
<
class
,
class
...
>
class
:
public
<
...>
{
public
:
typedef
;
typedef
<
,
...>
;
()
noexcept
{
(
nullptr
);
}
(
...
)
const
;
()
noexcept
{
();
}
protected
:
template
<
class
,
class
>
using
=
<
<
<
<
<
>,
>>,
<
,
,
...>>>;
bool
()
const
noexcept
{
return
(
() ==
nullptr
);
}
void
(
const
&
)
{
if
(!
.
())
{
(
.
()->
(
()));
}
}
void
(
&&
)
{
if
(!
.
())
{
if
(
.
())
{
(
.
()->
(
()));
.
();
}
else
{
(
.
());
.
(
nullptr
);
}
}
}
template
<
class
>
void
(
&&
)
{
if
(!
(
))
{
return
;
}
using
=
<
<
>,
,
...>;
_Reset_impl<_Impl>(_STD forward<_Fx>(_Val), _Is_large<_Impl>());
}
template
<
class
,
class
>
void
(
&&
,
)
{
_Set(_Global_new<_Myimpl>(_STD forward<_Fx>(_Val)));
}
template
<
class
,
class
>
void
(
&&
,
)
{
_Set(::new (_Getspace()) _Myimpl(_STD forward<_Fx>(_Val)));
(::
new
(
())
(::
std
::
<
>(
)));
}
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
template
<
class
,
class
>
void
(
&&
,
const
&
)
{
if
(!
(
))
{
return
;
}
using
=
<
<
>,
,
,
...>;
*
=
nullptr
;
<
,
>
(
);
_Reset_impl_alloc(_STD forward<_Fx>(_Val), _Ax, _Ptr, _Al, _Is_large<_Myimpl>());
(::
std
::
<
>(
),
,
_Ptr
,
_Al
,
<
>());
}
template
<
class
,
class
,
class
,
class
>
void
(
&&
,
const
&
,
*,
&
,
)
{
using
=
<
>;
const
auto
=
::
(
,
1
);
_Alimpl_traits::construct(_Al, _Unfancy(_Ptr), _STD forward<_Fx>(_Val), _Ax);
::
(
,
(
_Ptr
), ::
std
::
<
>(
),
);
::
(
,
_Ptr
,
1
);
(
(
_Ptr
));
}
template
<
class
,
class
,
class
,
class
>
void
(
&&
,
const
&
,
*,
&
,
)
{
*
=
static_cast
<
*>(
());
allocator_traits<_Alimpl>::construct(_Al, _Ptr, _STD forward<_Fx>(_Val), _Ax);
<
>::
(
,
_Ptr
, ::
std
::
<
>(
),
);
(
_Ptr
);
}
#endif /* _HAS_FUNCTION_ALLOCATOR_SUPPORT */
void
()
noexcept
{
if
(!
())
{
()->
(!
());
(
nullptr
);
}
}
void
(
&
)
noexcept
{
if
(!
() && !
.
())
{
*
=
();
(
.
());
.
(
_Temp
);
}
else
{
;
_Temp._Reset_move(_STD move(*this));
_Reset_move(_STD move(_Right));
_Right._Reset_move(_STD move(_Temp));
}
}
#if _HAS_STATIC_RTTI
const
&
()
const
noexcept
{
return
(
() ?
()->
() :
typeid
(
void
));
}
const
void
*
(
const
&
)
const
noexcept
{
return
(
() ?
()->
(
) :
nullptr
);
}
#endif /* _HAS_STATIC_RTTI */
private
:
bool
()
const
noexcept
{
return
(
()
());
}
union
{
;
char
[
_Space_size
];
*
[
_Small_object_num_ptrs
];
};
;
enum
{
=
_Small_object_num_ptrs
-
1
};
*
()
const
noexcept
{
return
(
.
[
_Small_object_num_ptrs
-
1
]);
}
void
(
*
)
noexcept
{
.
[
_Small_object_num_ptrs
-
1
] =
;
}
void
*
()
noexcept
{
return
(&
);
}
const
void
*
()
const
noexcept
{
return
(&
);
}
};
template
<
class
>
struct
;
#define _GET_FUNCTION_IMPL(CALL_OPT, X1, X2, X3) \
template<class _Ret, \
class... _Types> \
struct _Get_function_impl<_Ret CALL_OPT (_Types...)> \
{ /* determine type from argument list */ \
typedef _Func_class<_Ret, _Types...> type; \
};
_NON_MEMBER_CALL(_GET_FUNCTION_IMPL, X1, X2, X3)
template
<
class
,
class
...
>
struct
<
__cdecl
(
...)> {
typedef
<
,
...>
; };
template
<
class
,
class
...
>
struct
<
__fastcall
(
...)> {
typedef
<
,
...>
; };
template
<
class
,
class
...
>
struct
<
__stdcall
(
...)> {
typedef
<
,
...>
; };
template
<
class
,
class
...
>
struct
<
__vectorcall
(
...)> {
typedef
<
,
...>
; };
#undef _GET_FUNCTION_IMPL
template
<
class
>
class
:
public
<
>::
{
private
:
typedef
typename
<
>::
;
public
:
()
noexcept
{
}
(
)
noexcept
{
}
(
const
&
)
{
this
->
(
);
}
template
<
class
,
class
=
typename
::
template
<
&,
>>
(
)
{
this->_Reset(_STD move(_Func));
}
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
template
<
class
>
(
,
const
&)
noexcept
{
}
template
<
class
>
(
,
const
&,
)
noexcept
{
}
template
<
class
>
(
,
const
&
,
const
&
)
{
this
->
(
,
);
}
template
<
class
,
class
,
class
=
typename
::
template
<
&,
>>
(
,
const
&
,
)
{
this->_Reset_alloc(_STD move(_Func), _Ax);
}
#endif /* _HAS_FUNCTION_ALLOCATOR_SUPPORT */
&
(
const
&
)
{
(
).
(*
this
);
return
(*
this
);
}
(
&&
)
{
this->_Reset_move(_STD move(_Right));
}
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
template
<
class
>
(
,
const
&
,
&&
)
{
this->_Reset_alloc(_STD move(_Right), _Al);
}
#endif /* _HAS_FUNCTION_ALLOCATOR_SUPPORT */
&
(
&&
)
{
if (this != _STD addressof(_Right))
{
this
->
();
this->_Reset_move(_STD move(_Right));
}
return
(*
this
);
}
template
<
class
,
class
=
typename
::
template
<
<
>&,
>>
&
(
&&
)
{
function(_STD forward<_Fx>(_Func)).swap(*this);
return
(*
this
);
}
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
template
<
class
,
class
>
void
(
&&
,
const
&
)
{
function(allocator_arg, _Ax, _STD forward<_Fx>(_Func)).swap(*this);
(
allocator_arg
,
, ::
std
::
<
>(
)).
(*
this
);
}
#endif /* _HAS_FUNCTION_ALLOCATOR_SUPPORT */
&
(
)
noexcept
{
this
->
();
return
(*
this
);
}
template
<
class
>
&
(
<
>
)
noexcept
{
this
->
();
this
->
(
);
return
(*
this
);
}
void
(
&
)
noexcept
{
this
->
(
);
}
explicit
bool
()
const
noexcept
{
return
(!
this
->
());
}
#if _HAS_STATIC_RTTI
_NODISCARD const type_info& target_type() const noexcept
const
&
()
const
noexcept
{
return
(
this
->
());
}
template
<
class
>
_NODISCARD _Fx * target() noexcept
{
return
(
reinterpret_cast
<
*>(
const_cast
<
void
*>(
this
->
(
typeid
(
)))));
}
template
<
class
>
_NODISCARD const _Fx * target() const noexcept
const
*
()
const
noexcept
{
return
(
reinterpret_cast
<
const
*>(
this
->
(
typeid
(
))));
}
#else /* _HAS_STATIC_RTTI */
const type_info& target_type() const noexcept = delete; // requires static RTTI
template<class _Fx>
_Fx *target() noexcept = delete; // requires static RTTI
template<class _Fx>
const _Fx *target() const noexcept = delete; // requires static RTTI
#endif /* _HAS_STATIC_RTTI */
};
#if _HAS_CXX17
#define _FUNCTION_POINTER_DEDUCTION_GUIDE(CALL_OPT, X1, X2, X3) \
template<class _Ret, \
class... _Types> \
function(_Ret (CALL_OPT *)(_Types...)) \
-> function<_Ret (_Types...)>; // intentionally discards CALL_OPT
_NON_MEMBER_CALL(_FUNCTION_POINTER_DEDUCTION_GUIDE, X1, X2, X3)
#undef _FUNCTION_POINTER_DEDUCTION_GUIDE
// STRUCT TEMPLATE _Deduce_signature
template<class _Fx,
class = void>
struct _Deduce_signature
{ // can't deduce signature when &_Fx::operator() is missing, inaccessible, or ambiguous
};
template<class _Fx>
struct _Deduce_signature<_Fx, void_t<decltype(&_Fx::operator())>>
: _Is_memfunptr<decltype(&_Fx::operator())>::_Guide_type
{ // N4687 23.14.13.2.1 [func.wrap.func.con]/12
};
template<class _Fx>
function(_Fx)
-> function<typename _Deduce_signature<_Fx>::type>;
#endif /* _HAS_CXX17 */
template
<
class
>
inline
void
(
<
>&
,
<
>&
)
noexcept
{
.
(
);
}
template
<
class
>
_NODISCARD inline bool operator==(const function<_Fty>& _Other, nullptr_t) noexcept
inline
bool
(
const
<
>&
,
)
noexcept
{
return
(!
);
}
template
<
class
>
_NODISCARD inline bool operator==(nullptr_t, const function<_Fty>& _Other) noexcept
inline
bool
(
,
const
<
>&
)
noexcept
{
return
(!
);
}
template
<
class
>
_NODISCARD inline bool operator!=(const function<_Fty>& _Other, nullptr_t) noexcept
inline
bool
(
const
<
>&
,
)
noexcept
{
return
(
static_cast
<
bool
>(
));
}
template
<
class
>
_NODISCARD inline bool operator!=(nullptr_t, const function<_Fty>& _Other) noexcept
inline
bool
(
,
const
<
>&
)
noexcept
{
return
(
static_cast
<
bool
>(
));
}
template
<
int
>
struct
{
};
template
<
class
>
struct
:
<
int
,
0
>
{
};
template
<
int
>
struct
<
<
>>
:
<
int
,
>
{
};
template
<
class
>
struct
<
const
>
:
<
>::
{
};
template
<
class
>
struct
<
volatile
>
:
<
>::
{
};
template
<
class
>
struct
<
const
volatile
>
:
<
>::
{
};
template
<
class
>
_INLINE_VAR constexpr int is_placeholder_v = is_placeholder<_Ty>::value;
template
<
class
,
class
,
class
...
>
class
;
template
<
class
>
struct
:
{
};
template
<
class
,
class
,
class
...
>
struct
<
<
,
,
...>>
:
{
};
template
<
class
>
struct
<
const
>
:
<
>::
{
};
template
<
class
>
struct
<
volatile
>
:
<
>::
{
};
template
<
class
>
struct
<
const
volatile
>
:
<
>::
{
};
template
<
class
>
_INLINE_VAR constexpr bool is_bind_expression_v = is_bind_expression<_Ty>::value;
template
<
class
,
bool
=
<
<
>,
>,
bool
=
<
>,
int
=
<
>>
struct
;
template
<
class
>
struct
<
,
true
,
false
,
0
>
{
template
<
class
>
static
auto
(
&
,
&&)
->
typename
::type&
{
return
(
.get());
}
};
template
<
class
>
struct
<
,
false
,
true
,
0
>
{
#pragma warning(push)
#pragma warning(disable: 4100) // TRANSITION, VSO#181496, unreferenced formal parameter
#pragma warning(disable:
4100
)
template
<
class
,
...
>
static
auto
(
&
,
&&
,
<
...>)
-> decltype(_Tid(_STD get<_Jx>(_STD move(_Ut))...))
->
decltype
(
(::
std
::
<
>(::
std
::
(
))...))
{
return (_Tid(_STD get<_Jx>(_STD move(_Ut))...));
return
(
(::
std
::
<
>(::
std
::
(
))...));
}
#pragma warning(pop)
template
<
class
>
static
auto
(
&
,
&&
)
-> decltype(_Apply(_Tid, _STD move(_Ut),
->
decltype
(
(
, ::
std
::
(
),
<
<
>>()))
{
return (_Apply(_Tid, _STD move(_Ut),
<
<
>>()));
}
};
template
<
class
>
struct
<
,
false
,
false
,
0
>
{
template
<
class
>
static
&
(
&
,
&&)
{
return
(
);
}
};
template
<
class
,
int
>
struct
<
,
false
,
false
,
>
{
static_assert
(
>
0
,
"invalid is_placeholder value"
);
template
<
class
>
static
auto
(
&,
&&
)
-> decltype(_STD get<_Jx - 1>(_STD move(_Ut)))
->
decltype
(::
std
::
<
-
1
>(::
std
::
(
)))
{
return (_STD get<_Jx - 1>(_STD move(_Ut)));
return
(::
std
::
<
-
1
>(::
std
::
(
)));
}
};
template
<
class
,
class
>
inline
auto
(
&
,
&&
)
-> decltype(_Select_fixer<_Cv_TiD>::_Fix(_Tid, _STD move(_Ut)))
->
decltype
(
<
>::
(
, ::
std
::
(
)))
{
return (_Select_fixer<_Cv_TiD>::_Fix(_Tid, _STD move(_Ut)));
return
(
<
>::
(
, ::
std
::
(
)));
}
#pragma warning(push)
#pragma warning(disable: 4100) // TRANSITION, VSO#181496, unreferenced formal parameter
#pragma warning(disable:
4100
)
template
<
class
,
...
,
class
,
class
,
class
>
inline
auto
(
<
>,
<
...>,
&
,
&
,
&&
)
-> decltype(_Invoker_ret<_Ret>::_Call(_Obj, _Fix_arg(_STD get<_Ix>(_Tpl), _STD move(_Ut))...))
->
decltype
(
<
>::
(
,
(::
std
::
<
>(
), ::
std
::
(
))...))
{
return (_Invoker_ret<_Ret>::_Call(_Obj, _Fix_arg(_STD get<_Ix>(_Tpl), _STD move(_Ut))...));
return
(
<
>::
(
,
(::
std
::
<
>(
), ::
std
::
(
))...));
}
#pragma warning(pop)
template
<
class
>
struct
{
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type;
};
template
<
class
,
class
>
struct
{
typedef
<
>
;
typedef
typename
<
>::
;
typedef
<
<
,
>,
<
>,
<
>>
;
};
template
<
class
,
class
,
class
...
>
class
:
public
<
,
>::
{
private
:
typedef
<
...>
;
typedef
<
>
;
typedef
<
<
>...>
;
<
,
>
;
public
:
explicit
(
&&
,
&&...
)
: _Mypair(
_One_then_variadic_args_t
(),
_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...)
::
std
::
<
>(
), ::
std
::
<
>(
)...)
{
}
#define _BINDER_OPERATOR(CONST_OPT) \
template<class... _Unbound> \
auto operator()(_Unbound&&... _Unbargs) CONST_OPT \
-> decltype(_Call_binder(_Invoker_ret<_Ret>(), _Seq(), \
_Mypair._Get_first(), _Mypair._Get_second(), \
_STD forward_as_tuple(_STD forward<_Unbound>(_Unbargs)...))) \
{ /* invoke bound callable object with bound/unbound arguments */ \
return (_Call_binder(_Invoker_ret<_Ret>(), _Seq(), \
_Mypair._Get_first(), _Mypair._Get_second(), \
_STD forward_as_tuple(_STD forward<_Unbound>(_Unbargs)...))); \
}
_CLASS_DEFINE_CONST(_BINDER_OPERATOR)
template
<
class
...
>
auto
(
&&...
) ->
decltype
(
(
<
>(),
(),
.
(),
.
(), ::
std
::
(::
std
::
<
>(
)...))) {
return
(
(
<
>(),
(),
.
(),
.
(), ::
std
::
(::
std
::
<
>(
)...))); }
template
<
class
...
>
auto
(
&&...
)
const
->
decltype
(
(
<
>(),
(),
.
(),
.
(), ::
std
::
(::
std
::
<
>(
)...))) {
return
(
(
<
>(),
(),
.
(),
.
(), ::
std
::
(::
std
::
<
>(
)...))); }
#undef _BINDER_OPERATOR
};
template
<
class
,
class
...
>
_NODISCARD inline _Binder<_Unforced, _Fx, _Types...> bind(_Fx&& _Func, _Types&&... _Args)
inline
<
,
,
...>
(
&&
,
&&...
)
{
return (_Binder<_Unforced, _Fx, _Types...>(_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...));
return
(
<
,
,
...>(::
std
::
<
>(
), ::
std
::
<
>(
)...));
}
template
<
class
,
class
,
class
...
>
_NODISCARD _Binder<_Ret, _Fx, _Types...> bind(_Fx&& _Func, _Types&&... _Args)
{
return (_Binder<_Ret, _Fx, _Types...>(_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...));
return
(
<
,
,
...>(::
std
::
<
>(
), ::
std
::
<
>(
)...));
}
namespace
{
_INLINE_VAR constexpr _Ph<1> _1{};
_INLINE_VAR constexpr _Ph<2> _2{};
_INLINE_VAR constexpr _Ph<3> _3{};
_INLINE_VAR constexpr _Ph<4> _4{};
_INLINE_VAR constexpr _Ph<5> _5{};
_INLINE_VAR constexpr _Ph<6> _6{};
_INLINE_VAR constexpr _Ph<7> _7{};
_INLINE_VAR constexpr _Ph<8> _8{};
_INLINE_VAR constexpr _Ph<9> _9{};
_INLINE_VAR constexpr _Ph<10> _10{};
_INLINE_VAR constexpr _Ph<11> _11{};
_INLINE_VAR constexpr _Ph<12> _12{};
_INLINE_VAR constexpr _Ph<13> _13{};
_INLINE_VAR constexpr _Ph<14> _14{};
_INLINE_VAR constexpr _Ph<15> _15{};
_INLINE_VAR constexpr _Ph<16> _16{};
_INLINE_VAR constexpr _Ph<17> _17{};
_INLINE_VAR constexpr _Ph<18> _18{};
_INLINE_VAR constexpr _Ph<19> _19{};
_INLINE_VAR constexpr _Ph<20> _20{};
}
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
template
<
class
,
class
>
struct
<
<
>,
>
:
{
};
#endif /* _HAS_FUNCTION_ALLOCATOR_SUPPORT */
#if _HAS_CXX17
// HETEROGENEOUS MEMORY BLOCK UTILITIES
inline void _Add_alloc_size(size_t& _Size, const size_t _Size_added, const size_t _Alignment)
{ // moves _Size up to account for storing an object of size _Size_added with alignment
// _Alignment in a memory buffer
// assumes that the memory buffer will be allocated for the "worst" alignment used in the
// resulting buffer
const size_t _Align_masked = _Size & (_Alignment - 1u);
_Size += _Size_added;
if (_Align_masked != 0)
{
_Size += _Alignment - _Align_masked;
}
}
template<class _Ty> inline
void _Add_alloc_size(size_t& _Size)
{ // moves _Size up to account for allocating a _Ty
_Add_alloc_size(_Size, sizeof(_Ty), alignof(_Ty));
}
template<class _Ty> inline
void _Add_alloc_size(size_t& _Size, const size_t _Count)
{ // moves _Size up to account for allocating an array of _Count _Ty instances
if (static_cast<size_t>(-1) / sizeof(_Ty) < _Count)
{
_Xbad_alloc();
}
_Add_alloc_size(_Size, sizeof(_Ty) * _Count, alignof(_Ty));
}
inline void * _Decode_aligned_block(void *& _Base, size_t _Size, const size_t _Alignment)
{ // "allocates" an object of size _Size and alignment _Alignment from _Base, and shifts
// _Base up by the size necessary to decode that object.
auto _Space = static_cast<size_t>(-1);
auto _Result = _STD align(_Alignment, _Size, _Base, _Space);
_Base = static_cast<char *>(_Base) + _Size;
return (_Result);
}
template<class _Ty> inline
_Ty * _Decode_aligned_block(void *& _Base)
{ // "allocates" a _Ty from _Base
return (static_cast<_Ty *>(_Decode_aligned_block(_Base, sizeof(_Ty), alignof(_Ty))));
}
template<class _Ty> inline
_Ty * _Decode_aligned_block(void *& _Base, const size_t _Count)
{ // "allocates" an array of _Count _Ty instances from _Base
return (static_cast<_Ty *>(_Decode_aligned_block(_Base, sizeof(_Ty) * _Count, alignof(_Ty))));
}
// STRUCT _Global_delete
struct _Global_delete
{
void operator()(void * const _Ptr) const
{
::operator delete(_Ptr);
}
};
// CLASS TEMPLATE default_searcher
template<class _FwdItHaystack,
class _FwdItPat,
class _Pred_eq> inline
pair<_FwdItHaystack, _FwdItHaystack> _Search_pair_unchecked(_FwdItHaystack _First1, _FwdItHaystack _Last1,
_FwdItPat _First2, _FwdItPat _Last2, _Pred_eq& _Eq,
forward_iterator_tag, forward_iterator_tag)
{ // find first [_First2, _Last2) satisfying _Eq, arbitrary iterators
for (; ; ++_First1)
{ // loop until match or end of a sequence
_FwdItHaystack _Mid1 = _First1;
for (_FwdItPat _Mid2 = _First2; ; ++_Mid1, (void)++_Mid2)
{
if (_Mid2 == _Last2)
{
return {_First1, _Mid1};
}
if (_Mid1 == _Last1)
{
return {_Last1, _Last1};
}
if (!_Eq(*_Mid1, *_Mid2))
{
break;
}
}
}
}
template<class _FwdItHaystack,
class _FwdItPat,
class _Pred_eq> inline
pair<_FwdItHaystack, _FwdItHaystack> _Search_pair_unchecked(_FwdItHaystack _First1, _FwdItHaystack _Last1,
_FwdItPat _First2, _FwdItPat _Last2, _Pred_eq& _Eq,
random_access_iterator_tag, random_access_iterator_tag)
{ // find first [_First2, _Last2) satisfying _Eq, random-access iterators
_Iter_diff_t<_FwdItHaystack> _Count1 = _Last1 - _First1;
_Iter_diff_t<_FwdItPat> _Count2 = _Last2 - _First2;
for (; _Count2 <= _Count1; ++_First1, (void)--_Count1)
{ // room for match, try it
_FwdItHaystack _Mid1 = _First1;
for (_FwdItPat _Mid2 = _First2; ; ++_Mid1, (void)++_Mid2)
{
if (_Mid2 == _Last2)
{
return {_First1, _Mid1};
}
if (!_Eq(*_Mid1, *_Mid2))
{
break;
}
}
}
return {_Last1, _Last1};
}
template<class _FwdItPat,
class _Pred_eq = equal_to<>>
class default_searcher
{ // functor to search haystacks for needles
public:
default_searcher(_FwdItPat _First, _FwdItPat _Last, _Pred_eq _Eq = _Pred_eq())
: _Data{_One_then_variadic_args_t{}, _STD move(_Eq), pair<_FwdItPat, _FwdItPat>{_First, _Last}}
{ // construct a default_searcher
const auto& _Pat = _Data._Get_second();
_Adl_verify_range(_Pat.first, _Pat.second);
}
template<class _FwdItHaystack>
_NODISCARD pair<_FwdItHaystack, _FwdItHaystack> operator()(_FwdItHaystack _First, _FwdItHaystack _Last) const
{ // search [_First, _Last) for the searcher's pattern
_Adl_verify_range(_First, _Last);
const auto& _Eq = _Data._Get_first();
const auto& _Pat = _Data._Get_second();
_Adl_verify_range(_Pat.first, _Pat.second); // check again to ensure container is not destroyed
const auto _Result = _Search_pair_unchecked(_Get_unwrapped(_First), _Get_unwrapped(_Last),
_Get_unwrapped(_Pat.first), _Get_unwrapped(_Pat.second), _Eq,
_Iter_cat_t<_FwdItHaystack>{}, _Iter_cat_t<_FwdItPat>{});
_Seek_wrapped(_Last, _Result.second);
_Seek_wrapped(_First, _Result.first);
return {_First, _Last};
}
private:
_Compressed_pair<_Pred_eq, pair<_FwdItPat, _FwdItPat>> _Data;
};
// STRUCT TEMPLATE _Boyer_moore_hash_delta_1_table
template<class _RanItPat,
class _Hash_ty,
class _Pred_eq>
struct _Boyer_moore_hash_delta_1_table
{ // stores the Boyer-Moore delta_1 table using a hash table
using _Value_t = _Iter_value_t<_RanItPat>;
using _Diff = _Iter_diff_t<_RanItPat>;
_Boyer_moore_hash_delta_1_table(_RanItPat _Pat_first_arg, _Unwrapped_t<_RanItPat> _UPat_first,
const _Diff _Pat_size_arg, _Hash_ty&& _Hash_fn, _Pred_eq&& _Eq)
: _Pat_first(_Pat_first_arg),
_Pat_size(_Pat_size_arg),
_Map(0, _STD move(_Hash_fn), _STD move(_Eq))
{ // initialize a delta_1 hash table
for (_Diff _Idx = 1; _Idx <= _Pat_size; ++_Idx, (void)++_UPat_first)
{
_Map.insert_or_assign(*_UPat_first, _Pat_size - _Idx);
}
}
_Diff _Lookup(const _Value_t& _Value) const
{ // lookup the "character" _Value in the table, returning the maximum shift if found
const auto _Iter = _Map.find(_Value);
if (_Iter == _Map.end())
{
return (_Pat_size);
}
return (_Iter->second);
}
_Pred_eq _Get_eq() const
{ // return the comparison predicate
return (_Map.key_eq());
}
const _RanItPat _Pat_first;
const _Diff _Pat_size;
private:
unordered_map<_Value_t, _Diff, _Hash_ty, _Pred_eq> _Map;
};
// STRUCT TEMPLATE _Boyer_moore_flat_delta_1_table
template<class _RanItPat,
_Iter_diff_t<_RanItPat> _Limit>
struct _Boyer_moore_flat_delta_1_table
{ // stores the Boyer-Moore delta_1 table using a plain array lookup
using _Value_t = _Iter_value_t<_RanItPat>;
using _Diff = _Iter_diff_t<_RanItPat>;
_Boyer_moore_flat_delta_1_table(_RanItPat _Pat_first_arg, _Unwrapped_t<_RanItPat> _UPat_first,
const _Diff _Pat_size_arg, _Unused_parameter, _Unused_parameter)
: _Pat_first(_Pat_first_arg),
_Pat_size(_Pat_size_arg)
{ // initialize a delta_1 flat table
_STD fill(_STD begin(_Table), _STD end(_Table), _Pat_size);
for (_Diff _Idx = 1; _Idx <= _Pat_size; ++_Idx, (void)++_UPat_first)
{
_Table[_Unsigned_value(*_UPat_first)] = _Pat_size - _Idx;
}
}
_Diff _Lookup(const _Value_t _Value) const
{ // lookup the "character" _Value in the table
const auto _UValue = _Unsigned_value(_Value);
if (_UValue < _STD size(_Table))
{
return (_Table[_UValue]);
}
return (_Pat_size);
}
equal_to<> _Get_eq() const
{ // return an equality comparer
return {};
}
const _RanItPat _Pat_first;
const _Diff _Pat_size;
private:
_Diff _Table[_Limit];
};
// FUNCTION TEMPLATE _Build_boyer_moore_delta_2_table
template<class _RanItPat,
class _Pred_eq> inline
void _Build_boyer_moore_delta_2_table(
_Iter_diff_t<_RanItPat> * _Shifts,
const _RanItPat _Pat_first, const _Iter_diff_t<_RanItPat> _Pat_size,
_Pred_eq& _Eq)
{ // builds Boyer-Moore's delta_2 table from a pattern [_Pat_first, _Pat_first + _Pat_size)
// pre: _Shifts is a pointer to _Pat_size _Iter_diff_t<_RanIt>s
if (_Pat_size == 0)
{
return;
}
using _Diff = _Iter_diff_t<_RanItPat>;
unique_ptr<_Diff[]> _Suffix_fn{::new _Diff[static_cast<size_t>(_Pat_size)]};
for (_Diff _Idx = 0; _Idx < _Pat_size; ++_Idx)
{
_Shifts[_Idx] = 2 * _Pat_size - _Idx - 1;
}
_Diff _Suffix = _Pat_size;
for (_Diff _Idx = _Pat_size; _Idx > 0; --_Idx, (void)--_Suffix)
{
_Suffix_fn[static_cast<size_t>(_Idx - 1)] = _Suffix;
while (_Suffix < _Pat_size && !_Eq(_Pat_first[_Idx - 1], _Pat_first[_Suffix]))
{
_Shifts[_Suffix] = _Min_value(_Shifts[_Suffix], _Pat_size - _Idx);
_Suffix = _Suffix_fn[static_cast<size_t>(_Suffix)];
}
}
for (_Diff _Idx = 0; _Idx <= _Suffix; ++_Idx)
{
_Shifts[_Idx] = _Min_value(_Shifts[_Idx], _Pat_size + _Suffix - _Idx);
}
}
// FUNCTION TEMPLATE _Boyer_moore_search
template<class _Delta1_t,
class _RanItHaystack> inline
pair<_RanItHaystack, _RanItHaystack> _Boyer_moore_search(
const _Delta1_t& _Delta1, typename _Delta1_t::_Diff * _Delta2,
_RanItHaystack _First, _RanItHaystack _Last)
{ // run the loop of the Boyer-Moore string search algorithm
static_assert(is_same_v<typename _Delta1_t::_Value_t, _Iter_value_t<_RanItHaystack>>,
"boyer_moore_searcher requires matching iterator value types");
using _Diff = typename _Delta1_t::_Diff;
_Adl_verify_range(_First, _Last);
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
const auto _Pat_size = _Delta1._Pat_size;
if (_Pat_size == 0)
{
return {_First, _First};
}
const auto _UPat_first = _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
const auto _Eq = _Delta1._Get_eq();
_Diff _Shift = _Pat_size - 1;
while (_Shift < _ULast - _UFirst)
{
_UFirst += _Shift;
_Shift = _Delta1._Lookup(*_UFirst);
if (_Shift == 0)
{ // that is, *_UFirst == "_Pat.back()"
_Diff _Idx = _Pat_size - 1;
do
{
if (_Idx == 0)
{
_Seek_wrapped(_Last, _UFirst + _Pat_size);
_Seek_wrapped(_First, _UFirst);
return {_First, _Last};
}
--_Idx;
--_UFirst;
}
while (_Eq(*_UFirst, _UPat_first[_Idx]));
_Shift = _Max_value(_Delta1._Lookup(*_UFirst), _Delta2[_Idx]);
}
}
_Seek_wrapped(_Last, _ULast);
_Seek_wrapped(_First, _ULast);
return {_First, _Last};
}
// FUNCTION TEMPLATE _Boyer_moore_horspool_search
template<class _Delta1_t,
class _RanItHaystack> inline
pair<_RanItHaystack, _RanItHaystack> _Boyer_moore_horspool_search(
const _Delta1_t& _Delta1,
_RanItHaystack _First, _RanItHaystack _Last)
{ // run the loop of the Boyer-Moore-Horspool string search algorithm
static_assert(is_same_v<typename _Delta1_t::_Value_t, _Iter_value_t<_RanItHaystack>>,
"boyer_moore_horspool_searcher requires matching iterator value types");
using _Diff = typename _Delta1_t::_Diff;
_Adl_verify_range(_First, _Last);
const auto _Pat_size = _Delta1._Pat_size;
if (_Pat_size == 0)
{
return {_First, _First};
}
auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
const auto _UPat_first = _Get_unwrapped_n(_Delta1._Pat_first, _Pat_size);
const auto _Eq = _Delta1._Get_eq();
_Diff _Shift = _Pat_size - 1;
while (_Shift < _ULast - _UFirst)
{
_UFirst += _Shift;
_Shift = _Delta1._Lookup(*_UFirst);
if (_Shift == 0)
{ // that is, *_UFirst == "_Pat.back()"
const auto _Candidate = _UFirst - (_Pat_size - 1);
if (_Equal_unchecked(_UPat_first, _UPat_first + (_Pat_size - 1), _Candidate, _Pass_fn(_Eq)))
{
_Seek_wrapped(_Last, _Candidate + _Pat_size);
_Seek_wrapped(_First, _Candidate);
return {_First, _Last};
}
_Shift = 1;
}
}
_Seek_wrapped(_Last, _ULast);
_Seek_wrapped(_First, _ULast);
return {_First, _Last};
}
// STRUCT AND ALIAS TEMPLATES _Boyer_moore_traits
template<class _RanItPat,
class _Hash_ty,
class _Pred_eq,
class _Delta1_t>
struct _Single_delta1_type_boyer_moore_traits
{
using _Diff = _Iter_diff_t<_RanItPat>;
// uses buffers of the form {
// _Atomic_counter_t _Ref_count
// _Delta1_t _Delta1
// _Diff _Delta2[_Pattern_size] // not used for Boyer-Moore-Horspool
// }
template<bool _Build_delta2>
static void * _Build_boyer_moore(_RanItPat _First, _RanItPat _Last,
_Hash_ty _Hash_fn, _Pred_eq _Eq)
{ // builds data tables for the Boyer-Moore string search algorithm
_Adl_verify_range(_First, _Last);
const auto _UFirst = _Get_unwrapped(_First);
const auto _Pat_size_raw = _Get_unwrapped(_Last) - _UFirst;
using _CT = common_type_t<_Iter_diff_t<_RanItPat>, size_t>;
if (static_cast<_CT>(_Pat_size_raw) > static_cast<_CT>(SIZE_MAX))
{
_Xbad_alloc();
}
const auto _Pat_size = static_cast<size_t>(_Pat_size_raw);
size_t _Buf_size = 0;
_Add_alloc_size<_Atomic_counter_t>(_Buf_size);
_Add_alloc_size<_Delta1_t>(_Buf_size);
if (_Build_delta2)
{
_Add_alloc_size<_Diff>(_Buf_size, _Pat_size);
}
unique_ptr<void, _Global_delete> _Buf_bytes(::operator new(_Buf_size));
void * _Buf = _Buf_bytes.get();
*_Decode_aligned_block<_Atomic_counter_t>(_Buf) = 1;
void * const _Delta1 = _Decode_aligned_block<_Delta1_t>(_Buf);
if (_Build_delta2)
{
_Build_boyer_moore_delta_2_table(_Decode_aligned_block<_Diff>(_Buf, _Pat_size),
_UFirst, _Pat_size_raw, _Eq);
}
::new (_Delta1) _Delta1_t(_First, _UFirst, _Pat_size_raw, _STD move(_Hash_fn), _STD move(_Eq));
return (_Buf_bytes.release());
}
template<class _RanItHaystack>
static pair<_RanItHaystack, _RanItHaystack> _Use_boyer_moore(void * _Data,
_RanItHaystack _First, _RanItHaystack _Last)
{ // decodes data tables for the Boyer-Moore string search algorithm
(void)_Decode_aligned_block<_Atomic_counter_t>(_Data);
const auto _Delta1 = _Decode_aligned_block<_Delta1_t>(_Data);
const auto _Delta2 = _Decode_aligned_block<_Diff>(_Data, static_cast<size_t>(_Delta1->_Pat_size));
return (_Boyer_moore_search(*_Delta1, _Delta2, _First, _Last));
}
template<class _RanItHaystack>
static pair<_RanItHaystack, _RanItHaystack> _Use_boyer_moore_horspool(void * _Data,
_RanItHaystack _First, _RanItHaystack _Last)
{ // decodes data tables for the Boyer-Moore string search algorithm
(void)_Decode_aligned_block<_Atomic_counter_t>(_Data);
const auto _Delta1 = _Decode_aligned_block<_Delta1_t>(_Data);
return (_Boyer_moore_horspool_search(*_Delta1, _First, _Last));
}
static void _Destroy(void * const _Base) noexcept
{ // destroys data tables for either the Boyer-Moore or Boyer-Moore-Horspool
// string search algorithms
void * _Data = _Base;
(void)_Decode_aligned_block<_Atomic_counter_t>(_Data);
_Decode_aligned_block<_Delta1_t>(_Data)->~_Delta1_t();
::operator delete(_Base);
}
};
template<class _RanItPat,
class _Hash_ty,
class _Pred_eq>
using _Boyer_moore_traits_char_mode = _Single_delta1_type_boyer_moore_traits<_RanItPat, _Hash_ty, _Pred_eq,
_Boyer_moore_flat_delta_1_table<_RanItPat, 256>>;
template<class _RanItPat>
struct _Boyer_moore_traits_wchar_t_mode
{
using _Value_t = _Iter_value_t<_RanItPat>;
using _Diff = _Iter_diff_t<_RanItPat>;
using _Big_table_t = _Boyer_moore_flat_delta_1_table<_RanItPat, 65536>;
using _Small_table_t = _Boyer_moore_flat_delta_1_table<_RanItPat, 256>;
// uses buffers of the form {
// _Atomic_counter_t _Ref_count
// bool _Use_large_table // true if anything in the pattern is > 255
// conditional_t<_Use_large_table, _Big_table_t, _Small_table_t> _Delta1
// _Diff _Delta2[_Pattern_size] // not used for Boyer-Moore-Horspool
// }
template<bool _Build_delta2>
static void * _Build_boyer_moore(_RanItPat _First, _RanItPat _Last,
_Unused_parameter, _Unused_parameter)
{ // builds data tables for the Boyer-Moore string search algorithm
_Adl_verify_range(_First, _Last);
const auto _UFirst = _Get_unwrapped(_First);
const auto _ULast = _Get_unwrapped(_Last);
const auto _Pat_size_raw = _ULast - _UFirst;
using _CT = common_type_t<_Iter_diff_t<_RanItPat>, size_t>;
if (static_cast<_CT>(_Pat_size_raw) > static_cast<_CT>(SIZE_MAX))
{
_Xbad_alloc();
}
const auto _Pat_size = static_cast<size_t>(_Pat_size_raw);
size_t _Buf_size = 0;
_Add_alloc_size<_Atomic_counter_t>(_Buf_size);
bool _Use_large_table = false;
for (auto _Temp = _UFirst; _Temp != _ULast; ++_Temp)
{
if (_Unsigned_value(*_Temp) > 255)
{
_Use_large_table = true;
break;
}
}
_Add_alloc_size<bool>(_Buf_size);
if (_Use_large_table)
{
_Add_alloc_size<_Big_table_t>(_Buf_size);
}
else
{
_Add_alloc_size<_Small_table_t>(_Buf_size);
}
if (_Build_delta2)
{
_Add_alloc_size<_Diff>(_Buf_size, _Pat_size);
}
unique_ptr<void, _Global_delete> _Buf_bytes(::operator new(_Buf_size));
void * _Buf = _Buf_bytes.get();
*_Decode_aligned_block<_Atomic_counter_t>(_Buf) = 1;
*_Decode_aligned_block<bool>(_Buf) = _Use_large_table;
if (_Use_large_table)
{
using _Delta1_t = _Big_table_t;
::new (static_cast<void *>(_Decode_aligned_block<_Delta1_t>(_Buf)))
_Delta1_t(_First, _UFirst, _Pat_size_raw, {}, {});
}
else
{
using _Delta1_t = _Small_table_t;
::new (static_cast<void *>(_Decode_aligned_block<_Delta1_t>(_Buf)))
_Delta1_t(_First, _UFirst, _Pat_size_raw, {}, {});
}
if (_Build_delta2)
{
equal_to<> _Eq;
_Build_boyer_moore_delta_2_table(_Decode_aligned_block<_Diff>(_Buf, _Pat_size),
_UFirst, _Pat_size_raw, _Eq);
}
return (_Buf_bytes.release());
}
template<class _RanItHaystack>
static pair<_RanItHaystack, _RanItHaystack> _Use_boyer_moore(void * _Data,
_RanItHaystack _First, _RanItHaystack _Last)
{ // decodes data tables for the Boyer-Moore string search algorithm
(void)_Decode_aligned_block<_Atomic_counter_t>(_Data);
if (*_Decode_aligned_block<bool>(_Data))
{
const auto _Delta1 = _Decode_aligned_block<_Big_table_t>(_Data);
const auto _Delta2 = _Decode_aligned_block<_Diff>(_Data, static_cast<size_t>(_Delta1->_Pat_size));
return (_Boyer_moore_search(*_Delta1, _Delta2, _First, _Last));
}
else
{
const auto _Delta1 = _Decode_aligned_block<_Small_table_t>(_Data);
const auto _Delta2 = _Decode_aligned_block<_Diff>(_Data, static_cast<size_t>(_Delta1->_Pat_size));
return (_Boyer_moore_search(*_Delta1, _Delta2, _First, _Last));
}
}
template<class _RanItHaystack>
static pair<_RanItHaystack, _RanItHaystack> _Use_boyer_moore_horspool(void * _Data,
_RanItHaystack _First, _RanItHaystack _Last)
{ // decodes data tables for the Boyer-Moore string search algorithm
(void)_Decode_aligned_block<_Atomic_counter_t>(_Data);
if (*_Decode_aligned_block<bool>(_Data))
{
const auto _Delta1 = _Decode_aligned_block<_Big_table_t>(_Data);
return (_Boyer_moore_horspool_search(*_Delta1, _First, _Last));
}
else
{
const auto _Delta1 = _Decode_aligned_block<_Small_table_t>(_Data);
return (_Boyer_moore_horspool_search(*_Delta1, _First, _Last));
}
}
static void _Destroy(void * const _Base) noexcept
{ // destroys data tables for either the Boyer-Moore or Boyer-Moore-Horspool
// string search algorithms
void * _Data = _Base;
(void)_Decode_aligned_block<_Atomic_counter_t>(_Data);
if (*_Decode_aligned_block<bool>(_Data))
{
const auto _Delta1 = _Decode_aligned_block<_Big_table_t>(_Data);
_Delta1->~_Big_table_t();
}
else
{
const auto _Delta1 = _Decode_aligned_block<_Small_table_t>(_Data);
_Delta1->~_Small_table_t();
}
static_assert(is_trivially_destructible_v<_Diff>, "allows Boyer-Moore and Boyer-Moore-Horspool to "
"share cleanup functions");
::operator delete(_Base);
}
};
template<class _RanItPat,
class _Hash_ty,
class _Pred_eq>
using _Boyer_moore_traits_general_mode = _Single_delta1_type_boyer_moore_traits<_RanItPat, _Hash_ty, _Pred_eq,
_Boyer_moore_hash_delta_1_table<_RanItPat, _Hash_ty, _Pred_eq>>;
template<class _RanItPat,
class _Hash_ty,
class _Pred_eq,
class _Value_t = _Iter_value_t<_RanItPat>>
using _Boyer_moore_traits = conditional_t<is_integral_v<_Value_t> && sizeof(_Value_t) <= 2
&& (is_same_v<equal_to<>, _Pred_eq> || is_same_v<equal_to<_Value_t>, _Pred_eq>),
conditional_t<sizeof(_Value_t) == 1, _Boyer_moore_traits_char_mode<_RanItPat, _Hash_ty, _Pred_eq>,
_Boyer_moore_traits_wchar_t_mode<_RanItPat>>,
_Boyer_moore_traits_general_mode<_RanItPat, _Hash_ty, _Pred_eq>>;
// CLASS TEMPLATE boyer_moore_searcher
template<class _RanItPat,
class _Hash_ty = hash<_Iter_value_t<_RanItPat>>,
class _Pred_eq = equal_to<>>
class boyer_moore_searcher
{ // an implementation of the Boyer-Moore string search algorithm
public:
boyer_moore_searcher(const _RanItPat _First, const _RanItPat _Last,
_Hash_ty _Hash_fn = _Hash_ty(), _Pred_eq _Eq = _Pred_eq())
: _Data(_Traits::template _Build_boyer_moore<true>(_First, _Last,
_STD move(_Hash_fn), _STD move(_Eq)))
{ // preprocess a pattern for use with the Boyer-Moore string search algorithm
}
boyer_moore_searcher(const boyer_moore_searcher& _Other) noexcept // strengthened
: _Data(_Other)
{ // copy an instance of the Boyer-Moore string search algorithm
_MT_INCR(*static_cast<_Atomic_counter_t *>(_Data));
}
~boyer_moore_searcher() noexcept
{ // destroy this instance
if (_MT_DECR(*static_cast<_Atomic_counter_t *>(_Data)) == 0)
{
_Traits::_Destroy(_Data);
}
}
boyer_moore_searcher& operator=(const boyer_moore_searcher& _Other) noexcept // strengthened
{ // assign over this instance
boyer_moore_searcher _Cpy(_Other);
swap(_Data, _Other._Data);
}
template<class _RanItHaystack>
_NODISCARD pair<_RanItHaystack, _RanItHaystack> operator()(
const _RanItHaystack _First, const _RanItHaystack _Last) const
{ // search for the preprocessed pattern in [_First, _Last)
return (_Traits::_Use_boyer_moore(_Data, _First, _Last));
}
private:
using _Traits = _Boyer_moore_traits<_RanItPat, _Hash_ty, _Pred_eq>;
void * _Data;
};
// CLASS TEMPLATE boyer_moore_horspool_searcher
template<class _RanItPat,
class _Hash_ty = hash<_Iter_value_t<_RanItPat>>,
class _Pred_eq = equal_to<>>
class boyer_moore_horspool_searcher
{ // an implementation of the Boyer-Moore-Horspool string search algorithm
// (equivalent to Boyer-Moore without the second table)
public:
boyer_moore_horspool_searcher(const _RanItPat _First, const _RanItPat _Last,
_Hash_ty _Hash_fn = _Hash_ty(), _Pred_eq _Eq = _Pred_eq())
: _Data(_Traits::template _Build_boyer_moore<false>(_First, _Last,
_STD move(_Hash_fn), _STD move(_Eq)))
{ // preprocess a pattern for use with the Boyer-Moore-Horspool string search algorithm
}
boyer_moore_horspool_searcher(
const boyer_moore_horspool_searcher& _Other) noexcept // strengthened
: _Data(_Other)
{ // copy an instance of the Boyer-Moore-Horspool string search algorithm
_MT_INCR(*static_cast<_Atomic_counter_t *>(_Data));
}
~boyer_moore_horspool_searcher() noexcept
{
if (_MT_DECR(*static_cast<_Atomic_counter_t *>(_Data)) == 0)
{
_Traits::_Destroy(_Data);
}
}
boyer_moore_horspool_searcher& operator=(
const boyer_moore_horspool_searcher& _Other) noexcept // strengthened
{ // assign over this instance
boyer_moore_horspool_searcher _Cpy(_Other);
swap(_Data, _Other._Data);
}
template<class _RanItHaystack>
_NODISCARD pair<_RanItHaystack, _RanItHaystack> operator()(
const _RanItHaystack _First, const _RanItHaystack _Last) const
{ // search for the preprocessed pattern in [_First, _Last)
return (_Traits::_Use_boyer_moore_horspool(_Data, _First, _Last));
}
private:
using _Traits = _Boyer_moore_traits<_RanItPat, _Hash_ty, _Pred_eq>;
void * _Data;
};
#endif /* _HAS_CXX17 */
#if _HAS_TR1_NAMESPACE
namespace _DEPRECATE_TR1_NAMESPACE tr1 {
namespace
[[deprecated(
"warning STL4002: "
"The non-Standard std::tr1 namespace and TR1-only machinery are deprecated and will be REMOVED. You can "
"define _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING to acknowledge that you have received this warning."
)]]
{
using _STD bad_function_call;
using _STD is_bind_expression;
using _STD is_placeholder;
namespace
{
using namespace _STD placeholders;
using
namespace
::
std
::
placeholders
;
}
}
#endif /* _HAS_TR1_NAMESPACE */
#if _HAS_FUNCTION_ALLOCATOR_SUPPORT
template
<
class
,
class
,
class
,
class
...
>
inline
<
,
,
,
...>::
(
&&...
)
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
{
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
auto
&
=
();
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
return (_Invoker_ret<_Rx>::_Call(_The_callee, _STD forward<_Types>(_Args)...));
return
(
<
>::
(
_The_callee
, ::
std
::
<
>(
)...));
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
}
#endif /* _HAS_FUNCTION_ALLOCATOR_SUPPORT */
template
<
class
,
class
,
class
...
>
inline
<
,
,
...>::
(
&&...
)
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
{
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
return (_Invoker_ret<_Rx>::_Call(_Callee, _STD forward<_Types>(_Args)...));
return
(
<
>::
(
, ::
std
::
<
>(
)...));
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
}
template
<
class
,
class
...
>
inline
<
,
...>::
(
...
)
const
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
{
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
if
(
())
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
{
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
();
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
}
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
const
auto
=
();
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
return (_Impl->_Do_call(_STD forward<_Types>(_Args)...));
return
(
_Impl
->
(::
std
::
<
>(
)...));
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
}
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
#pragma warning(pop)
#pragma warning(pop)
#pragma pack(pop)
#endif /* RC_INVOKED */
#endif /* _FUNCTIONAL_ */
#pragma pack(pop)