File Index Symbol Index

// type_traits standard header (core)
#pragma once
#ifndef _TYPE_TRAITS_
#define _TYPE_TRAITS_
#ifndef RC_INVOKED #include <xstddef>
_STL_DISABLE_CLANG_WARNINGS
#pragma push_macro("new")
#undef new
// STRUCT TEMPLATE integer_sequence
template
<
class
_Ty
,
_Ty
...
_Vals
>
struct
integer_sequence
{
// sequence of integer parameters
static_assert
(
is_integral_v
<
_Ty
>,
"integer_sequence<T, I...> requires T to be an integral type."
);
using
value_type
=
_Ty
; {
// get length of parameter list
return
(
sizeof
...(
_Vals
)); } };
// ALIAS TEMPLATE make_integer_sequence
template
<
class
_Ty
,
_Ty
_Size
>
using
make_integer_sequence
= __make_integer_seq<
integer_sequence
,
_Ty
,
_Size
>;
template
<
size_t
...
_Vals
>
using
index_sequence
=
integer_sequence
<
size_t
,
_Vals
...>;
template
<
size_t
_Size
>
using
make_index_sequence
=
make_integer_sequence
<
size_t
,
_Size
>;
template
<
class
...
_Types
>
using
index_sequence_for
=
make_index_sequence
<
sizeof
...(
_Types
)>;
// STRUCT TEMPLATE conjunction
template
<
bool
_First_value
,
class
_First
,
class
...
_Rest
>
struct
_Conjunction
{
// handle false trait or last trait
using
type
=
_First
; };
template
<
class
_True
,
class
_Next
,
class
...
_Rest
>
struct
_Conjunction
<
true
,
_True
,
_Next
,
_Rest
...> {
// the first trait is true, try the next one
using
type
=
typename
_Conjunction
<
_Next
::value,
_Next
,
_Rest
...>::
type
; };
template
<
class
...
_Traits
>
struct
conjunction
:
true_type
{
// If _Traits is empty, true_type
};
template
<
class
_First
,
class
...
_Rest
>
struct
conjunction
<
_First
,
_Rest
...> :
_Conjunction
<
_First
::value,
_First
,
_Rest
...>::
type
{
// Otherwise, if any of _Traits are false, the first false trait
// Otherwise, the last trait in _Traits
};
template
<
class
...
_Traits
>
// STRUCT TEMPLATE disjunction
template
<
bool
_First_value
,
class
_First
,
class
...
_Rest
>
struct
_Disjunction
{
// handle true trait or last trait
using
type
=
_First
; };
template
<
class
_False
,
class
_Next
,
class
...
_Rest
>
struct
_Disjunction
<
false
,
_False
,
_Next
,
_Rest
...> {
// first trait is false, try the next trait
using
type
=
typename
_Disjunction
<
_Next
::value,
_Next
,
_Rest
...>::
type
; };
template
<
class
...
_Traits
>
struct
disjunction
:
false_type
{
// If _Traits is empty, false_type
};
template
<
class
_First
,
class
...
_Rest
>
struct
disjunction
<
_First
,
_Rest
...> :
_Disjunction
<
_First
::value,
_First
,
_Rest
...>::
type
{
// Otherwise, if any of _Traits are true, the first true trait
// Otherwise, the last trait in _Traits
};
template
<
class
...
_Traits
>
// STRUCT TEMPLATE negation
template
<
class
_Trait
>
struct
negation
:
bool_constant
<!
static_cast
<
bool
>(
_Trait
::value)> {
// The negated result of _Trait
};
template
<
class
_Trait
>
// VARIABLE TEMPLATE _Is_any_of_v
template
<
class
_Ty
,
class
...
_Types
>
// STRUCT TEMPLATE _Arg_types
template
<
class
...
_Types
>
struct
_Arg_types
{
// provide argument_type, etc. (sometimes)
};
template
<
class
_Ty1
>
struct
_Arg_types
<
_Ty1
> {
// provide argument_type, etc. (sometimes)
};
template
<
class
_Ty1
,
class
_Ty2
>
struct
_Arg_types
<
_Ty1
,
_Ty2
> {
// provide argument_type, etc. (sometimes)
};
// STRUCT TEMPLATE is_function
template
<
class
_Ty
>
struct
_Is_function
{
// determine whether _Ty is a function
using
_Bool_type
=
false_type
; };
#define _IS_FUNCTION(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \
template<class _Ret, \
class... _Types> \
struct _Is_function<_Ret CALL_OPT (_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> \
: _Arg_types<_Types...> \
{ /* determine whether _Ty is a function */ \
using _Bool_type = true_type; \
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \
};
#undef _IS_FUNCTION
#define _IS_FUNCTION_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \
template<class _Ret, \
class... _Types> \
struct _Is_function<_Ret (_Types..., ...) CV_REF_NOEXCEPT_OPT> \
{ /* no calling conventions for ellipsis */ \
using _Bool_type = true_type; \
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \
};
#undef _IS_FUNCTION_ELLIPSIS
template
<
class
_Ty
>
struct
is_function
:
_Is_function
<
_Ty
>::
_Bool_type
{
// determine whether _Ty is a function
};
template
<
class
_Ty
>
template
<
class
_Ty
>
struct
_Is_memfunptr
{
// base class for member function pointer predicates
using
_Bool_type
=
false_type
; };
#define _IS_MEMFUNPTR(CALL_OPT, CV_OPT, REF_OPT, NOEXCEPT_OPT) \
template<class _Ret, \
class _Arg0, \
class... _Types> \
struct _Is_memfunptr<_Ret (CALL_OPT _Arg0::*)(_Types...) CV_OPT REF_OPT NOEXCEPT_OPT> \
: _Arg_types<CV_OPT _Arg0 *, _Types...> \
{ /* base class for member function pointer predicates */ \
using _Bool_type = true_type; \
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \
using _Class_type = _Arg0; \
using _Guide_type = enable_if<!is_same_v<int REF_OPT, int&&>, _Ret (_Types...)>; \
};
#undef _IS_MEMFUNPTR
#define _IS_MEMFUNPTR_ELLIPSIS(CV_REF_NOEXCEPT_OPT) \
template<class _Ret, \
class _Arg0, \
class... _Types> \
struct _Is_memfunptr<_Ret (_Arg0::*)(_Types..., ...) CV_REF_NOEXCEPT_OPT> \
{ /* no calling conventions for ellipsis */ \
using _Bool_type = true_type; \
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ret result_type; \
using _Class_type = _Arg0; \
using _Guide_type = enable_if<false>; \
};
#undef _IS_MEMFUNPTR_ELLIPSIS
// STRUCT TEMPLATE is_void
template
<
class
_Ty
>
struct
is_void
:
false_type
{
// determine whether _Ty is void
};
#define _IS_VOID(CV_OPT) \
template<> \
struct is_void<CV_OPT void> \
: true_type \
{ /* determine whether _Ty is void */ \
};
#undef _IS_VOID
template
<
class
_Ty
>
// ALIAS TEMPLATE void_t
template
<
class
...
_Types
>
using
void_t
=
void
;
// Type modifiers
// STRUCT TEMPLATE add_const
template
<
class
_Ty
>
struct
add_const
{
// add top level const qualifier
using
type
=
const
_Ty
; };
template
<
class
_Ty
>
using
add_const_t
=
const
_Ty
;
// STRUCT TEMPLATE add_volatile
template
<
class
_Ty
>
struct
add_volatile
{
// add top level volatile qualifier
using
type
=
volatile
_Ty
; };
template
<
class
_Ty
>
using
add_volatile_t
=
volatile
_Ty
;
// STRUCT TEMPLATE add_cv
template
<
class
_Ty
>
struct
add_cv
{
// add top level const and volatile qualifiers
using
type
=
const
volatile
_Ty
; };
template
<
class
_Ty
>
using
add_cv_t
=
const
volatile
_Ty
;
// STRUCT TEMPLATE _Add_reference
template
<
class
_Ty
,
class
=
void
>
struct
_Add_reference
{
// add reference
using
_Lvalue
=
_Ty
;
using
_Rvalue
=
_Ty
; };
template
<
class
_Ty
>
struct
_Add_reference
<
_Ty
,
void_t
<
_Ty
&>> {
// add reference
using
_Lvalue
=
_Ty
&;
using
_Rvalue
=
_Ty
&&; };
// STRUCT TEMPLATE add_lvalue_reference
template
<
class
_Ty
>
struct
add_lvalue_reference
{
// add lvalue reference
using
type
=
typename
_Add_reference
<
_Ty
>::
_Lvalue
; };
template
<
class
_Ty
>
using
add_lvalue_reference_t
=
typename
_Add_reference
<
_Ty
>::
_Lvalue
;
// STRUCT TEMPLATE add_rvalue_reference
template
<
class
_Ty
>
struct
add_rvalue_reference
{
// add rvalue reference
using
type
=
typename
_Add_reference
<
_Ty
>::
_Rvalue
; };
template
<
class
_Ty
>
using
add_rvalue_reference_t
=
typename
_Add_reference
<
_Ty
>::
_Rvalue
;
// FUNCTION TEMPLATE declval
template
<
class
_Ty
>
add_rvalue_reference_t
<
_Ty
>
declval
()
noexcept
;
// STRUCT TEMPLATE remove_extent
template
<
class
_Ty
>
struct
remove_extent
{
// remove array extent
using
type
=
_Ty
; };
template
<
class
_Ty
,
size_t
_Ix
>
struct
remove_extent
<
_Ty
[
_Ix
]> {
// remove array extent
using
type
=
_Ty
; };
template
<
class
_Ty
>
struct
remove_extent
<
_Ty
[]> {
// remove array extent
using
type
=
_Ty
; };
template
<
class
_Ty
>
using
remove_extent_t
=
typename
remove_extent
<
_Ty
>::
type
;
// STRUCT TEMPLATE remove_all_extents
template
<
class
_Ty
>
struct
remove_all_extents
{
// remove all array extents
using
type
=
_Ty
; };
template
<
class
_Ty
,
size_t
_Ix
>
struct
remove_all_extents
<
_Ty
[
_Ix
]> {
// remove all array extents
using
type
=
typename
remove_all_extents
<
_Ty
>::
type
; };
template
<
class
_Ty
>
struct
remove_all_extents
<
_Ty
[]> {
// remove all array extents
using
type
=
typename
remove_all_extents
<
_Ty
>::
type
; };
template
<
class
_Ty
>
using
remove_all_extents_t
=
typename
remove_all_extents
<
_Ty
>::
type
;
// STRUCT TEMPLATE remove_pointer
template
<
class
_Ty
>
struct
remove_pointer
{
// remove pointer
using
type
=
_Ty
; };
#define _REMOVE_POINTER(CV_OPT) \
template<class _Ty> \
struct remove_pointer<_Ty * CV_OPT> \
{ /* remove pointer */ \
using type = _Ty; \
};
#undef _REMOVE_POINTER
template
<
class
_Ty
>
using
remove_pointer_t
=
typename
remove_pointer
<
_Ty
>::
type
;
// STRUCT TEMPLATE add_pointer
template
<
class
_Ty
,
class
=
void
>
struct
_Add_pointer
{
// add pointer
using
type
=
_Ty
; };
template
<
class
_Ty
>
struct
_Add_pointer
<
_Ty
,
void_t
<
remove_reference_t
<
_Ty
> *>> {
// add pointer
using
type
=
remove_reference_t
<
_Ty
> *; };
template
<
class
_Ty
>
struct
add_pointer
{
// add pointer
using
type
=
typename
_Add_pointer
<
_Ty
>::
type
; };
template
<
class
_Ty
>
using
add_pointer_t
=
typename
_Add_pointer
<
_Ty
>::
type
;
// TYPE PREDICATES
// STRUCT TEMPLATE is_array
template
<
class
_Ty
>
struct
is_array
:
false_type
{
// determine whether _Ty is an array
};
template
<
class
_Ty
,
size_t
_Nx
>
struct
is_array
<
_Ty
[
_Nx
]> :
true_type
{
// determine whether _Ty is an array
};
template
<
class
_Ty
>
struct
is_array
<
_Ty
[]> :
true_type
{
// determine whether _Ty is an array
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_lvalue_reference
template
<
class
_Ty
>
struct
is_lvalue_reference
:
false_type
{
// determine whether _Ty is an lvalue reference
};
template
<
class
_Ty
>
struct
is_lvalue_reference
<
_Ty
&> :
true_type
{
// determine whether _Ty is an lvalue reference
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_rvalue_reference
template
<
class
_Ty
>
struct
is_rvalue_reference
:
false_type
{
// determine whether _Ty is an rvalue reference
};
template
<
class
_Ty
>
struct
is_rvalue_reference
<
_Ty
&&> :
true_type
{
// determine whether _Ty is an rvalue reference
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_reference
template
<
class
_Ty
>
struct
is_reference
:
false_type
{
// determine whether _Ty is a reference
};
template
<
class
_Ty
>
struct
is_reference
<
_Ty
&> :
true_type
{
// determine whether _Ty is a reference
};
template
<
class
_Ty
>
struct
is_reference
<
_Ty
&&> :
true_type
{
// determine whether _Ty is a reference
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_member_object_pointer
template
<
class
_Ty
,
bool
_Pmf
=
_Is_memfunptr
<
_Ty
>::
_Bool_type
::
value
>
struct
_Is_member_object_pointer
:
false_type
{
// determine whether _Ty is a pointer to member object
};
template
<
class
_Ty1
,
class
_Ty2
>
struct
_Is_member_object_pointer
<
_Ty1
_Ty2
::*,
false
> :
true_type
{
// determine whether _Ty is a pointer to member object
using
_Class_type
=
_Ty2
; };
template
<
class
_Ty
>
struct
is_member_object_pointer
:
_Is_member_object_pointer
<
remove_cv_t
<
_Ty
>>::
type
{
// determine whether _Ty is a pointer to member object
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_member_function_pointer
template
<
class
_Ty
>
struct
is_member_function_pointer
:
_Is_memfunptr
<
remove_cv_t
<
_Ty
>>::
_Bool_type
{
// determine whether _Ty is a pointer to member function
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_pointer
template
<
class
_Ty
>
struct
is_pointer
:
false_type
{
// determine whether _Ty is a pointer
};
template
<
class
_Ty
>
struct
is_pointer
<
_Ty
*> :
true_type
{
// determine whether _Ty is a pointer
};
template
<
class
_Ty
>
struct
is_pointer
<
_Ty
*
const
> :
true_type
{
// determine whether _Ty is a pointer
};
template
<
class
_Ty
>
struct
is_pointer
<
_Ty
*
volatile
> :
true_type
{
// determine whether _Ty is a pointer
};
template
<
class
_Ty
>
struct
is_pointer
<
_Ty
*
const
volatile
> :
true_type
{
// determine whether _Ty is a pointer
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_null_pointer
template
<
class
_Ty
>
struct
is_null_pointer
:
bool_constant
<
is_same_v
<
remove_cv_t
<
_Ty
>,
nullptr_t
>> {
// determine whether _Ty is nullptr_t
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_union
template
<
class
_Ty
>
struct
is_union
:
bool_constant
<__is_union(
_Ty
)> {
// determine whether _Ty is a union
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_class
template
<
class
_Ty
>
struct
is_class
:
bool_constant
<__is_class(
_Ty
)> {
// determine whether _Ty is a class
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_fundamental
template
<
class
_Ty
>
struct
is_fundamental
:
bool_constant
<
is_arithmetic_v
<
_Ty
> ||
is_void_v
<
_Ty
> ||
is_null_pointer_v
<
_Ty
>> {
// determine whether _Ty is a fundamental type
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_object
template
<
class
_Ty
>
struct
is_object
:
bool_constant
<!
is_function_v
<
_Ty
> && !
is_reference_v
<
_Ty
> && !
is_void_v
<
_Ty
>> {
// determine whether _Ty is an object type
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_convertible
template
<
class
_From
,
class
_To
>
struct
is_convertible
:
bool_constant
<__is_convertible_to(
_From
,
_To
)> {
// determine whether _From is convertible to _To
};
template
<
class
_From
,
class
_To
>
// STRUCT TEMPLATE is_enum
template
<
class
_Ty
>
struct
is_enum
:
bool_constant
<__is_enum(
_Ty
)> {
// determine whether _Ty is an enumerated type
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_compound
template
<
class
_Ty
>
struct
is_compound
:
bool_constant
<!
is_fundamental_v
<
_Ty
>> {
// determine whether _Ty is a compound type
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_member_pointer
template
<
class
_Ty
>
struct
is_member_pointer
:
bool_constant
<
is_member_object_pointer_v
<
_Ty
> ||
is_member_function_pointer_v
<
_Ty
>> {
// determine whether _Ty is a pointer to member
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_scalar
template
<
class
_Ty
>
struct
is_scalar
:
bool_constant
<
is_arithmetic_v
<
_Ty
> ||
is_enum_v
<
_Ty
> ||
is_pointer_v
<
_Ty
> ||
is_member_pointer_v
<
_Ty
> ||
is_null_pointer_v
<
_Ty
>> {
// determine whether _Ty is a scalar type
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_const
template
<
class
_Ty
>
struct
is_const
:
false_type
{
// determine whether _Ty is const qualified
};
template
<
class
_Ty
>
struct
is_const
<
const
_Ty
> :
true_type
{
// determine whether _Ty is const qualified
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_volatile
template
<
class
_Ty
>
struct
is_volatile
:
false_type
{
// determine whether _Ty is volatile qualified
};
template
<
class
_Ty
>
struct
is_volatile
<
volatile
_Ty
> :
true_type
{
// determine whether _Ty is volatile qualified
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_pod
template
<
class
_Ty
>
struct
is_pod
:
bool_constant
<__is_pod(
_Ty
)> {
// determine whether _Ty is a POD type
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_empty
template
<
class
_Ty
>
struct
is_empty
:
bool_constant
<__is_empty(
_Ty
)> {
// determine whether _Ty is an empty class
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_polymorphic
template
<
class
_Ty
>
struct
is_polymorphic
:
bool_constant
<__is_polymorphic(
_Ty
)> {
// determine whether _Ty is a polymorphic type
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_abstract
template
<
class
_Ty
>
struct
is_abstract
:
bool_constant
<__is_abstract(
_Ty
)> {
// determine whether _Ty is an abstract class
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_final
template
<
class
_Ty
>
struct
is_final
:
bool_constant
<__is_final(
_Ty
)> {
// determine whether _Ty is a final class
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_standard_layout
template
<
class
_Ty
>
struct
is_standard_layout
:
bool_constant
<__is_standard_layout(
_Ty
)> {
// determine whether _Ty is standard layout
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_literal_type
template
<
class
_Ty
> :
bool_constant
<__is_literal_type(
_Ty
)> {
// determine whether _Ty is a literal type
}; #pragma warning(push)
template
<
class
_Ty
> #pragma warning(pop)
// STRUCT TEMPLATE is_trivial
template
<
class
_Ty
>
struct
is_trivial
:
bool_constant
<__is_trivial(
_Ty
)> {
// determine whether _Ty is trivial
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_trivially_copyable
template
<
class
_Ty
>
struct
is_trivially_copyable
:
bool_constant
<__is_trivially_copyable(
_Ty
)> {
// determine whether _Ty is trivially copyable
};
template
<
class
_Ty
>
// STRUCT TEMPLATE has_virtual_destructor
template
<
class
_Ty
>
struct
has_virtual_destructor
:
bool_constant
<__has_virtual_destructor(
_Ty
)> {
// determine whether _Ty has a virtual destructor
};
template
<
class
_Ty
>
#if _HAS_CXX17
// STRUCT TEMPLATE has_unique_object_representations
template<class _Ty>
struct has_unique_object_representations
: bool_constant<__has_unique_object_representations(_Ty)>
{ // determine whether _Ty has unique object representations
};
template<class _Ty>
_INLINE_VAR constexpr bool has_unique_object_representations_v = __has_unique_object_representations(_Ty);
// STRUCT TEMPLATE is_aggregate
template<class _Ty>
struct is_aggregate
: bool_constant<__is_aggregate(_Ty)>
{ // determine whether _Ty is an aggregate
};
template<class _Ty>
_INLINE_VAR constexpr bool is_aggregate_v = __is_aggregate(_Ty); #endif /* _HAS_CXX17 */
// CONSTRUCTIBLE/ASSIGNABLE TRAITS
// STRUCT TEMPLATE is_constructible
template
<
class
_Ty
,
class
...
_Args
>
struct
is_constructible
:
bool_constant
<__is_constructible(
_Ty
,
_Args
...)> {
// determine whether _Ty(_Args...) is constructible
};
template
<
class
_Ty
,
class
...
_Args
>
// STRUCT TEMPLATE is_copy_constructible
template
<
class
_Ty
>
struct
is_copy_constructible
:
bool_constant
<__is_constructible(
_Ty
,
add_lvalue_reference_t
<
const
_Ty
>)> {
// determine whether _Ty has a copy constructor
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_default_constructible
template
<
class
_Ty
>
struct
is_default_constructible
:
bool_constant
<__is_constructible(
_Ty
)> {
// determine whether _Ty has a default constructor
};
template
<
class
_Ty
>
// STRUCT TEMPLATE _Is_implicitly_default_constructible
template
<
class
_Ty
,
class
=
void
>
struct
_Is_implicitly_default_constructible
:
false_type
{
// determine whether _Ty is implicitly default constructible
};
template
<
class
_Ty
>
void
_Implicitly_default_construct
(
const
_Ty
&);
template
<
class
_Ty
>
struct
_Is_implicitly_default_constructible
<
_Ty
,
void_t
<
decltype
(
_Implicitly_default_construct
<
_Ty
>({}))>> :
true_type
{
// determine whether _Ty is implicitly default constructible
};
// STRUCT TEMPLATE is_move_constructible
template
<
class
_Ty
>
struct
is_move_constructible
:
bool_constant
<__is_constructible(
_Ty
,
_Ty
)> {
// determine whether _Ty has a move constructor
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_assignable
template
<
class
_To
,
class
_From
>
struct
is_assignable
:
bool_constant
<__is_assignable(
_To
,
_From
)> {
// determine whether _From can be assigned to _To
};
template
<
class
_To
,
class
_From
>
// STRUCT TEMPLATE is_copy_assignable
template
<
class
_Ty
>
struct
is_copy_assignable
:
bool_constant
<__is_assignable(
add_lvalue_reference_t
<
_Ty
>,
add_lvalue_reference_t
<
const
_Ty
>)> {
// determine whether _Ty has a copy assignment operator
};
template
<
class
_Ty
> __is_assignable(
add_lvalue_reference_t
<
_Ty
>,
add_lvalue_reference_t
<
const
_Ty
>);
// STRUCT TEMPLATE is_move_assignable
template
<
class
_Ty
>
struct
is_move_assignable
:
bool_constant
<__is_assignable(
add_lvalue_reference_t
<
_Ty
>,
_Ty
)> {
// determine whether _Ty has a move assignment operator
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_destructible
template
<
class
_Ty
>
struct
is_destructible
:
bool_constant
<__is_destructible(
_Ty
)> {
// determine whether _Ty has a destructor
};
template
<
class
_Ty
>
// TRIVIAL TRAITS
// STRUCT TEMPLATE is_trivially_constructible
template
<
class
_Ty
,
class
...
_Args
>
struct
is_trivially_constructible
:
bool_constant
<__is_trivially_constructible(
_Ty
,
_Args
...)> {
// determine whether _Ty(_Args...) is trivially constructible
};
template
<
class
_Ty
,
class
...
_Args
>
// STRUCT TEMPLATE is_trivially_copy_constructible
template
<
class
_Ty
>
struct
is_trivially_copy_constructible
:
bool_constant
<__is_trivially_constructible(
_Ty
,
add_lvalue_reference_t
<
const
_Ty
>)> {
// determine whether _Ty has a trivial copy constructor
};
template
<
class
_Ty
> __is_trivially_constructible(
_Ty
,
add_lvalue_reference_t
<
const
_Ty
>);
// STRUCT TEMPLATE is_trivially_default_constructible
template
<
class
_Ty
>
struct
is_trivially_default_constructible
:
bool_constant
<__is_trivially_constructible(
_Ty
)> {
// determine whether _Ty has a trivial default constructor
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_trivially_move_constructible
template
<
class
_Ty
>
struct
is_trivially_move_constructible
:
bool_constant
<__is_trivially_constructible(
_Ty
,
_Ty
)> {
// determine whether _Ty has a trivial move constructor
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_trivially_assignable
template
<
class
_To
,
class
_From
>
struct
is_trivially_assignable
:
bool_constant
<__is_trivially_assignable(
_To
,
_From
)> {
// determine whether _From can be assigned to _To, trivially
};
template
<
class
_To
,
class
_From
>
// STRUCT TEMPLATE is_trivially_copy_assignable
template
<
class
_Ty
>
struct
is_trivially_copy_assignable
:
bool_constant
<__is_trivially_assignable(
add_lvalue_reference_t
<
_Ty
>,
add_lvalue_reference_t
<
const
_Ty
>)> {
// determine whether _Ty has a trivial copy assignment operator
};
template
<
class
_Ty
> __is_trivially_assignable(
add_lvalue_reference_t
<
_Ty
>,
add_lvalue_reference_t
<
const
_Ty
>);
// STRUCT TEMPLATE is_trivially_move_assignable
template
<
class
_Ty
>
struct
is_trivially_move_assignable
:
bool_constant
<__is_trivially_assignable(
add_lvalue_reference_t
<
_Ty
>,
_Ty
)> {
// determine whether _Ty has a trivial move assignment operator
};
template
<
class
_Ty
> __is_trivially_assignable(
add_lvalue_reference_t
<
_Ty
>,
_Ty
);
// STRUCT TEMPLATE is_trivially_destructible
template
<
class
_Ty
>
struct
is_trivially_destructible
:
bool_constant
<__is_trivially_destructible(
_Ty
)> {
// determine whether _Ty has a trivial destructor
};
template
<
class
_Ty
>
// NOTHROW TRAITS
// STRUCT TEMPLATE is_nothrow_constructible
template
<
class
_Ty
,
class
...
_Args
>
struct
is_nothrow_constructible
:
bool_constant
<__is_nothrow_constructible(
_Ty
,
_Args
...)> {
// determine whether _Ty(_Args...) is nothrow constructible
};
template
<
class
_Ty
,
class
...
_Args
>
// STRUCT TEMPLATE is_nothrow_copy_constructible
template
<
class
_Ty
>
struct
is_nothrow_copy_constructible
:
bool_constant
<__is_nothrow_constructible(
_Ty
,
add_lvalue_reference_t
<
const
_Ty
>)> {
// determine whether _Ty has a nothrow copy constructor
};
template
<
class
_Ty
> __is_nothrow_constructible(
_Ty
,
add_lvalue_reference_t
<
const
_Ty
>);
// STRUCT TEMPLATE is_nothrow_default_constructible
template
<
class
_Ty
>
struct
is_nothrow_default_constructible
:
bool_constant
<__is_nothrow_constructible(
_Ty
)> {
// determine whether _Ty has a nothrow default constructor
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_nothrow_move_constructible
template
<
class
_Ty
>
struct
is_nothrow_move_constructible
:
bool_constant
<__is_nothrow_constructible(
_Ty
,
_Ty
)> {
// determine whether _Ty has a nothrow move constructor
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_nothrow_assignable
template
<
class
_To
,
class
_From
>
struct
is_nothrow_assignable
:
bool_constant
<__is_nothrow_assignable(
_To
,
_From
)> {
// determine whether _From can be assigned to _To, nothrow
};
template
<
class
_To
,
class
_From
>
// STRUCT TEMPLATE is_nothrow_copy_assignable
template
<
class
_Ty
>
struct
is_nothrow_copy_assignable
:
bool_constant
<__is_nothrow_assignable(
add_lvalue_reference_t
<
_Ty
>,
add_lvalue_reference_t
<
const
_Ty
>)> {
// determine whether _Ty has a nothrow copy assignment operator
};
template
<
class
_Ty
> __is_nothrow_assignable(
add_lvalue_reference_t
<
_Ty
>,
add_lvalue_reference_t
<
const
_Ty
>);
// STRUCT TEMPLATE is_nothrow_move_assignable
template
<
class
_Ty
>
struct
is_nothrow_move_assignable
:
bool_constant
<__is_nothrow_assignable(
add_lvalue_reference_t
<
_Ty
>,
_Ty
)> {
// determine whether _Ty has a nothrow move assignment operator
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_nothrow_destructible
template
<
class
_Ty
>
struct
is_nothrow_destructible
:
bool_constant
<__is_nothrow_destructible(
_Ty
)> {
// determine whether _Ty has a nothrow destructor
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_signed
#pragma warning(push)
template
<
class
_Ty
,
bool
=
is_integral_v
<
_Ty
>>
struct
_Sign_base
{
// determine whether integral _Ty is a signed or unsigned type
using
_Uty
=
remove_cv_t
<
_Ty
>;
using
_Signed
=
bool_constant
<
_Uty
(-
1
) <
_Uty
(
0
)>;
using
_Unsigned
=
bool_constant
<
_Uty
(
0
) <
_Uty
(-
1
)>; }; #pragma warning(pop)
template
<
class
_Ty
>
struct
_Sign_base
<
_Ty
,
false
> {
// floating-point _Ty is signed
// non-arithmetic _Ty is neither signed nor unsigned
using
_Signed
=
typename
is_floating_point
<
_Ty
>::
type
;
using
_Unsigned
=
false_type
; };
template
<
class
_Ty
>
struct
is_signed
:
_Sign_base
<
_Ty
>::
_Signed
{
// determine whether _Ty is a signed type
};
template
<
class
_Ty
>
// STRUCT TEMPLATE is_unsigned
template
<
class
_Ty
>
struct
is_unsigned
:
_Sign_base
<
_Ty
>::
_Unsigned
{
// determine whether _Ty is an unsigned type
};
template
<
class
_Ty
>
// ALIAS TEMPLATE _Is_nonbool_integral
template
<
class
_Ty
>
using
_Is_nonbool_integral
=
bool_constant
<
is_integral_v
<
_Ty
> && !
is_same_v
<
remove_cv_t
<
_Ty
>,
bool
>>;
// STRUCT TEMPLATE _Change_sign
template
<
class
_Ty
>
struct
_Change_sign
{
// signed/unsigned partners to _Ty
static_assert
(
_Is_nonbool_integral
<
_Ty
>::
value
||
is_enum_v
<
_Ty
>,
"make_signed<T>/make_unsigned<T> require that T shall be a (possibly "
"cv-qualified) integral type or enumeration but not a bool type."
);
using
_Signed
=
conditional_t
<
_Is_any_of_v
<
_Ty
,
long
,
unsigned
long
>,
long
,
conditional_t
<
sizeof
(
_Ty
)
=
=
1
,
signed
char
,
conditional_t
<
sizeof
(
_Ty
)
=
=
2
,
short
,
conditional_t
<
sizeof
(
_Ty
)
=
=
4
,
int
,
long
long
>>>>;
using
_Unsigned
=
conditional_t
<
_Is_any_of_v
<
_Ty
,
long
,
unsigned
long
>,
unsigned
long
,
conditional_t
<
sizeof
(
_Ty
)
=
=
1
,
unsigned
char
,
conditional_t
<
sizeof
(
_Ty
)
=
=
2
,
unsigned
short
,
conditional_t
<
sizeof
(
_Ty
)
=
=
4
,
unsigned
int
,
unsigned
long
long
>>>>; };
template
<
class
_Ty
>
struct
_Change_sign
<
const
_Ty
> {
// signed/unsigned partners to _Ty
using
_Signed
=
const
typename
_Change_sign
<
_Ty
>::
_Signed
;
using
_Unsigned
=
const
typename
_Change_sign
<
_Ty
>::
_Unsigned
; };
template
<
class
_Ty
>
struct
_Change_sign
<
volatile
_Ty
> {
// signed/unsigned partners to _Ty
using
_Signed
=
volatile
typename
_Change_sign
<
_Ty
>::
_Signed
;
using
_Unsigned
=
volatile
typename
_Change_sign
<
_Ty
>::
_Unsigned
; };
template
<
class
_Ty
>
struct
_Change_sign
<
const
volatile
_Ty
> {
// signed/unsigned partners to _Ty
using
_Signed
=
const
volatile
typename
_Change_sign
<
_Ty
>::
_Signed
;
using
_Unsigned
=
const
volatile
typename
_Change_sign
<
_Ty
>::
_Unsigned
; };
// STRUCT TEMPLATE make_signed
template
<
class
_Ty
>
struct
make_signed
{
// signed partner to _Ty
using
type
=
typename
_Change_sign
<
_Ty
>::
_Signed
; };
template
<
class
_Ty
>
using
make_signed_t
=
typename
make_signed
<
_Ty
>::
type
;
// STRUCT TEMPLATE make_unsigned
template
<
class
_Ty
>
struct
make_unsigned
{
// unsigned partner to _Ty
using
type
=
typename
_Change_sign
<
_Ty
>::
_Unsigned
; };
template
<
class
_Ty
>
using
make_unsigned_t
=
typename
make_unsigned
<
_Ty
>::
type
;
// FUNCTION TEMPLATE _Unsigned_value
template
<
class
_Rep
>
constexpr
make_unsigned_t
<
_Rep
>
_Unsigned_value
(
_Rep
_Val
) {
// makes _Val unsigned
return
(
static_cast
<
make_unsigned_t
<
_Rep
>>(
_Val
)); }
// STRUCT TEMPLATE alignment_of
template
<
class
_Ty
>
struct
alignment_of
:
integral_constant
<
size_t
, alignof(
_Ty
)> {
// determine alignment of _Ty
};
template
<
class
_Ty
>
// STRUCT TEMPLATE aligned_storage
#define _FITS(_Ty) _Align <= alignof(_Ty)
#define _NEXT_ALIGN(_Ty) \
using type = typename _Aligned<_Len, _Align, _Ty, _FITS(_Ty)>::type
template
<
class
_Ty
,
size_t
_Len
>
union
_Align_type
{
// union with size _Len bytes and alignment of _Ty
_Ty
_Val
;
char
_Pad
[
_Len
]; };
template
<
size_t
_Len
,
size_t
_Align
,
class
_Ty
,
bool
_Ok
>
struct
_Aligned
;
template
<
size_t
_Len
,
size_t
_Align
,
class
_Ty
>
struct
_Aligned
<
_Len
,
_Align
,
_Ty
,
true
> {
// define type with size _Len and alignment _Ty
using
type
=
_Align_type
<
_Ty
,
_Len
>; };
template
<
size_t
_Len
,
size_t
_Align
>
struct
_Aligned
<
_Len
,
_Align
,
double
,
false
> {
// define type with size _Len and alignment _Ty
#ifdef _ENABLE_EXTENDED_ALIGNED_STORAGE
struct type
{
alignas(_Align) char _Space[_Len];
};
#else /* ^^^ _ENABLE_EXTENDED_ALIGNED_STORAGE / !_ENABLE_EXTENDED_ALIGNED_STORAGE vvv */
#ifndef _DISABLE_EXTENDED_ALIGNED_STORAGE
static_assert
(
_Always_false
<
_Aligned
>,
"You've instantiated std::aligned_storage<Len, Align> with an extended alignment (in other "
"words, Align > alignof(max_align_t)). Before VS 2017 15.8, the member type would "
"non-conformingly have an alignment of only alignof(max_align_t). VS 2017 15.8 was fixed to "
"handle this correctly, but the fix inherently changes layout and breaks binary compatibility "
"(*only* for uses of aligned_storage with extended alignments). "
"Please define either "
"(1) _ENABLE_EXTENDED_ALIGNED_STORAGE to acknowledge that you understand this message and "
"that you actually want a type with an extended alignment, or "
"(2) _DISABLE_EXTENDED_ALIGNED_STORAGE to silence this message and get the old non-conformant "
"behavior."
);
#endif /* !_DISABLE_EXTENDED_ALIGNED_STORAGE */
using
type
=
_Align_type
<
max_align_t
,
_Len
>;
#endif /* _ENABLE_EXTENDED_ALIGNED_STORAGE */
};
template
<
size_t
_Len
,
size_t
_Align
>
struct
_Aligned
<
_Len
,
_Align
,
int
,
false
> {
// define type with size _Len and alignment _Ty
};
template
<
size_t
_Len
,
size_t
_Align
>
struct
_Aligned
<
_Len
,
_Align
,
short
,
false
> {
// define type with size _Len and alignment _Ty
};
template
<
size_t
_Len
,
size_t
_Align
>
struct
_Aligned
<
_Len
,
_Align
,
char
,
false
> {
// define type with size _Len and alignment _Ty
};
template
<
size_t
_Len
,
size_t
_Align
= alignof(
max_align_t
)>
struct
aligned_storage
{
// define type with size _Len and alignment _Align
};
#undef _FITS
#undef _NEXT_ALIGN
template
<
size_t
_Len
,
size_t
_Align
= alignof(
max_align_t
)>
using
aligned_storage_t
=
typename
aligned_storage
<
_Len
,
_Align
>::
type
;
// STRUCT TEMPLATE aligned_union
template
<
size_t
...
_Vals
>
struct
_Maximum
;
template
<>
struct
_Maximum
<> :
integral_constant
<
size_t
,
0
> {
// maximum of nothing is 0
};
template
<
size_t
_Val
>
struct
_Maximum
<
_Val
> :
integral_constant
<
size_t
,
_Val
> {
// maximum of _Val is _Val
};
template
<
size_t
_First
,
size_t
_Second
,
size_t
...
_Rest
>
struct
_Maximum
<
_First
,
_Second
,
_Rest
...> :
_Maximum
<(
_First
<
_Second
?
_Second
:
_First
),
_Rest
...>::
type
{
// find maximum value in _First, _Second, _Rest...
};
template
<
size_t
_Len
,
class
...
_Types
>
struct
aligned_union
{
// define type with size at least _Len, for storing anything in _Types
static
constexpr
size_t
_Max_len
=
_Maximum
<
_Len
,
sizeof
(
_Types
)...>::
value
;
// NOT sizeof...(_Types)
static
constexpr
size_t
alignment_value
=
_Maximum
<alignof(
_Types
)...>::
value
;
using
type
=
aligned_storage_t
<
_Max_len
,
alignment_value
>; };
template
<
size_t
_Len
,
class
...
_Types
>
using
aligned_union_t
=
typename
aligned_union
<
_Len
,
_Types
...>::
type
;
// STRUCT TEMPLATE underlying_type
template
<
class
_Ty
>
struct
underlying_type
{
// determine type underlying type for enum
using
type
= __underlying_type(
_Ty
); };
template
<
class
_Ty
>
using
underlying_type_t
=
typename
underlying_type
<
_Ty
>::
type
;
// STRUCT TEMPLATE rank
template
<
class
_Ty
>
struct
rank
:
integral_constant
<
size_t
,
0
> {
// determine number of dimensions of array _Ty
};
template
<
class
_Ty
,
size_t
_Ix
>
struct
rank
<
_Ty
[
_Ix
]> :
integral_constant
<
size_t
,
rank
<
_Ty
>::
value
+
1
> {
// determine number of dimensions of array _Ty
};
template
<
class
_Ty
>
struct
rank
<
_Ty
[]> :
integral_constant
<
size_t
,
rank
<
_Ty
>::
value
+
1
> {
// determine number of dimensions of array _Ty
};
template
<
class
_Ty
>
// STRUCT TEMPLATE extent
template
<
class
_Ty
,
unsigned
int
_Nx
>
struct
_Extent
:
integral_constant
<
size_t
,
0
> {
// determine extent of dimension _Nx of array _Ty
};
template
<
class
_Ty
,
size_t
_Ix
>
struct
_Extent
<
_Ty
[
_Ix
],
0
> :
integral_constant
<
size_t
,
_Ix
> {
// determine extent of dimension _Nx of array _Ty
};
template
<
class
_Ty
,
unsigned
int
_Nx
,
size_t
_Ix
>
struct
_Extent
<
_Ty
[
_Ix
],
_Nx
> :
_Extent
<
_Ty
,
_Nx
-
1
> {
// determine extent of dimension _Nx of array _Ty
};
template
<
class
_Ty
,
unsigned
int
_Nx
>
struct
_Extent
<
_Ty
[],
_Nx
> :
_Extent
<
_Ty
,
_Nx
-
1
> {
// determine extent of dimension _Nx of array _Ty
};
template
<
class
_Ty
,
unsigned
int
_Nx
=
0
>
struct
extent
:
_Extent
<
_Ty
,
_Nx
> {
// determine extent of dimension _Nx of array _Ty
};
template
<
class
_Ty
,
unsigned
int
_Ix
=
0
>
// STRUCT TEMPLATE is_base_of
template
<
class
_Base
,
class
_Derived
>
struct
is_base_of
:
bool_constant
<__is_base_of(
_Base
,
_Derived
)> {
// determine whether _Base is a base of or the same as _Derived
};
template
<
class
_Base
,
class
_Derived
>
// STRUCT TEMPLATE decay
template
<
class
_Ty
>
struct
decay
{
// determines decayed version of _Ty
using
_Ty1
=
remove_reference_t
<
_Ty
>;
using
type
=
conditional_t
<
is_array_v
<
_Ty1
>,
add_pointer_t
<
remove_extent_t
<
_Ty1
>>,
conditional_t
<
is_function_v
<
_Ty1
>,
add_pointer_t
<
_Ty1
>,
remove_cv_t
<
_Ty1
>>>; };
template
<
class
_Ty
>
using
decay_t
=
typename
decay
<
_Ty
>::
type
;
// STRUCT TEMPLATE common_type
template
<
class
_Ty1
,
class
_Ty2
,
class
=
void
>
struct
_Decayed_cond_oper
{ };
template
<
class
_Ty1
,
class
_Ty2
> { };
template
<
class
...
_Ty
>
struct
common_type
;
template
<
class
...
_Ty
>
using
common_type_t
=
typename
common_type
<
_Ty
...>::type;
template
<>
struct
common_type
<> { };
template
<
class
_Ty1
>
struct
common_type
<
_Ty1
> :
common_type
<
_Ty1
,
_Ty1
> { };
template
<
class
_Ty1
,
class
_Ty2
,
class
_Decayed1
=
decay_t
<
_Ty1
>,
class
_Decayed2
=
decay_t
<
_Ty2
>>
struct
_Common_type2
:
common_type
<
_Decayed1
,
_Decayed2
> { };
template
<
class
_Ty1
,
class
_Ty2
>
struct
_Common_type2
<
_Ty1
,
_Ty2
,
_Ty1
,
_Ty2
> :
_Decayed_cond_oper
<
_Ty1
,
_Ty2
> { };
template
<
class
_Ty1
,
class
_Ty2
>
struct
common_type
<
_Ty1
,
_Ty2
> :
_Common_type2
<
_Ty1
,
_Ty2
> { };
template
<
class
_Void
,
class
_Ty1
,
class
_Ty2
,
class
...
_Rest
>
struct
_Common_type3
{ };
template
<
class
_Ty1
,
class
_Ty2
,
class
...
_Rest
>
struct
_Common_type3
<
void_t
<
common_type_t
<
_Ty1
,
_Ty2
>>,
_Ty1
,
_Ty2
,
_Rest
...> :
common_type
<
common_type_t
<
_Ty1
,
_Ty2
>,
_Rest
...> { };
template
<
class
_Ty1
,
class
_Ty2
,
class
...
_Rest
>
struct
common_type
<
_Ty1
,
_Ty2
,
_Rest
...> :
_Common_type3
<
void
,
_Ty1
,
_Ty2
,
_Rest
...> { };
#if _HAS_IDENTITY_STRUCT
// STRUCT TEMPLATE identity
template
<
class
_Ty
> {
// map _Ty to type unchanged
using
type
=
_Ty
;
const
_Ty
&
operator
(
)
(
const
_Ty
&
_Left
)
const
{
// apply identity operator to operand
return
(
_Left
); } };
#endif /* _HAS_IDENTITY_STRUCT */
// STRUCT TEMPLATE _Identity
template
<
class
_Ty
>
struct
_Identity
{
// the identity transformation trait
using
type
=
_Ty
; };
template
<
class
_Ty
>
using
_Identity_t
=
typename
_Identity
<
_Ty
>::
type
;
// TRAIT _Is_specialization: TRUE IFF _Type IS A SPECIALIZATION OF _Template
template
<
class
_Type
,
template
<
class
...>
class
_Template
>
template
<
template
<
class
...>
class
_Template
,
class
...
_Types
>
template
<
class
_Type
,
template
<
class
...>
class
_Template
>
struct
_Is_specialization
:
bool_constant
<
_Is_specialization_v
<
_Type
,
_Template
>> {};
// FUNCTION TEMPLATE forward
template
<
class
_Ty
> {
// forward an lvalue as either an lvalue or an rvalue
return
(
static_cast
<
_Ty
&&>(
_Arg
)); }
template
<
class
_Ty
> {
// forward an rvalue as an rvalue
static_assert
(!
is_lvalue_reference_v
<
_Ty
>,
"bad forward call"
);
return
(
static_cast
<
_Ty
&&>(
_Arg
)); }
// FUNCTION TEMPLATE move
template
<
class
_Ty
>
move
(
_Ty
&&
_Arg
)
noexcept
{
// forward _Arg as movable
return
(
static_cast
<
remove_reference_t
<
_Ty
>&&>(
_Arg
)); }
// FUNCTION TEMPLATE move_if_noexcept
template
<
class
_Ty
>
const
_Ty
&,
_Ty
&&>
move_if_noexcept
(
_Ty
&
_Arg
)
noexcept
{
// forward _Arg as movable, sometimes
}
template
<
class
_Ty
>
class
reference_wrapper
;
#define _CONCATX(x, y) x ## y
#define _CONCAT(x, y) _CONCATX(x, y)
#define _IMPLEMENT_INVOKE(NAME_PREFIX, CONSTEXPR) \
/* FUNCTION TEMPLATE invoke */ \
struct _CONCAT(NAME_PREFIX, _Invoker_pmf_object) \
{ /* INVOKE a pointer to member function on an object */ \
template<class _Decayed, \
class _Ty1, \
class... _Types2> \
static CONSTEXPR auto _Call(_Decayed _Pmf, _Ty1&& _Arg1, _Types2&&... _Args2) \
_NOEXCEPT_COND(_NOEXCEPT_OPER((_STD forward<_Ty1>(_Arg1).*_Pmf)(_STD forward<_Types2>(_Args2)...))) \
-> decltype((_STD forward<_Ty1>(_Arg1).*_Pmf)(_STD forward<_Types2>(_Args2)...)) \
{ /* INVOKE a pointer to member function on an object */ \
return ((_STD forward<_Ty1>(_Arg1).*_Pmf)(_STD forward<_Types2>(_Args2)...)); \
} \
}; \
\
struct _CONCAT(NAME_PREFIX, _Invoker_pmf_refwrap) \
{ /* INVOKE a pointer to member function on a reference_wrapper */ \
template<class _Decayed, \
class _Ty1, \
class... _Types2> \
static CONSTEXPR auto _Call(_Decayed _Pmf, _Ty1&& _Arg1, _Types2&&... _Args2) \
_NOEXCEPT_COND(_NOEXCEPT_OPER((_STD forward<_Ty1>(_Arg1).get().*_Pmf)(_STD forward<_Types2>(_Args2)...))) \
-> decltype((_STD forward<_Ty1>(_Arg1).get().*_Pmf)(_STD forward<_Types2>(_Args2)...)) \
{ /* INVOKE a pointer to member function on a reference_wrapper */ \
return ((_STD forward<_Ty1>(_Arg1).get().*_Pmf)(_STD forward<_Types2>(_Args2)...)); \
} \
}; \
\
struct _CONCAT(NAME_PREFIX, _Invoker_pmf_pointer) \
{ /* INVOKE a pointer to member function on a [smart] pointer */ \
template<class _Decayed, \
class _Ty1, \
class... _Types2> \
static CONSTEXPR auto _Call(_Decayed _Pmf, _Ty1&& _Arg1, _Types2&&... _Args2) \
_NOEXCEPT_COND(_NOEXCEPT_OPER(((*_STD forward<_Ty1>(_Arg1)).*_Pmf)(_STD forward<_Types2>(_Args2)...))) \
-> decltype(((*_STD forward<_Ty1>(_Arg1)).*_Pmf)(_STD forward<_Types2>(_Args2)...)) \
{ /* INVOKE a pointer to member function on a [smart] pointer */ \
return (((*_STD forward<_Ty1>(_Arg1)).*_Pmf)(_STD forward<_Types2>(_Args2)...)); \
} \
}; \
\
struct _CONCAT(NAME_PREFIX, _Invoker_pmd_object) \
{ /* INVOKE a pointer to member data on an object */ \
template<class _Decayed, \
class _Ty1> \
static CONSTEXPR auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) \
_NOEXCEPT_COND(_NOEXCEPT_OPER(_STD forward<_Ty1>(_Arg1).*_Pmd)) \
-> decltype(_STD forward<_Ty1>(_Arg1).*_Pmd) \
{ /* INVOKE a pointer to member data on an object */ \
return (_STD forward<_Ty1>(_Arg1).*_Pmd); \
} \
}; \
\
struct _CONCAT(NAME_PREFIX, _Invoker_pmd_refwrap) \
{ /* INVOKE a pointer to member data on a reference_wrapper */ \
template<class _Decayed, \
class _Ty1> \
static CONSTEXPR auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) \
_NOEXCEPT_COND(_NOEXCEPT_OPER(_STD forward<_Ty1>(_Arg1).get().*_Pmd)) \
-> decltype(_STD forward<_Ty1>(_Arg1).get().*_Pmd) \
{ /* INVOKE a pointer to member data on a reference_wrapper */ \
return (_STD forward<_Ty1>(_Arg1).get().*_Pmd); \
} \
}; \
\
struct _CONCAT(NAME_PREFIX, _Invoker_pmd_pointer) \
{ /* INVOKE a pointer to member data on a [smart] pointer */ \
template<class _Decayed, \
class _Ty1> \
static CONSTEXPR auto _Call(_Decayed _Pmd, _Ty1&& _Arg1) \
_NOEXCEPT_COND(_NOEXCEPT_OPER((*_STD forward<_Ty1>(_Arg1)).*_Pmd)) \
-> decltype((*_STD forward<_Ty1>(_Arg1)).*_Pmd) \
{ /* INVOKE a pointer to member data on a [smart] pointer */ \
return ((*_STD forward<_Ty1>(_Arg1)).*_Pmd); \
} \
}; \
\
struct _CONCAT(NAME_PREFIX, _Invoker_functor) \
{ /* INVOKE a function object */ \
template<class _Callable, \
class... _Types> \
static CONSTEXPR auto _Call(_Callable&& _Obj, _Types&&... _Args) \
_NOEXCEPT_COND(_NOEXCEPT_OPER(_STD forward<_Callable>(_Obj)(_STD forward<_Types>(_Args)...))) \
-> decltype(_STD forward<_Callable>(_Obj)(_STD forward<_Types>(_Args)...)) \
{ /* INVOKE a function object */ \
return (_STD forward<_Callable>(_Obj)(_STD forward<_Types>(_Args)...)); \
} \
}; \
\
template<class _Callable, \
class _Ty1, \
class _Removed_cvref = remove_cv_t<remove_reference_t<_Callable>>, \
bool _Is_pmf = is_member_function_pointer_v<_Removed_cvref>, \
bool _Is_pmd = is_member_object_pointer_v<_Removed_cvref>> \
struct _CONCAT(NAME_PREFIX, _Invoker1); \
\
template<class _Callable, \
class _Ty1, \
class _Removed_cvref> \
struct _CONCAT(NAME_PREFIX, _Invoker1)<_Callable, _Ty1, _Removed_cvref, true, false> \
: conditional_t<is_base_of_v< \
typename _Is_memfunptr<_Removed_cvref>::_Class_type, \
remove_reference_t<_Ty1>>, \
_CONCAT(NAME_PREFIX, _Invoker_pmf_object), \
conditional_t<_Is_specialization_v<remove_cv_t<remove_reference_t<_Ty1>>, reference_wrapper>, \
_CONCAT(NAME_PREFIX, _Invoker_pmf_refwrap), \
_CONCAT(NAME_PREFIX, _Invoker_pmf_pointer) \
>> \
{ /* pointer to member function */ \
}; \
\
template<class _Callable, \
class _Ty1, \
class _Removed_cvref> \
struct _CONCAT(NAME_PREFIX, _Invoker1)<_Callable, _Ty1, _Removed_cvref, false, true> \
: conditional_t<is_base_of_v< \
typename _Is_member_object_pointer<_Removed_cvref>::_Class_type, \
remove_reference_t<_Ty1>>, \
_CONCAT(NAME_PREFIX, _Invoker_pmd_object), \
conditional_t<_Is_specialization_v<remove_cv_t<remove_reference_t<_Ty1>>, reference_wrapper>, \
_CONCAT(NAME_PREFIX, _Invoker_pmd_refwrap), \
_CONCAT(NAME_PREFIX, _Invoker_pmd_pointer) \
>> \
{ /* pointer to member data */ \
}; \
\
template<class _Callable, \
class _Ty1, \
class _Removed_cvref> \
struct _CONCAT(NAME_PREFIX, _Invoker1)<_Callable, _Ty1, _Removed_cvref, false, false> \
: _CONCAT(NAME_PREFIX, _Invoker_functor) \
{ /* function object */ \
}; \
\
template<class _Callable, \
class... _Types> \
struct _CONCAT(NAME_PREFIX, _Invoker); \
\
template<class _Callable> \
struct _CONCAT(NAME_PREFIX, _Invoker)<_Callable> \
: _CONCAT(NAME_PREFIX, _Invoker_functor) \
{ /* zero arguments */ \
}; \
\
template<class _Callable, \
class _Ty1, \
class... _Types2> \
struct _CONCAT(NAME_PREFIX, _Invoker)<_Callable, _Ty1, _Types2...> \
: _CONCAT(NAME_PREFIX, _Invoker1)<_Callable, _Ty1> \
{ /* one or more arguments */ \
}; \
\
template<class _Callable, \
class... _Types> \
CONSTEXPR auto _CONCAT(NAME_PREFIX, invoke)(_Callable&& _Obj, _Types&&... _Args) \
_NOEXCEPT_COND(_NOEXCEPT_OPER(_CONCAT(NAME_PREFIX, _Invoker)<_Callable, _Types...>::_Call( \
_STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...))) \
-> decltype(_CONCAT(NAME_PREFIX, _Invoker)<_Callable, _Types...>::_Call( \
_STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...)) \
{ /* INVOKE a callable object */ \
return (_CONCAT(NAME_PREFIX, _Invoker)<_Callable, _Types...>::_Call( \
_STD forward<_Callable>(_Obj), _STD forward<_Types>(_Args)...)); \
}
template
<
class
_Callable
,
class
...
_Types
>
struct
_Invoker
;
template
<
class
_Callable
,
class
...
_Types
>
inline
auto
invoke
(
_Callable
&&
_Obj
,
_Types
&&...
_Args
) ->
decltype
(
_Invoker
<
_Callable
,
_Types
...>::_Call(
struct
_Unforced
{
// tag to distinguish bind() from bind<R>()
};
// TYPE TRAITS FOR invoke()
template
<
class
_To
>
void
_Implicitly_convert_to
(
_To
)
noexcept
;
template
<
class
_From
,
class
_To
,
bool
=
is_convertible_v
<
_From
,
_To
>>
struct
_Is_nothrow_convertible
{
// determine whether _From is nothrow-convertible to _To
};
template
<
class
_From
,
class
_To
>
struct
_Is_nothrow_convertible
<
_From
,
_To
,
false
> :
false_type
{
// determine whether _From is nothrow-convertible to _To
};
template
<
class
_Void
,
class
...
_Types
>
struct
_Invoke_traits
{
// selected when _Callable isn't callable with _Args
using
_Is_invocable
=
false_type
;
using
_Is_nothrow_invocable
=
false_type
;
template
<
class
_Rx
>
using
_Is_invocable_r
=
false_type
;
template
<
class
_Rx
>
using
_Is_nothrow_invocable_r
=
false_type
; };
template
<
class
...
_Types
> {
// selected when _Callable is callable with _Args
using
_Is_invocable
=
true_type
;
template
<
class
_Rx
>
using
_Is_invocable_r
=
bool_constant
<
disjunction_v
<
is_void
<
_Rx
>,
is_convertible
<
type
,
_Rx
>>>;
template
<
class
_Rx
>
using
_Is_nothrow_invocable_r
=
bool_constant
<
conjunction_v
<
_Is_nothrow_invocable
,
disjunction
<
is_void
<
_Rx
>,
_Is_nothrow_convertible
<
type
,
_Rx
>>>>; };
// STRUCT TEMPLATE result_of
template
<
class
_Fty
> {
// explain usage
static_assert
(
_Always_false
<
_Fty
>,
"result_of<CallableType> is invalid; use "
"result_of<CallableType(zero or more argument types)> instead."
); };
#define _RESULT_OF(CALL_OPT, X1, X2, X3) \
template<class _Callable, \
class... _Args> \
struct _CXX17_DEPRECATE_RESULT_OF result_of<_Callable CALL_OPT (_Args...)> \
: _Invoke_traits<void, _Callable, _Args...> \
{ /* template to determine result of call operation */ \
};
#undef _RESULT_OF
#pragma warning(push)
template
<
class
_Ty
> #pragma warning(pop)
template
<
class
_Callable
,
class
...
_Args
>
using
_Invoke_result_t
=
typename
_Invoke_traits
<
void
,
_Callable
,
_Args
...>::type;
template
<
class
_Rx
,
class
_Callable
,
class
...
_Args
>
using
_Is_invocable_r_
=
typename
_Invoke_traits
<
void
,
_Callable
,
_Args
...>::
template
_Is_invocable_r
<
_Rx
>;
template
<
class
_Rx
,
class
_Callable
,
class
...
_Args
>
struct
_Is_invocable_r
:
_Is_invocable_r_
<
_Rx
,
_Callable
,
_Args
...> {
// determines whether _Callable is callable with _Args and return type _Rx
};
#if _HAS_CXX17
// STRUCT TEMPLATE invoke_result
template<class _Callable,
class... _Args>
struct invoke_result
: _Invoke_traits<void, _Callable, _Args...>
{ // determine the result type of invoking _Callable with _Args
};
template<class _Callable,
class... _Args>
using invoke_result_t = typename _Invoke_traits<void, _Callable, _Args...>::type;
// STRUCT TEMPLATE is_invocable
template<class _Callable,
class... _Args>
struct is_invocable
: _Invoke_traits<void, _Callable, _Args...>::_Is_invocable
{ // determines whether _Callable is callable with _Args
};
template<class _Callable,
class... _Args>
_INLINE_VAR constexpr bool is_invocable_v = _Invoke_traits<void, _Callable, _Args...>::_Is_invocable::value;
// STRUCT TEMPLATE is_nothrow_invocable
template<class _Callable,
class... _Args>
struct is_nothrow_invocable
: _Invoke_traits<void, _Callable, _Args...>::_Is_nothrow_invocable
{ // determines whether _Callable is nothrow-callable with _Args
};
template<class _Callable,
class... _Args>
_INLINE_VAR constexpr bool is_nothrow_invocable_v =
_Invoke_traits<void, _Callable, _Args...>::_Is_nothrow_invocable::value;
// STRUCT TEMPLATE is_invocable_r
template<class _Rx,
class _Callable,
class... _Args>
struct is_invocable_r
: _Is_invocable_r_<_Rx, _Callable, _Args...>
{ // determines whether _Callable is callable with _Args and return type _Rx
};
template<class _Rx,
class _Callable,
class... _Args>
_INLINE_VAR constexpr bool is_invocable_r_v = _Is_invocable_r_<_Rx, _Callable, _Args...>::value;
// STRUCT TEMPLATE is_nothrow_invocable_r
template<class _Rx,
class _Callable,
class... _Args>
struct is_nothrow_invocable_r
: _Invoke_traits<void, _Callable, _Args...>::template _Is_nothrow_invocable_r<_Rx>
{ // determines whether _Callable is nothrow-callable with _Args and return type _Rx
};
template<class _Rx,
class _Callable,
class... _Args>
_INLINE_VAR constexpr bool is_nothrow_invocable_r_v =
_Invoke_traits<void, _Callable, _Args...>::template _Is_nothrow_invocable_r<_Rx>::value; #endif /* _HAS_CXX17 */
// STRUCT TEMPLATE _Weak_types
template
<
class
_Ty
,
class
=
void
>
struct
_Weak_result_type
{
// default definition
}; #pragma warning(push)
template
<
class
_Ty
>
struct
_Weak_result_type
<
_Ty
,
void_t
<
typename
_Ty
::result_type>> {
// defined if _Ty::result_type exists
}; #pragma warning(pop)
template
<
class
_Ty
,
class
=
void
>
struct
_Weak_argument_type
:
_Weak_result_type
<
_Ty
> {
// default definition
}; #pragma warning(push)
template
<
class
_Ty
>
struct
_Weak_argument_type
<
_Ty
,
void_t
<
typename
_Ty
::argument_type>> :
_Weak_result_type
<
_Ty
> {
// defined if _Ty::argument_type exists
}; #pragma warning(pop)
template
<
class
_Ty
,
class
=
void
>
struct
_Weak_binary_args
:
_Weak_argument_type
<
_Ty
> {
// default definition
}; #pragma warning(push)
template
<
class
_Ty
>
struct
_Weak_binary_args
<
_Ty
,
void_t
<
typename
_Ty
::first_argument_type,
typename
_Ty
::second_argument_type>> :
_Weak_argument_type
<
_Ty
> {
// defined if both types exist
}; #pragma warning(pop)
template
<
class
_Ty
>
struct
_Weak_types
{
// provide nested types (sometimes)
using
_Is_f_or_pf
=
_Is_function
<
remove_pointer_t
<
_Ty
>>;
using
_Is_pmf
=
_Is_memfunptr
<
remove_cv_t
<
_Ty
>>;
using
type
=
conditional_t
<
_Is_f_or_pf
::
_Bool_type
::
value
,
_Is_f_or_pf
,
conditional_t
<
_Is_pmf
::
_Bool_type
::
value
,
_Is_pmf
,
_Weak_binary_args
<
_Ty
>>>; };
// CLASS TEMPLATE reference_wrapper
template
<
class
_Ty
>
void
_Refwrap_ctor_fun
(
_Identity_t
<
_Ty
&>)
noexcept
;
template
<
class
_Ty
>
void
_Refwrap_ctor_fun
(
_Identity_t
<
_Ty
&&>) =
delete
;
struct
_Unique_tag_refwrap_has_ctor_from
{
// TRANSITION, VSO#606027
};
template
<
class
_Ty
,
class
_Uty
,
class
=
void
>
struct
_Refwrap_has_ctor_from
:
false_type
{ };
template
<
class
_Ty
,
class
_Uty
>
struct
_Refwrap_has_ctor_from
<
_Ty
,
_Uty
,
void_t
<
_Unique_tag_refwrap_has_ctor_from
,
// TRANSITION, VSO#606027
:
true_type
{ };
template
<
class
_Ty
>
class
reference_wrapper
:
public
_Weak_types
<
_Ty
>::
type
{
// stand-in for an assignable reference
public
:
static_assert
(
is_object_v
<
_Ty
> ||
is_function_v
<
_Ty
>,
"reference_wrapper<T> requires T to be an object type or a function type."
);
using
type
=
_Ty
;
template
<
class
_Uty
,
enable_if_t
<
conjunction_v
<
negation
<
is_same
<
remove_cv_t
<
remove_reference_t
<
_Uty
>>,
reference_wrapper
>>,
_Refwrap_has_ctor_from
<
_Ty
,
_Uty
>>,
int
> =
0
>
reference_wrapper
(
_Uty
&&
_Val
) {
// construct
}
operator
_Ty
&()
const
noexcept
{
// return reference
return
(*
_Ptr
); } {
// return reference
return
(*
_Ptr
); }
template
<
class
...
_Types
>
auto
operator
(
)
(
_Types
&&...
_Args
)
const
{
// invoke object/function
}
private
:
_Ty
*
_Ptr
; };
#if _HAS_CXX17
template<class _Ty>
reference_wrapper(_Ty&)
-> reference_wrapper<_Ty>; #endif /* _HAS_CXX17 */
// FUNCTION TEMPLATES ref AND cref
template
<
class
_Ty
> {
// create reference_wrapper<_Ty> object
return
(
reference_wrapper
<
_Ty
>(
_Val
)); }
template
<
class
_Ty
>
void
ref
(
const
_Ty
&&) =
delete
;
template
<
class
_Ty
> {
// create reference_wrapper<_Ty> object
}
template
<
class
_Ty
> {
// create reference_wrapper<const _Ty> object
return
(
reference_wrapper
<
const
_Ty
>(
_Val
)); }
template
<
class
_Ty
>
void
cref
(
const
_Ty
&&) =
delete
;
template
<
class
_Ty
> {
// create reference_wrapper<const _Ty> object
}
// STRUCT TEMPLATE _Is_swappable
template
<
class
_Ty
>
struct
_Is_swappable
;
// STRUCT TEMPLATE _Is_nothrow_swappable
template
<
class
_Ty
>
struct
_Is_nothrow_swappable
;
// FUNCTION TEMPLATE swap
#if _HAS_CXX17
template<class _Ty,
class = enable_if_t<is_move_constructible_v<_Ty>
&& is_move_assignable_v<_Ty>>> inline #else /* _HAS_CXX17 */
template
<
class
_Ty
,
class
=
void
>
inline
#endif /* _HAS_CXX17 */
void
swap
(
_Ty
&,
_Ty
&)
template
<
class
_Ty
,
size_t
_Size
,
class
=
enable_if_t
<
_Is_swappable
<
_Ty
>::value>>
inline
void
swap
(
_Ty
(&)[
_Size
],
_Ty
(&)[
_Size
])
// STRUCT TEMPLATE _Swappable_with_helper
template
<
class
_Ty1
,
class
_Ty2
,
class
=
void
>
struct
_Swappable_with_helper
:
false_type
{
// swap(declval<_Ty1>(), declval<_Ty2>()) is not valid
};
template
<
class
_Ty1
,
class
_Ty2
> :
true_type
{
// swap(declval<_Ty1>(), declval<_Ty2>()) is valid
};
// STRUCT TEMPLATE _Is_swappable_with
template
<
class
_Ty1
,
class
_Ty2
>
struct
_Is_swappable_with
:
bool_constant
<
conjunction_v
<
_Swappable_with_helper
<
_Ty1
,
_Ty2
>,
_Swappable_with_helper
<
_Ty2
,
_Ty1
>>> {
// Determine if expressions with type and value category _Ty1 and _Ty2
// can be swapped (and vice versa)
};
// STRUCT TEMPLATE _Is_swappable
template
<
class
_Ty
>
struct
_Is_swappable
:
_Is_swappable_with
<
add_lvalue_reference_t
<
_Ty
>,
add_lvalue_reference_t
<
_Ty
>>::
type
{
// Determine if _Ty lvalues satisfy is_swappable_with
};
// STRUCT TEMPLATE _Swap_cannot_throw
template
<
class
_Ty1
,
class
_Ty2
>
struct
_Swap_cannot_throw
{
// Determine if expressions with type and value category _Ty1 and _Ty2
// (presumed to satisfy is_swappable_with) can be swapped without
// emitting exceptions
};
// STRUCT TEMPLATE _Is_nothrow_swappable_with
template
<
class
_Ty1
,
class
_Ty2
>
struct
_Is_nothrow_swappable_with
:
bool_constant
<
conjunction_v
<
_Is_swappable_with
<
_Ty1
,
_Ty2
>,
_Swap_cannot_throw
<
_Ty1
,
_Ty2
>>> {
// Determine if expressions with type and value category _Ty1 and _Ty2
// satisfy is_swappable_with, and can be swapped without emitting exceptions
};
// STRUCT TEMPLATE _Is_nothrow_swappable
template
<
class
_Ty
>
struct
_Is_nothrow_swappable
:
_Is_nothrow_swappable_with
<
add_lvalue_reference_t
<
_Ty
>,
add_lvalue_reference_t
<
_Ty
>>::
type
{
// Determine if _Ty lvalues satisfy is_nothrow_swappable_with
};
#if _HAS_CXX17
// STRUCT TEMPLATE is_swappable_with
template<class _Ty1,
class _Ty2>
struct is_swappable_with
: _Is_swappable_with<_Ty1, _Ty2>::type
{ // Determine if expressions with type and value category _Ty1 and _Ty2
// can be swapped (and vice versa)
};
template<class _Ty1,
class _Ty2>
_INLINE_VAR constexpr bool is_swappable_with_v = is_swappable_with<_Ty1, _Ty2>::value;
// STRUCT TEMPLATE is_swappable
template<class _Ty>
struct is_swappable
: _Is_swappable<_Ty>::type
{ // Determine if _Ty lvalues satisfy is_swappable_with
};
template<class _Ty>
_INLINE_VAR constexpr bool is_swappable_v = is_swappable<_Ty>::value;
// STRUCT TEMPLATE is_nothrow_swappable_with
template<class _Ty1,
class _Ty2>
struct is_nothrow_swappable_with
: _Is_nothrow_swappable_with<_Ty1, _Ty2>::type
{ // Determine if expressions with type and value category _Ty1 and _Ty2
// satisfy is_swappable_with, and can be swapped without emitting exceptions
};
template<class _Ty1,
class _Ty2>
_INLINE_VAR constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_Ty1, _Ty2>::value;
// STRUCT TEMPLATE is_nothrow_swappable
template<class _Ty>
struct is_nothrow_swappable
: _Is_nothrow_swappable<_Ty>::type
{ // Determine if _Ty lvalues satisfy is_nothrow_swappable_with
};
template<class _Ty>
_INLINE_VAR constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Ty>::value; #endif /* _HAS_CXX17 */
// TYPE TRAIT _Is_trivially_swappable
namespace
_Has_ADL_swap_detail
{
void
swap
();
// undefined (deliberate shadowing)
template
<
class
,
class
=
void
>
struct
_Has_ADL_swap
:
false_type
{};
template
<
class
_Ty
> :
true_type
{}; }
// namespace _Has_ADL_swap_detail
using
_Has_ADL_swap_detail
::
_Has_ADL_swap
;
template
<
class
_Ty
>
struct
_Is_trivially_swappable
:
bool_constant
<
conjunction_v
<
is_trivially_destructible
<
_Ty
>,
is_trivially_move_constructible
<
_Ty
>,
is_trivially_move_assignable
<
_Ty
>,
negation
<
_Has_ADL_swap
<
_Ty
>>>> {
// true_type if it is valid to swap two _Ty lvalues by exchanging
// object representations.
};
template
<
class
_Ty
>
// BITMASK OPERATIONS
#define _BITMASK_OPS(_BITMASK) \
_NODISCARD constexpr _BITMASK operator&(_BITMASK _Left, _BITMASK _Right) noexcept \
{ /* return _Left & _Right */ \
using _IntTy = _STD underlying_type_t<_BITMASK>; \
return (static_cast<_BITMASK>(static_cast<_IntTy>(_Left) & static_cast<_IntTy>(_Right))); \
} \
\
_NODISCARD constexpr _BITMASK operator|(_BITMASK _Left, _BITMASK _Right) noexcept \
{ /* return _Left | _Right */ \
using _IntTy = _STD underlying_type_t<_BITMASK>; \
return (static_cast<_BITMASK>(static_cast<_IntTy>(_Left) | static_cast<_IntTy>(_Right))); \
} \
\
_NODISCARD constexpr _BITMASK operator^(_BITMASK _Left, _BITMASK _Right) noexcept \
{ /* return _Left ^ _Right */ \
using _IntTy = _STD underlying_type_t<_BITMASK>; \
return (static_cast<_BITMASK>(static_cast<_IntTy>(_Left) ^ static_cast<_IntTy>(_Right))); \
} \
\
constexpr _BITMASK& operator&=(_BITMASK& _Left, _BITMASK _Right) noexcept \
{ /* return _Left &= _Right */ \
return (_Left = _Left & _Right); \
} \
\
constexpr _BITMASK& operator|=(_BITMASK& _Left, _BITMASK _Right) noexcept \
{ /* return _Left |= _Right */ \
return (_Left = _Left | _Right); \
} \
\
constexpr _BITMASK& operator^=(_BITMASK& _Left, _BITMASK _Right) noexcept \
{ /* return _Left ^= _Right */ \
return (_Left = _Left ^ _Right); \
} \
\
_NODISCARD constexpr _BITMASK operator~(_BITMASK _Left) noexcept \
{ /* return ~_Left */ \
using _IntTy = _STD underlying_type_t<_BITMASK>; \
return (static_cast<_BITMASK>(~static_cast<_IntTy>(_Left))); \
} \
\
_NODISCARD constexpr bool _Bitmask_includes(_BITMASK _Left, _BITMASK _Elements) noexcept \
{ /* return (_Left & _Elements) != _BITMASK{} */ \
using _IntTy = _STD underlying_type_t<_BITMASK>; /* TRANSITION, VSO#574589 */ \
return (static_cast<_IntTy>(_Left & _Elements) != 0); \
} \
\
_NODISCARD constexpr bool _Bitmask_includes_all(_BITMASK _Left, _BITMASK _Elements) noexcept \
{ /* return (_Left & _Elements) == _Elements */ \
return ((_Left & _Elements) == _Elements); \
}
// FNV-1a UTILITIES
// These functions are extremely performance sensitive, check examples like
// that in VSO#653642 before making changes.
#if defined(_WIN64)
_INLINE_VAR constexpr size_t _FNV_offset_basis = 14695981039346656037ULL;
_INLINE_VAR constexpr size_t _FNV_prime = 1099511628211ULL; #else /* defined(_WIN64) */
const
unsigned
char
*
const
_First
,
const
size_t
_Count
)
noexcept
{
// accumulate range [_First, _First + _Count) into partial FNV-1a hash _Val
for
(
size_t
_Idx
=
0
;
_Idx
<
_Count
; ++
_Idx
) {
_Val
^=
static_cast
<
size_t
>(
_First
[
_Idx
]);
_Val
*=
_FNV_prime
; }
return
(
_Val
); }
template
<
class
_Ty
>
const
_Ty
*
const
_First
,
const
_Ty
*
const
_Last
)
noexcept
{
// accumulate range [_First, _Last) into partial FNV-1a hash _Val
static_assert
(
is_trivial_v
<
_Ty
>,
"Only trivial types can be directly hashed."
);
const
auto
_Firstb
=
reinterpret_cast
<
const
unsigned
char
*>(
_First
);
const
auto
_Lastb
=
reinterpret_cast
<
const
unsigned
char
*>(
_Last
);
return
(
_Fnv1a_append_bytes
(
_Val
,
_Firstb
,
static_cast
<
size_t
>(
_Lastb
-
_Firstb
))); }
template
<
class
_Kty
> {
// accumulate _Keyval into partial FNV-1a hash _Val
static_assert
(
is_trivial_v
<
_Kty
>,
"Only trivial types can be directly hashed."
);
return
(
_Fnv1a_append_bytes
(
_Val
, &
reinterpret_cast
<
const
unsigned
char
&>(
_Keyval
),
sizeof
(
_Kty
))); }
// FUNCTION TEMPLATE _Hash_representation
template
<
class
_Kty
> {
// bitwise hashes the representation of a key
return
(
_Fnv1a_append_value
(
_FNV_offset_basis
,
_Keyval
)); }
// FUNCTION TEMPLATE _Hash_array_representation
template
<
class
_Kty
>
const
_Kty
*
const
_First
,
const
size_t
_Count
)
noexcept
{
// bitwise hashes the representation of an array
static_assert
(
is_trivial_v
<
_Kty
>,
"Only trivial types can be directly hashed."
);
return
(
_Fnv1a_append_bytes
(
_FNV_offset_basis
,
reinterpret_cast
<
const
unsigned
char
*>(
_First
),
_Count
*
sizeof
(
_Kty
))); }
// STRUCT TEMPLATE _Conditionally_enabled_hash
template
<
class
_Kty
>
struct
hash
;
template
<
class
_Kty
,
bool
_Enabled
>
struct
_Conditionally_enabled_hash
{
// conditionally enabled hash base
{
// hash _Keyval to size_t value by pseudorandomizing transform
return
(
hash
<
_Kty
>::
_Do_hash
(
_Keyval
)); } };
template
<
class
_Kty
>
struct
_Conditionally_enabled_hash
<
_Kty
,
false
> {
// conditionally disabled hash base
_Conditionally_enabled_hash
() =
delete
;
_Conditionally_enabled_hash
(
const
_Conditionally_enabled_hash
&) =
delete
;
_Conditionally_enabled_hash
(
_Conditionally_enabled_hash
&&) =
delete
;
_Conditionally_enabled_hash
&
operator
=
(
const
_Conditionally_enabled_hash
&) =
delete
;
_Conditionally_enabled_hash
&
operator
=
(
_Conditionally_enabled_hash
&&) =
delete
; };
// STRUCT TEMPLATE hash
template
<
class
_Kty
>
struct
hash
:
_Conditionally_enabled_hash
<
_Kty
, !
is_const_v
<
_Kty
> && !
is_volatile_v
<
_Kty
> && (
is_enum_v
<
_Kty
> ||
is_integral_v
<
_Kty
> ||
is_pointer_v
<
_Kty
>)> {
// hash functor primary template (handles enums, integrals, and pointers)
static
size_t
_Do_hash
(
const
_Kty
&
_Keyval
)
noexcept
{
// hash _Keyval to size_t value by pseudorandomizing transform
return
(
_Hash_representation
(
_Keyval
)); } };
template
<>
struct
hash
<
float
> {
// hash functor for float
{
// hash _Keyval to size_t value by pseudorandomizing transform
return
(
_Hash_representation
(
_Keyval
=
=
0.0F
?
0.0F
:
_Keyval
));
// map -0 to 0
} };
template
<>
struct
hash
<
double
> {
// hash functor for double
{
// hash _Keyval to size_t value by pseudorandomizing transform
return
(
_Hash_representation
(
_Keyval
=
=
0.0
?
0.0
:
_Keyval
));
// map -0 to 0
} };
template
<>
struct
hash
<
long
double
> {
// hash functor for long double
{
// hash _Keyval to size_t value by pseudorandomizing transform
return
(
_Hash_representation
(
_Keyval
=
=
0.0L
?
0.0L
:
_Keyval
));
// map -0 to 0
} };
template
<>
struct
hash
<
nullptr_t
> {
// hash functor for nullptr_t
{
// hash nullptr_t to size_t value by pseudorandomizing transform
void
*
_Null
{};
return
(
_Hash_representation
(
_Null
)); } };
// STRUCT TEMPLATE _Is_nothrow_hashable
template
<
class
_Kty
,
class
=
void
>
struct
_Is_nothrow_hashable
:
false_type
{
// tests if std::hash can hash _Kty with noexcept
};
template
<
class
_Kty
> {
// tests if std::hash can hash _Kty with noexcept
};
#if _HAS_TR1_NAMESPACE
#pragma warning(push) } #pragma warning(pop)
#endif /* _HAS_TR1_NAMESPACE */
// EVERYTHING BELOW WILL HAVE STRANGE LINE NUMBERS
#define _DEBUGGER_STEP_OVER 15732479 // 0xf00f00 - 1
#define _DEBUGGER_STEP_INTO 16707565 // 0xfeefee - 1
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
#if _HAS_CXX17
// constexpr IMPLEMENTATION OF invoke
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
_IMPLEMENT_INVOKE(_C_, constexpr) #endif /* _HAS_CXX17 */
#undef _IMPLEMENT_INVOKE
template
<
class
_Rx
,
bool
=
is_void_v
<
_Rx
>>
struct
_Invoker_ret
{
// helper to give INVOKE an explicit return type; avoids undesirable Expression SFINAE
};
template
<
class
_Cv_void
>
struct
_Invoker_ret
<
_Cv_void
,
true
> {
// selected for _Rx being cv void
template
<
class
...
_Valtys
>
static
void
_Call
(
_Valtys
&&...
_Vals
)
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
{
// INVOKE, "implicitly" converted to void
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
} };
template
<
class
_Rx
>
struct
_Invoker_ret
<
_Rx
,
false
> {
// selected for all _Rx other than cv void and _Unforced
template
<
class
...
_Valtys
>
static
_Rx
_Call
(
_Valtys
&&...
_Vals
)
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
{
// INVOKE, implicitly converted to _Rx
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
} };
template
<>
struct
_Invoker_ret
<
_Unforced
,
false
> {
// selected for _Rx being _Unforced
template
<
class
...
_Valtys
>
static
auto
_Call
(
_Valtys
&&...
_Vals
)
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
{
// INVOKE, unchanged
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
} };
#pragma pop_macro("new")
_STL_RESTORE_CLANG_WARNINGS
/* * Copyright (c) by P.J. Plauger. All rights reserved. * Consult your license regarding permissions and restrictions. V6.50:0009 */