// C++11 -*- C++ -*- // Copyright (C) 2007-2019 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // . /** @file include/type_traits * This is a Standard C++ Library header. */ #ifndef _GLIBCXX_TYPE_TRAITS #define _GLIBCXX_TYPE_TRAITS 1 #pragma GCC system_header #if __cplusplus < 201103L # include #else #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION /** * @defgroup metaprogramming Metaprogramming * @ingroup utilities * * Template utilities for compile-time introspection and modification, * including type classification traits, type property inspection traits * and type transformation traits. * * @{ */ /// integral_constant template struct integral_constant { static constexpr _Tp value = __v; typedef _Tp value_type; typedef integral_constant<_Tp, __v> type; constexpr operator value_type() const noexcept { return value; } #if __cplusplus > 201103L #define __cpp_lib_integral_constant_callable 201304 constexpr value_type operator()() const noexcept { return value; } #endif }; template constexpr _Tp integral_constant<_Tp, __v>::value; /// The type used as a compile-time boolean with true value. typedef integral_constant true_type; /// The type used as a compile-time boolean with false value. typedef integral_constant false_type; template using __bool_constant = integral_constant; #if __cplusplus > 201402L # define __cpp_lib_bool_constant 201505 template using bool_constant = integral_constant; #endif // Meta programming helper types. template struct conditional; template struct __or_; template<> struct __or_<> : public false_type { }; template struct __or_<_B1> : public _B1 { }; template struct __or_<_B1, _B2> : public conditional<_B1::value, _B1, _B2>::type { }; template struct __or_<_B1, _B2, _B3, _Bn...> : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type { }; template struct __and_; template<> struct __and_<> : public true_type { }; template struct __and_<_B1> : public _B1 { }; template struct __and_<_B1, _B2> : public conditional<_B1::value, _B2, _B1>::type { }; template struct __and_<_B1, _B2, _B3, _Bn...> : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type { }; template struct __not_ : public __bool_constant { }; #if __cplusplus >= 201703L template inline constexpr bool __or_v = __or_<_Bn...>::value; template inline constexpr bool __and_v = __and_<_Bn...>::value; #define __cpp_lib_logical_traits 201510 template struct conjunction : __and_<_Bn...> { }; template struct disjunction : __or_<_Bn...> { }; template struct negation : __not_<_Pp> { }; template inline constexpr bool conjunction_v = conjunction<_Bn...>::value; template inline constexpr bool disjunction_v = disjunction<_Bn...>::value; template inline constexpr bool negation_v = negation<_Pp>::value; #endif // C++17 // For several sfinae-friendly trait implementations we transport both the // result information (as the member type) and the failure information (no // member type). This is very similar to std::enable_if, but we cannot use // them, because we need to derive from them as an implementation detail. template struct __success_type { typedef _Tp type; }; struct __failure_type { }; // Primary type categories. template struct remove_cv; template struct __is_void_helper : public false_type { }; template<> struct __is_void_helper : public true_type { }; /// is_void template struct is_void : public __is_void_helper::type>::type { }; template struct __is_integral_helper : public false_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; #ifdef _GLIBCXX_USE_WCHAR_T template<> struct __is_integral_helper : public true_type { }; #endif #ifdef _GLIBCXX_USE_CHAR8_T template<> struct __is_integral_helper : public true_type { }; #endif template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; template<> struct __is_integral_helper : public true_type { }; // Conditionalizing on __STRICT_ANSI__ here will break any port that // uses one of these types for size_t. #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_0> : public true_type { }; template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_1> : public true_type { }; template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_2> : public true_type { }; template<> struct __is_integral_helper : public true_type { }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) template<> struct __is_integral_helper<__GLIBCXX_TYPE_INT_N_3> : public true_type { }; template<> struct __is_integral_helper : public true_type { }; #endif /// is_integral template struct is_integral : public __is_integral_helper::type>::type { }; template struct __is_floating_point_helper : public false_type { }; template<> struct __is_floating_point_helper : public true_type { }; template<> struct __is_floating_point_helper : public true_type { }; template<> struct __is_floating_point_helper : public true_type { }; #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) template<> struct __is_floating_point_helper<__float128> : public true_type { }; #endif /// is_floating_point template struct is_floating_point : public __is_floating_point_helper::type>::type { }; /// is_array template struct is_array : public false_type { }; template struct is_array<_Tp[_Size]> : public true_type { }; template struct is_array<_Tp[]> : public true_type { }; template struct __is_pointer_helper : public false_type { }; template struct __is_pointer_helper<_Tp*> : public true_type { }; /// is_pointer template struct is_pointer : public __is_pointer_helper::type>::type { }; /// is_lvalue_reference template struct is_lvalue_reference : public false_type { }; template struct is_lvalue_reference<_Tp&> : public true_type { }; /// is_rvalue_reference template struct is_rvalue_reference : public false_type { }; template struct is_rvalue_reference<_Tp&&> : public true_type { }; template struct is_function; template struct __is_member_object_pointer_helper : public false_type { }; template struct __is_member_object_pointer_helper<_Tp _Cp::*> : public __not_>::type { }; /// is_member_object_pointer template struct is_member_object_pointer : public __is_member_object_pointer_helper< typename remove_cv<_Tp>::type>::type { }; template struct __is_member_function_pointer_helper : public false_type { }; template struct __is_member_function_pointer_helper<_Tp _Cp::*> : public is_function<_Tp>::type { }; /// is_member_function_pointer template struct is_member_function_pointer : public __is_member_function_pointer_helper< typename remove_cv<_Tp>::type>::type { }; /// is_enum template struct is_enum : public integral_constant { }; /// is_union template struct is_union : public integral_constant { }; /// is_class template struct is_class : public integral_constant { }; /// is_function template struct is_function : public false_type { }; template struct is_function<_Res(_ArgTypes...) _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) const _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) const & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) const && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) const _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) const & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) const && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) volatile _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) volatile & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) volatile && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) volatile _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) volatile & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) volatile && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) const volatile _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) const volatile & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes...) const volatile && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) const volatile _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) const volatile & _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct is_function<_Res(_ArgTypes......) const volatile && _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; #define __cpp_lib_is_null_pointer 201309 template struct __is_null_pointer_helper : public false_type { }; template<> struct __is_null_pointer_helper : public true_type { }; /// is_null_pointer (LWG 2247). template struct is_null_pointer : public __is_null_pointer_helper::type>::type { }; /// __is_nullptr_t (extension). template struct __is_nullptr_t : public is_null_pointer<_Tp> { }; // Composite type categories. /// is_reference template struct is_reference : public __or_, is_rvalue_reference<_Tp>>::type { }; /// is_arithmetic template struct is_arithmetic : public __or_, is_floating_point<_Tp>>::type { }; /// is_fundamental template struct is_fundamental : public __or_, is_void<_Tp>, is_null_pointer<_Tp>>::type { }; /// is_object template struct is_object : public __not_<__or_, is_reference<_Tp>, is_void<_Tp>>>::type { }; template struct is_member_pointer; /// is_scalar template struct is_scalar : public __or_, is_enum<_Tp>, is_pointer<_Tp>, is_member_pointer<_Tp>, is_null_pointer<_Tp>>::type { }; /// is_compound template struct is_compound : public __not_>::type { }; template struct __is_member_pointer_helper : public false_type { }; template struct __is_member_pointer_helper<_Tp _Cp::*> : public true_type { }; /// is_member_pointer template struct is_member_pointer : public __is_member_pointer_helper::type>::type { }; // Utility to detect referenceable types ([defns.referenceable]). template struct __is_referenceable : public __or_, is_reference<_Tp>>::type { }; template struct __is_referenceable<_Res(_Args...) _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; template struct __is_referenceable<_Res(_Args......) _GLIBCXX_NOEXCEPT_QUAL> : public true_type { }; // Type properties. /// is_const template struct is_const : public false_type { }; template struct is_const<_Tp const> : public true_type { }; /// is_volatile template struct is_volatile : public false_type { }; template struct is_volatile<_Tp volatile> : public true_type { }; /// is_trivial template struct is_trivial : public integral_constant { }; // is_trivially_copyable template struct is_trivially_copyable : public integral_constant { }; /// is_standard_layout template struct is_standard_layout : public integral_constant { }; /// is_pod // Could use is_standard_layout && is_trivial instead of the builtin. template struct is_pod : public integral_constant { }; /// is_literal_type template struct is_literal_type : public integral_constant { }; /// is_empty template struct is_empty : public integral_constant { }; /// is_polymorphic template struct is_polymorphic : public integral_constant { }; #if __cplusplus >= 201402L #define __cpp_lib_is_final 201402L /// is_final template struct is_final : public integral_constant { }; #endif /// is_abstract template struct is_abstract : public integral_constant { }; template::value> struct __is_signed_helper : public false_type { }; template struct __is_signed_helper<_Tp, true> : public integral_constant { }; /// is_signed template struct is_signed : public __is_signed_helper<_Tp>::type { }; /// is_unsigned template struct is_unsigned : public __and_, __not_>> { }; // Destructible and constructible type properties. /** * @brief Utility to simplify expressions used in unevaluated operands * @ingroup utilities */ template _Up __declval(int); template _Tp __declval(long); template auto declval() noexcept -> decltype(__declval<_Tp>(0)); template struct extent; template struct remove_all_extents; template struct __is_array_known_bounds : public integral_constant::value > 0)> { }; template struct __is_array_unknown_bounds : public __and_, __not_>> { }; // In N3290 is_destructible does not say anything about function // types and abstract types, see LWG 2049. This implementation // describes function types as non-destructible and all complete // object types as destructible, iff the explicit destructor // call expression is wellformed. struct __do_is_destructible_impl { template().~_Tp())> static true_type __test(int); template static false_type __test(...); }; template struct __is_destructible_impl : public __do_is_destructible_impl { typedef decltype(__test<_Tp>(0)) type; }; template, __is_array_unknown_bounds<_Tp>, is_function<_Tp>>::value, bool = __or_, is_scalar<_Tp>>::value> struct __is_destructible_safe; template struct __is_destructible_safe<_Tp, false, false> : public __is_destructible_impl::type>::type { }; template struct __is_destructible_safe<_Tp, true, false> : public false_type { }; template struct __is_destructible_safe<_Tp, false, true> : public true_type { }; /// is_destructible template struct is_destructible : public __is_destructible_safe<_Tp>::type { }; // is_nothrow_destructible requires that is_destructible is // satisfied as well. We realize that by mimicing the // implementation of is_destructible but refer to noexcept(expr) // instead of decltype(expr). struct __do_is_nt_destructible_impl { template static __bool_constant().~_Tp())> __test(int); template static false_type __test(...); }; template struct __is_nt_destructible_impl : public __do_is_nt_destructible_impl { typedef decltype(__test<_Tp>(0)) type; }; template, __is_array_unknown_bounds<_Tp>, is_function<_Tp>>::value, bool = __or_, is_scalar<_Tp>>::value> struct __is_nt_destructible_safe; template struct __is_nt_destructible_safe<_Tp, false, false> : public __is_nt_destructible_impl::type>::type { }; template struct __is_nt_destructible_safe<_Tp, true, false> : public false_type { }; template struct __is_nt_destructible_safe<_Tp, false, true> : public true_type { }; /// is_nothrow_destructible template struct is_nothrow_destructible : public __is_nt_destructible_safe<_Tp>::type { }; /// is_constructible template struct is_constructible : public __bool_constant<__is_constructible(_Tp, _Args...)> { }; /// is_default_constructible template struct is_default_constructible : public is_constructible<_Tp>::type { }; template::value> struct __is_copy_constructible_impl; template struct __is_copy_constructible_impl<_Tp, false> : public false_type { }; template struct __is_copy_constructible_impl<_Tp, true> : public is_constructible<_Tp, const _Tp&> { }; /// is_copy_constructible template struct is_copy_constructible : public __is_copy_constructible_impl<_Tp> { }; template::value> struct __is_move_constructible_impl; template struct __is_move_constructible_impl<_Tp, false> : public false_type { }; template struct __is_move_constructible_impl<_Tp, true> : public is_constructible<_Tp, _Tp&&> { }; /// is_move_constructible template struct is_move_constructible : public __is_move_constructible_impl<_Tp> { }; template struct __is_nt_default_constructible_atom : public integral_constant { }; template::value> struct __is_nt_default_constructible_impl; template struct __is_nt_default_constructible_impl<_Tp, true> : public __and_<__is_array_known_bounds<_Tp>, __is_nt_default_constructible_atom::type>> { }; template struct __is_nt_default_constructible_impl<_Tp, false> : public __is_nt_default_constructible_atom<_Tp> { }; /// is_nothrow_default_constructible template struct is_nothrow_default_constructible : public __and_, __is_nt_default_constructible_impl<_Tp>> { }; template struct __is_nt_constructible_impl : public integral_constant()...))> { }; template struct __is_nt_constructible_impl<_Tp, _Arg> : public integral_constant(declval<_Arg>()))> { }; template struct __is_nt_constructible_impl<_Tp> : public is_nothrow_default_constructible<_Tp> { }; /// is_nothrow_constructible template struct is_nothrow_constructible : public __and_, __is_nt_constructible_impl<_Tp, _Args...>> { }; template::value> struct __is_nothrow_copy_constructible_impl; template struct __is_nothrow_copy_constructible_impl<_Tp, false> : public false_type { }; template struct __is_nothrow_copy_constructible_impl<_Tp, true> : public is_nothrow_constructible<_Tp, const _Tp&> { }; /// is_nothrow_copy_constructible template struct is_nothrow_copy_constructible : public __is_nothrow_copy_constructible_impl<_Tp> { }; template::value> struct __is_nothrow_move_constructible_impl; template struct __is_nothrow_move_constructible_impl<_Tp, false> : public false_type { }; template struct __is_nothrow_move_constructible_impl<_Tp, true> : public is_nothrow_constructible<_Tp, _Tp&&> { }; /// is_nothrow_move_constructible template struct is_nothrow_move_constructible : public __is_nothrow_move_constructible_impl<_Tp> { }; /// is_assignable template struct is_assignable : public __bool_constant<__is_assignable(_Tp, _Up)> { }; template::value> struct __is_copy_assignable_impl; template struct __is_copy_assignable_impl<_Tp, false> : public false_type { }; template struct __is_copy_assignable_impl<_Tp, true> : public is_assignable<_Tp&, const _Tp&> { }; /// is_copy_assignable template struct is_copy_assignable : public __is_copy_assignable_impl<_Tp> { }; template::value> struct __is_move_assignable_impl; template struct __is_move_assignable_impl<_Tp, false> : public false_type { }; template struct __is_move_assignable_impl<_Tp, true> : public is_assignable<_Tp&, _Tp&&> { }; /// is_move_assignable template struct is_move_assignable : public __is_move_assignable_impl<_Tp> { }; template struct __is_nt_assignable_impl : public integral_constant() = declval<_Up>())> { }; /// is_nothrow_assignable template struct is_nothrow_assignable : public __and_, __is_nt_assignable_impl<_Tp, _Up>> { }; template::value> struct __is_nt_copy_assignable_impl; template struct __is_nt_copy_assignable_impl<_Tp, false> : public false_type { }; template struct __is_nt_copy_assignable_impl<_Tp, true> : public is_nothrow_assignable<_Tp&, const _Tp&> { }; /// is_nothrow_copy_assignable template struct is_nothrow_copy_assignable : public __is_nt_copy_assignable_impl<_Tp> { }; template::value> struct __is_nt_move_assignable_impl; template struct __is_nt_move_assignable_impl<_Tp, false> : public false_type { }; template struct __is_nt_move_assignable_impl<_Tp, true> : public is_nothrow_assignable<_Tp&, _Tp&&> { }; /// is_nothrow_move_assignable template struct is_nothrow_move_assignable : public __is_nt_move_assignable_impl<_Tp> { }; /// is_trivially_constructible template struct is_trivially_constructible : public __bool_constant<__is_trivially_constructible(_Tp, _Args...)> { }; /// is_trivially_default_constructible template struct is_trivially_default_constructible : public is_trivially_constructible<_Tp>::type { }; struct __do_is_implicitly_default_constructible_impl { template static void __helper(const _Tp&); template static true_type __test(const _Tp&, decltype(__helper({}))* = 0); static false_type __test(...); }; template struct __is_implicitly_default_constructible_impl : public __do_is_implicitly_default_constructible_impl { typedef decltype(__test(declval<_Tp>())) type; }; template struct __is_implicitly_default_constructible_safe : public __is_implicitly_default_constructible_impl<_Tp>::type { }; template struct __is_implicitly_default_constructible : public __and_, __is_implicitly_default_constructible_safe<_Tp>> { }; /// is_trivially_copy_constructible template::value> struct __is_trivially_copy_constructible_impl; template struct __is_trivially_copy_constructible_impl<_Tp, false> : public false_type { }; template struct __is_trivially_copy_constructible_impl<_Tp, true> : public __and_, integral_constant> { }; template struct is_trivially_copy_constructible : public __is_trivially_copy_constructible_impl<_Tp> { }; /// is_trivially_move_constructible template::value> struct __is_trivially_move_constructible_impl; template struct __is_trivially_move_constructible_impl<_Tp, false> : public false_type { }; template struct __is_trivially_move_constructible_impl<_Tp, true> : public __and_, integral_constant> { }; template struct is_trivially_move_constructible : public __is_trivially_move_constructible_impl<_Tp> { }; /// is_trivially_assignable template struct is_trivially_assignable : public __bool_constant<__is_trivially_assignable(_Tp, _Up)> { }; /// is_trivially_copy_assignable template::value> struct __is_trivially_copy_assignable_impl; template struct __is_trivially_copy_assignable_impl<_Tp, false> : public false_type { }; template struct __is_trivially_copy_assignable_impl<_Tp, true> : public __bool_constant<__is_trivially_assignable(_Tp&, const _Tp&)> { }; template struct is_trivially_copy_assignable : public __is_trivially_copy_assignable_impl<_Tp> { }; /// is_trivially_move_assignable template::value> struct __is_trivially_move_assignable_impl; template struct __is_trivially_move_assignable_impl<_Tp, false> : public false_type { }; template struct __is_trivially_move_assignable_impl<_Tp, true> : public __bool_constant<__is_trivially_assignable(_Tp&, _Tp&&)> { }; template struct is_trivially_move_assignable : public __is_trivially_move_assignable_impl<_Tp> { }; /// is_trivially_destructible template struct is_trivially_destructible : public __and_, __bool_constant<__has_trivial_destructor(_Tp)>> { }; /// has_virtual_destructor template struct has_virtual_destructor : public integral_constant { }; // type property queries. /// alignment_of template struct alignment_of : public integral_constant { }; /// rank template struct rank : public integral_constant { }; template struct rank<_Tp[_Size]> : public integral_constant::value> { }; template struct rank<_Tp[]> : public integral_constant::value> { }; /// extent template struct extent : public integral_constant { }; template struct extent<_Tp[_Size], _Uint> : public integral_constant::value> { }; template struct extent<_Tp[], _Uint> : public integral_constant::value> { }; // Type relations. /// is_same template struct is_same : public false_type { }; template struct is_same<_Tp, _Tp> : public true_type { }; /// is_base_of template struct is_base_of : public integral_constant { }; template, is_function<_To>, is_array<_To>>::value> struct __is_convertible_helper { typedef typename is_void<_To>::type type; }; template class __is_convertible_helper<_From, _To, false> { template static void __test_aux(_To1) noexcept; template(std::declval<_From1>()))> static true_type __test(int); template static false_type __test(...); public: typedef decltype(__test<_From, _To>(0)) type; }; /// is_convertible template struct is_convertible : public __is_convertible_helper<_From, _To>::type { }; #if __cplusplus > 201703L template, is_function<_To>, is_array<_To>>::value> struct __is_nt_convertible_helper : is_void<_To> { }; template class __is_nt_convertible_helper<_From, _To, false> { template static void __test_aux(_To1) noexcept; template static bool_constant(std::declval<_From1>()))> __test(int); template static false_type __test(...); public: using type = decltype(__test<_From, _To>(0)); }; /// is_nothrow_convertible template struct is_nothrow_convertible : public __is_nt_convertible_helper<_From, _To>::type { }; /// is_nothrow_convertible_v template inline constexpr bool is_nothrow_convertible_v = is_nothrow_convertible<_From, _To>::value; #endif // C++2a // Const-volatile modifications. /// remove_const template struct remove_const { typedef _Tp type; }; template struct remove_const<_Tp const> { typedef _Tp type; }; /// remove_volatile template struct remove_volatile { typedef _Tp type; }; template struct remove_volatile<_Tp volatile> { typedef _Tp type; }; /// remove_cv template struct remove_cv { typedef typename remove_const::type>::type type; }; /// add_const template struct add_const { typedef _Tp const type; }; /// add_volatile template struct add_volatile { typedef _Tp volatile type; }; /// add_cv template struct add_cv { typedef typename add_const::type>::type type; }; #if __cplusplus > 201103L #define __cpp_lib_transformation_trait_aliases 201304 /// Alias template for remove_const template using remove_const_t = typename remove_const<_Tp>::type; /// Alias template for remove_volatile template using remove_volatile_t = typename remove_volatile<_Tp>::type; /// Alias template for remove_cv template using remove_cv_t = typename remove_cv<_Tp>::type; /// Alias template for add_const template using add_const_t = typename add_const<_Tp>::type; /// Alias template for add_volatile template using add_volatile_t = typename add_volatile<_Tp>::type; /// Alias template for add_cv template using add_cv_t = typename add_cv<_Tp>::type; #endif // Reference transformations. /// remove_reference template struct remove_reference { typedef _Tp type; }; template struct remove_reference<_Tp&> { typedef _Tp type; }; template struct remove_reference<_Tp&&> { typedef _Tp type; }; template::value> struct __add_lvalue_reference_helper { typedef _Tp type; }; template struct __add_lvalue_reference_helper<_Tp, true> { typedef _Tp& type; }; /// add_lvalue_reference template struct add_lvalue_reference : public __add_lvalue_reference_helper<_Tp> { }; template::value> struct __add_rvalue_reference_helper { typedef _Tp type; }; template struct __add_rvalue_reference_helper<_Tp, true> { typedef _Tp&& type; }; /// add_rvalue_reference template struct add_rvalue_reference : public __add_rvalue_reference_helper<_Tp> { }; #if __cplusplus > 201103L /// Alias template for remove_reference template using remove_reference_t = typename remove_reference<_Tp>::type; /// Alias template for add_lvalue_reference template using add_lvalue_reference_t = typename add_lvalue_reference<_Tp>::type; /// Alias template for add_rvalue_reference template using add_rvalue_reference_t = typename add_rvalue_reference<_Tp>::type; #endif // Sign modifications. // Utility for constructing identically cv-qualified types. template struct __cv_selector; template struct __cv_selector<_Unqualified, false, false> { typedef _Unqualified __type; }; template struct __cv_selector<_Unqualified, false, true> { typedef volatile _Unqualified __type; }; template struct __cv_selector<_Unqualified, true, false> { typedef const _Unqualified __type; }; template struct __cv_selector<_Unqualified, true, true> { typedef const volatile _Unqualified __type; }; template::value, bool _IsVol = is_volatile<_Qualified>::value> class __match_cv_qualifiers { typedef __cv_selector<_Unqualified, _IsConst, _IsVol> __match; public: typedef typename __match::__type __type; }; // Utility for finding the unsigned versions of signed integral types. template struct __make_unsigned { typedef _Tp __type; }; template<> struct __make_unsigned { typedef unsigned char __type; }; template<> struct __make_unsigned { typedef unsigned char __type; }; template<> struct __make_unsigned { typedef unsigned short __type; }; template<> struct __make_unsigned { typedef unsigned int __type; }; template<> struct __make_unsigned { typedef unsigned long __type; }; template<> struct __make_unsigned { typedef unsigned long long __type; }; #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_0> { typedef unsigned __GLIBCXX_TYPE_INT_N_0 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_1> { typedef unsigned __GLIBCXX_TYPE_INT_N_1 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_2> { typedef unsigned __GLIBCXX_TYPE_INT_N_2 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) template<> struct __make_unsigned<__GLIBCXX_TYPE_INT_N_3> { typedef unsigned __GLIBCXX_TYPE_INT_N_3 __type; }; #endif // Select between integral and enum: not possible to be both. template::value, bool _IsEnum = is_enum<_Tp>::value> class __make_unsigned_selector; template class __make_unsigned_selector<_Tp, true, false> { using __unsigned_type = typename __make_unsigned::type>::__type; public: using __type = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type; }; class __make_unsigned_selector_base { protected: template struct _List { }; template struct _List<_Tp, _Up...> : _List<_Up...> { static constexpr size_t __size = sizeof(_Tp); }; template struct __select; template struct __select<_Sz, _List<_Uint, _UInts...>, true> { using __type = _Uint; }; template struct __select<_Sz, _List<_Uint, _UInts...>, false> : __select<_Sz, _List<_UInts...>> { }; }; // Choose unsigned integer type with the smallest rank and same size as _Tp template class __make_unsigned_selector<_Tp, false, true> : __make_unsigned_selector_base { // With -fshort-enums, an enum may be as small as a char. using _UInts = _List; using __unsigned_type = typename __select::__type; public: using __type = typename __match_cv_qualifiers<_Tp, __unsigned_type>::__type; }; // wchar_t, char8_t, char16_t and char32_t are integral types but are // neither signed integer types nor unsigned integer types, so must be // transformed to the unsigned integer type with the smallest rank. // Use the partial specialization for enumeration types to do that. #if defined(_GLIBCXX_USE_WCHAR_T) template<> struct __make_unsigned { using __type = typename __make_unsigned_selector::__type; }; #endif #ifdef _GLIBCXX_USE_CHAR8_T template<> struct __make_unsigned { using __type = typename __make_unsigned_selector::__type; }; #endif template<> struct __make_unsigned { using __type = typename __make_unsigned_selector::__type; }; template<> struct __make_unsigned { using __type = typename __make_unsigned_selector::__type; }; // Given an integral/enum type, return the corresponding unsigned // integer type. // Primary template. /// make_unsigned template struct make_unsigned { typedef typename __make_unsigned_selector<_Tp>::__type type; }; // Integral, but don't define. template<> struct make_unsigned; // Utility for finding the signed versions of unsigned integral types. template struct __make_signed { typedef _Tp __type; }; template<> struct __make_signed { typedef signed char __type; }; template<> struct __make_signed { typedef signed char __type; }; template<> struct __make_signed { typedef signed short __type; }; template<> struct __make_signed { typedef signed int __type; }; template<> struct __make_signed { typedef signed long __type; }; template<> struct __make_signed { typedef signed long long __type; }; #if defined(__GLIBCXX_TYPE_INT_N_0) template<> struct __make_signed { typedef __GLIBCXX_TYPE_INT_N_0 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_1) template<> struct __make_signed { typedef __GLIBCXX_TYPE_INT_N_1 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_2) template<> struct __make_signed { typedef __GLIBCXX_TYPE_INT_N_2 __type; }; #endif #if defined(__GLIBCXX_TYPE_INT_N_3) template<> struct __make_signed { typedef __GLIBCXX_TYPE_INT_N_3 __type; }; #endif // Select between integral and enum: not possible to be both. template::value, bool _IsEnum = is_enum<_Tp>::value> class __make_signed_selector; template class __make_signed_selector<_Tp, true, false> { using __signed_type = typename __make_signed::type>::__type; public: using __type = typename __match_cv_qualifiers<_Tp, __signed_type>::__type; }; // Choose signed integer type with the smallest rank and same size as _Tp template class __make_signed_selector<_Tp, false, true> { typedef typename __make_unsigned_selector<_Tp>::__type __unsigned_type; public: typedef typename __make_signed_selector<__unsigned_type>::__type __type; }; // wchar_t, char16_t and char32_t are integral types but are neither // signed integer types nor unsigned integer types, so must be // transformed to the signed integer type with the smallest rank. // Use the partial specialization for enumeration types to do that. #if defined(_GLIBCXX_USE_WCHAR_T) template<> struct __make_signed { using __type = typename __make_signed_selector::__type; }; #endif #if defined(_GLIBCXX_USE_CHAR8_T) template<> struct __make_signed { using __type = typename __make_signed_selector::__type; }; #endif template<> struct __make_signed { using __type = typename __make_signed_selector::__type; }; template<> struct __make_signed { using __type = typename __make_signed_selector::__type; }; // Given an integral/enum type, return the corresponding signed // integer type. // Primary template. /// make_signed template struct make_signed { typedef typename __make_signed_selector<_Tp>::__type type; }; // Integral, but don't define. template<> struct make_signed; #if __cplusplus > 201103L /// Alias template for make_signed template using make_signed_t = typename make_signed<_Tp>::type; /// Alias template for make_unsigned template using make_unsigned_t = typename make_unsigned<_Tp>::type; #endif // Array modifications. /// remove_extent template struct remove_extent { typedef _Tp type; }; template struct remove_extent<_Tp[_Size]> { typedef _Tp type; }; template struct remove_extent<_Tp[]> { typedef _Tp type; }; /// remove_all_extents template struct remove_all_extents { typedef _Tp type; }; template struct remove_all_extents<_Tp[_Size]> { typedef typename remove_all_extents<_Tp>::type type; }; template struct remove_all_extents<_Tp[]> { typedef typename remove_all_extents<_Tp>::type type; }; #if __cplusplus > 201103L /// Alias template for remove_extent template using remove_extent_t = typename remove_extent<_Tp>::type; /// Alias template for remove_all_extents template using remove_all_extents_t = typename remove_all_extents<_Tp>::type; #endif // Pointer modifications. template struct __remove_pointer_helper { typedef _Tp type; }; template struct __remove_pointer_helper<_Tp, _Up*> { typedef _Up type; }; /// remove_pointer template struct remove_pointer : public __remove_pointer_helper<_Tp, typename remove_cv<_Tp>::type> { }; /// add_pointer template, is_void<_Tp>>::value> struct __add_pointer_helper { typedef _Tp type; }; template struct __add_pointer_helper<_Tp, true> { typedef typename remove_reference<_Tp>::type* type; }; template struct add_pointer : public __add_pointer_helper<_Tp> { }; #if __cplusplus > 201103L /// Alias template for remove_pointer template using remove_pointer_t = typename remove_pointer<_Tp>::type; /// Alias template for add_pointer template using add_pointer_t = typename add_pointer<_Tp>::type; #endif template struct __aligned_storage_msa { union __type { unsigned char __data[_Len]; struct __attribute__((__aligned__)) { } __align; }; }; /** * @brief Alignment type. * * The value of _Align is a default-alignment which shall be the * most stringent alignment requirement for any C++ object type * whose size is no greater than _Len (3.9). The member typedef * type shall be a POD type suitable for use as uninitialized * storage for any object whose size is at most _Len and whose * alignment is a divisor of _Align. */ template::__type)> struct aligned_storage { union type { unsigned char __data[_Len]; struct __attribute__((__aligned__((_Align)))) { } __align; }; }; template struct __strictest_alignment { static const size_t _S_alignment = 0; static const size_t _S_size = 0; }; template struct __strictest_alignment<_Tp, _Types...> { static const size_t _S_alignment = alignof(_Tp) > __strictest_alignment<_Types...>::_S_alignment ? alignof(_Tp) : __strictest_alignment<_Types...>::_S_alignment; static const size_t _S_size = sizeof(_Tp) > __strictest_alignment<_Types...>::_S_size ? sizeof(_Tp) : __strictest_alignment<_Types...>::_S_size; }; /** * @brief Provide aligned storage for types. * * [meta.trans.other] * * Provides aligned storage for any of the provided types of at * least size _Len. * * @see aligned_storage */ template struct aligned_union { private: static_assert(sizeof...(_Types) != 0, "At least one type is required"); using __strictest = __strictest_alignment<_Types...>; static const size_t _S_len = _Len > __strictest::_S_size ? _Len : __strictest::_S_size; public: /// The value of the strictest alignment of _Types. static const size_t alignment_value = __strictest::_S_alignment; /// The storage. typedef typename aligned_storage<_S_len, alignment_value>::type type; }; template const size_t aligned_union<_Len, _Types...>::alignment_value; // Decay trait for arrays and functions, used for perfect forwarding // in make_pair, make_tuple, etc. template::value, bool _IsFunction = is_function<_Up>::value> struct __decay_selector; // NB: DR 705. template struct __decay_selector<_Up, false, false> { typedef typename remove_cv<_Up>::type __type; }; template struct __decay_selector<_Up, true, false> { typedef typename remove_extent<_Up>::type* __type; }; template struct __decay_selector<_Up, false, true> { typedef typename add_pointer<_Up>::type __type; }; /// decay template class decay { typedef typename remove_reference<_Tp>::type __remove_type; public: typedef typename __decay_selector<__remove_type>::__type type; }; template class reference_wrapper; // Helper which adds a reference to a type when given a reference_wrapper template struct __strip_reference_wrapper { typedef _Tp __type; }; template struct __strip_reference_wrapper > { typedef _Tp& __type; }; template struct __decay_and_strip { typedef typename __strip_reference_wrapper< typename decay<_Tp>::type>::__type __type; }; // Primary template. /// Define a member typedef @c type only if a boolean constant is true. template struct enable_if { }; // Partial specialization for true. template struct enable_if { typedef _Tp type; }; template using _Require = typename enable_if<__and_<_Cond...>::value>::type; // Primary template. /// Define a member typedef @c type to one of two argument types. template struct conditional { typedef _Iftrue type; }; // Partial specialization for false. template struct conditional { typedef _Iffalse type; }; /// common_type template struct common_type; // Sfinae-friendly common_type implementation: struct __do_common_type_impl { template static __success_type() : std::declval<_Up>())>::type> _S_test(int); template static __failure_type _S_test(...); }; template struct __common_type_impl : private __do_common_type_impl { typedef decltype(_S_test<_Tp, _Up>(0)) type; }; struct __do_member_type_wrapper { template static __success_type _S_test(int); template static __failure_type _S_test(...); }; template struct __member_type_wrapper : private __do_member_type_wrapper { typedef decltype(_S_test<_Tp>(0)) type; }; template struct __expanded_common_type_wrapper { typedef common_type type; }; template struct __expanded_common_type_wrapper<__failure_type, _Args...> { typedef __failure_type type; }; template<> struct common_type<> { }; template struct common_type<_Tp> : common_type<_Tp, _Tp> { }; template struct common_type<_Tp, _Up> : public __common_type_impl<_Tp, _Up>::type { }; template struct common_type<_Tp, _Up, _Vp...> : public __expanded_common_type_wrapper>::type, _Vp...>::type { }; template::value> struct __underlying_type_impl { using type = __underlying_type(_Tp); }; template struct __underlying_type_impl<_Tp, false> { }; /// The underlying type of an enum. template struct underlying_type : public __underlying_type_impl<_Tp> { }; template struct __declval_protector { static const bool __stop = false; }; template auto declval() noexcept -> decltype(__declval<_Tp>(0)) { static_assert(__declval_protector<_Tp>::__stop, "declval() must not be used!"); return __declval<_Tp>(0); } // __remove_cvref_t (std::remove_cvref_t for C++11). template using __remove_cvref_t = typename remove_cv::type>::type; /// result_of template class result_of; // Sfinae-friendly result_of implementation: #define __cpp_lib_result_of_sfinae 201210 struct __invoke_memfun_ref { }; struct __invoke_memfun_deref { }; struct __invoke_memobj_ref { }; struct __invoke_memobj_deref { }; struct __invoke_other { }; // Associate a tag type with a specialization of __success_type. template struct __result_of_success : __success_type<_Tp> { using __invoke_type = _Tag; }; // [func.require] paragraph 1 bullet 1: struct __result_of_memfun_ref_impl { template static __result_of_success().*std::declval<_Fp>())(std::declval<_Args>()...) ), __invoke_memfun_ref> _S_test(int); template static __failure_type _S_test(...); }; template struct __result_of_memfun_ref : private __result_of_memfun_ref_impl { typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; }; // [func.require] paragraph 1 bullet 2: struct __result_of_memfun_deref_impl { template static __result_of_success()).*std::declval<_Fp>())(std::declval<_Args>()...) ), __invoke_memfun_deref> _S_test(int); template static __failure_type _S_test(...); }; template struct __result_of_memfun_deref : private __result_of_memfun_deref_impl { typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type; }; // [func.require] paragraph 1 bullet 3: struct __result_of_memobj_ref_impl { template static __result_of_success().*std::declval<_Fp>() ), __invoke_memobj_ref> _S_test(int); template static __failure_type _S_test(...); }; template struct __result_of_memobj_ref : private __result_of_memobj_ref_impl { typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; }; // [func.require] paragraph 1 bullet 4: struct __result_of_memobj_deref_impl { template static __result_of_success()).*std::declval<_Fp>() ), __invoke_memobj_deref> _S_test(int); template static __failure_type _S_test(...); }; template struct __result_of_memobj_deref : private __result_of_memobj_deref_impl { typedef decltype(_S_test<_MemPtr, _Arg>(0)) type; }; template struct __result_of_memobj; template struct __result_of_memobj<_Res _Class::*, _Arg> { typedef __remove_cvref_t<_Arg> _Argval; typedef _Res _Class::* _MemPtr; typedef typename conditional<__or_, is_base_of<_Class, _Argval>>::value, __result_of_memobj_ref<_MemPtr, _Arg>, __result_of_memobj_deref<_MemPtr, _Arg> >::type::type type; }; template struct __result_of_memfun; template struct __result_of_memfun<_Res _Class::*, _Arg, _Args...> { typedef typename remove_reference<_Arg>::type _Argval; typedef _Res _Class::* _MemPtr; typedef typename conditional::value, __result_of_memfun_ref<_MemPtr, _Arg, _Args...>, __result_of_memfun_deref<_MemPtr, _Arg, _Args...> >::type::type type; }; // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2219. INVOKE-ing a pointer to member with a reference_wrapper // as the object expression // Used by result_of, invoke etc. to unwrap a reference_wrapper. template> struct __inv_unwrap { using type = _Tp; }; template struct __inv_unwrap<_Tp, reference_wrapper<_Up>> { using type = _Up&; }; template struct __result_of_impl { typedef __failure_type type; }; template struct __result_of_impl : public __result_of_memobj::type, typename __inv_unwrap<_Arg>::type> { }; template struct __result_of_impl : public __result_of_memfun::type, typename __inv_unwrap<_Arg>::type, _Args...> { }; // [func.require] paragraph 1 bullet 5: struct __result_of_other_impl { template static __result_of_success()(std::declval<_Args>()...) ), __invoke_other> _S_test(int); template static __failure_type _S_test(...); }; template struct __result_of_impl : private __result_of_other_impl { typedef decltype(_S_test<_Functor, _ArgTypes...>(0)) type; }; // __invoke_result (std::invoke_result for C++11) template struct __invoke_result : public __result_of_impl< is_member_object_pointer< typename remove_reference<_Functor>::type >::value, is_member_function_pointer< typename remove_reference<_Functor>::type >::value, _Functor, _ArgTypes... >::type { }; template struct result_of<_Functor(_ArgTypes...)> : public __invoke_result<_Functor, _ArgTypes...> { }; #if __cplusplus >= 201402L /// Alias template for aligned_storage template::__type)> using aligned_storage_t = typename aligned_storage<_Len, _Align>::type; template using aligned_union_t = typename aligned_union<_Len, _Types...>::type; /// Alias template for decay template using decay_t = typename decay<_Tp>::type; /// Alias template for enable_if template using enable_if_t = typename enable_if<_Cond, _Tp>::type; /// Alias template for conditional template using conditional_t = typename conditional<_Cond, _Iftrue, _Iffalse>::type; /// Alias template for common_type template using common_type_t = typename common_type<_Tp...>::type; /// Alias template for underlying_type template using underlying_type_t = typename underlying_type<_Tp>::type; /// Alias template for result_of template using result_of_t = typename result_of<_Tp>::type; #endif // C++14 // __enable_if_t (std::enable_if_t for C++11) template using __enable_if_t = typename enable_if<_Cond, _Tp>::type; // __void_t (std::void_t for C++11) template using __void_t = void; #if __cplusplus >= 201703L || !defined(__STRICT_ANSI__) // c++17 or gnu++11 #define __cpp_lib_void_t 201411 /// A metafunction that always yields void, used for detecting valid types. template using void_t = void; #endif /// Implementation of the detection idiom (negative case). template class _Op, typename... _Args> struct __detector { using value_t = false_type; using type = _Default; }; /// Implementation of the detection idiom (positive case). template class _Op, typename... _Args> struct __detector<_Default, __void_t<_Op<_Args...>>, _Op, _Args...> { using value_t = true_type; using type = _Op<_Args...>; }; // Detect whether _Op<_Args...> is a valid type, use _Default if not. template class _Op, typename... _Args> using __detected_or = __detector<_Default, void, _Op, _Args...>; // _Op<_Args...> if that is a valid type, otherwise _Default. template class _Op, typename... _Args> using __detected_or_t = typename __detected_or<_Default, _Op, _Args...>::type; /// @} group metaprogramming /** * Use SFINAE to determine if the type _Tp has a publicly-accessible * member type _NTYPE. */ #define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \ template> \ struct __has_##_NTYPE \ : false_type \ { }; \ template \ struct __has_##_NTYPE<_Tp, __void_t> \ : true_type \ { }; template struct __is_swappable; template struct __is_nothrow_swappable; template class tuple; template struct __is_tuple_like_impl : false_type { }; template struct __is_tuple_like_impl> : true_type { }; // Internal type trait that allows us to sfinae-protect tuple_cat. template struct __is_tuple_like : public __is_tuple_like_impl<__remove_cvref_t<_Tp>>::type { }; template inline typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>, is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value>::type swap(_Tp&, _Tp&) noexcept(__and_, is_nothrow_move_assignable<_Tp>>::value); template inline typename enable_if<__is_swappable<_Tp>::value>::type swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]) noexcept(__is_nothrow_swappable<_Tp>::value); namespace __swappable_details { using std::swap; struct __do_is_swappable_impl { template(), std::declval<_Tp&>()))> static true_type __test(int); template static false_type __test(...); }; struct __do_is_nothrow_swappable_impl { template static __bool_constant< noexcept(swap(std::declval<_Tp&>(), std::declval<_Tp&>())) > __test(int); template static false_type __test(...); }; } // namespace __swappable_details template struct __is_swappable_impl : public __swappable_details::__do_is_swappable_impl { typedef decltype(__test<_Tp>(0)) type; }; template struct __is_nothrow_swappable_impl : public __swappable_details::__do_is_nothrow_swappable_impl { typedef decltype(__test<_Tp>(0)) type; }; template struct __is_swappable : public __is_swappable_impl<_Tp>::type { }; template struct __is_nothrow_swappable : public __is_nothrow_swappable_impl<_Tp>::type { }; #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 #define __cpp_lib_is_swappable 201603 /// Metafunctions used for detecting swappable types: p0185r1 /// is_swappable template struct is_swappable : public __is_swappable_impl<_Tp>::type { }; /// is_nothrow_swappable template struct is_nothrow_swappable : public __is_nothrow_swappable_impl<_Tp>::type { }; #if __cplusplus >= 201402L /// is_swappable_v template _GLIBCXX17_INLINE constexpr bool is_swappable_v = is_swappable<_Tp>::value; /// is_nothrow_swappable_v template _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value; #endif // __cplusplus >= 201402L namespace __swappable_with_details { using std::swap; struct __do_is_swappable_with_impl { template(), std::declval<_Up>())), typename = decltype(swap(std::declval<_Up>(), std::declval<_Tp>()))> static true_type __test(int); template static false_type __test(...); }; struct __do_is_nothrow_swappable_with_impl { template static __bool_constant< noexcept(swap(std::declval<_Tp>(), std::declval<_Up>())) && noexcept(swap(std::declval<_Up>(), std::declval<_Tp>())) > __test(int); template static false_type __test(...); }; } // namespace __swappable_with_details template struct __is_swappable_with_impl : public __swappable_with_details::__do_is_swappable_with_impl { typedef decltype(__test<_Tp, _Up>(0)) type; }; // Optimization for the homogenous lvalue case, not required: template struct __is_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_swappable_impl { typedef decltype(__test<_Tp&>(0)) type; }; template struct __is_nothrow_swappable_with_impl : public __swappable_with_details::__do_is_nothrow_swappable_with_impl { typedef decltype(__test<_Tp, _Up>(0)) type; }; // Optimization for the homogenous lvalue case, not required: template struct __is_nothrow_swappable_with_impl<_Tp&, _Tp&> : public __swappable_details::__do_is_nothrow_swappable_impl { typedef decltype(__test<_Tp&>(0)) type; }; /// is_swappable_with template struct is_swappable_with : public __is_swappable_with_impl<_Tp, _Up>::type { }; /// is_nothrow_swappable_with template struct is_nothrow_swappable_with : public __is_nothrow_swappable_with_impl<_Tp, _Up>::type { }; #if __cplusplus >= 201402L /// is_swappable_with_v template _GLIBCXX17_INLINE constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value; /// is_nothrow_swappable_with_v template _GLIBCXX17_INLINE constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_Tp, _Up>::value; #endif // __cplusplus >= 201402L #endif// c++1z or gnu++11 // __is_invocable (std::is_invocable for C++11) // The primary template is used for invalid INVOKE expressions. template::value, typename = void> struct __is_invocable_impl : false_type { }; // Used for valid INVOKE and INVOKE expressions. template struct __is_invocable_impl<_Result, _Ret, /* is_void<_Ret> = */ true, __void_t> : true_type { }; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wctor-dtor-privacy" // Used for INVOKE expressions to check the implicit conversion to R. template struct __is_invocable_impl<_Result, _Ret, /* is_void<_Ret> = */ false, __void_t> { private: // The type of the INVOKE expression. // Unlike declval, this doesn't add_rvalue_reference. static typename _Result::type _S_get(); template static void _S_conv(_Tp); // This overload is viable if INVOKE(f, args...) can convert to _Tp. template(_S_get()))> static true_type _S_test(int); template static false_type _S_test(...); public: using type = decltype(_S_test<_Ret>(1)); }; #pragma GCC diagnostic pop template struct __is_invocable : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type { }; template constexpr bool __call_is_nt(__invoke_memfun_ref) { using _Up = typename __inv_unwrap<_Tp>::type; return noexcept((std::declval<_Up>().*std::declval<_Fn>())( std::declval<_Args>()...)); } template constexpr bool __call_is_nt(__invoke_memfun_deref) { return noexcept(((*std::declval<_Tp>()).*std::declval<_Fn>())( std::declval<_Args>()...)); } template constexpr bool __call_is_nt(__invoke_memobj_ref) { using _Up = typename __inv_unwrap<_Tp>::type; return noexcept(std::declval<_Up>().*std::declval<_Fn>()); } template constexpr bool __call_is_nt(__invoke_memobj_deref) { return noexcept((*std::declval<_Tp>()).*std::declval<_Fn>()); } template constexpr bool __call_is_nt(__invoke_other) { return noexcept(std::declval<_Fn>()(std::declval<_Args>()...)); } template struct __call_is_nothrow : __bool_constant< std::__call_is_nt<_Fn, _Args...>(typename _Result::__invoke_type{}) > { }; template using __call_is_nothrow_ = __call_is_nothrow<__invoke_result<_Fn, _Args...>, _Fn, _Args...>; // __is_nothrow_invocable (std::is_nothrow_invocable for C++11) template struct __is_nothrow_invocable : __and_<__is_invocable<_Fn, _Args...>, __call_is_nothrow_<_Fn, _Args...>>::type { }; struct __nonesuch { __nonesuch() = delete; ~__nonesuch() = delete; __nonesuch(__nonesuch const&) = delete; void operator=(__nonesuch const&) = delete; }; #if __cplusplus >= 201703L # define __cpp_lib_is_invocable 201703 /// std::invoke_result template struct invoke_result : public __invoke_result<_Functor, _ArgTypes...> { }; /// std::invoke_result_t template using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; /// std::is_invocable template struct is_invocable : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type { }; /// std::is_invocable_r template struct is_invocable_r : __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>::type { }; /// std::is_nothrow_invocable template struct is_nothrow_invocable : __and_<__is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>, __call_is_nothrow_<_Fn, _ArgTypes...>>::type { }; template struct __is_nt_invocable_impl : false_type { }; template struct __is_nt_invocable_impl<_Result, _Ret, __void_t> : __or_, __and_, is_nothrow_constructible<_Ret, typename _Result::type>>> { }; /// std::is_nothrow_invocable_r template struct is_nothrow_invocable_r : __and_<__is_nt_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, _Ret>, __call_is_nothrow_<_Fn, _ArgTypes...>>::type { }; /// std::is_invocable_v template inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; /// std::is_nothrow_invocable_v template inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value; /// std::is_invocable_r_v template inline constexpr bool is_invocable_r_v = is_invocable_r<_Fn, _Args...>::value; /// std::is_nothrow_invocable_r_v template inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Fn, _Args...>::value; #endif // C++17 #if __cplusplus >= 201703L # define __cpp_lib_type_trait_variable_templates 201510L template inline constexpr bool is_void_v = is_void<_Tp>::value; template inline constexpr bool is_null_pointer_v = is_null_pointer<_Tp>::value; template inline constexpr bool is_integral_v = is_integral<_Tp>::value; template inline constexpr bool is_floating_point_v = is_floating_point<_Tp>::value; template inline constexpr bool is_array_v = is_array<_Tp>::value; template inline constexpr bool is_pointer_v = is_pointer<_Tp>::value; template inline constexpr bool is_lvalue_reference_v = is_lvalue_reference<_Tp>::value; template inline constexpr bool is_rvalue_reference_v = is_rvalue_reference<_Tp>::value; template inline constexpr bool is_member_object_pointer_v = is_member_object_pointer<_Tp>::value; template inline constexpr bool is_member_function_pointer_v = is_member_function_pointer<_Tp>::value; template inline constexpr bool is_enum_v = is_enum<_Tp>::value; template inline constexpr bool is_union_v = is_union<_Tp>::value; template inline constexpr bool is_class_v = is_class<_Tp>::value; template inline constexpr bool is_function_v = is_function<_Tp>::value; template inline constexpr bool is_reference_v = is_reference<_Tp>::value; template inline constexpr bool is_arithmetic_v = is_arithmetic<_Tp>::value; template inline constexpr bool is_fundamental_v = is_fundamental<_Tp>::value; template inline constexpr bool is_object_v = is_object<_Tp>::value; template inline constexpr bool is_scalar_v = is_scalar<_Tp>::value; template inline constexpr bool is_compound_v = is_compound<_Tp>::value; template inline constexpr bool is_member_pointer_v = is_member_pointer<_Tp>::value; template inline constexpr bool is_const_v = is_const<_Tp>::value; template inline constexpr bool is_volatile_v = is_volatile<_Tp>::value; template inline constexpr bool is_trivial_v = is_trivial<_Tp>::value; template inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<_Tp>::value; template inline constexpr bool is_standard_layout_v = is_standard_layout<_Tp>::value; template inline constexpr bool is_pod_v = is_pod<_Tp>::value; template inline constexpr bool is_literal_type_v = is_literal_type<_Tp>::value; template inline constexpr bool is_empty_v = is_empty<_Tp>::value; template inline constexpr bool is_polymorphic_v = is_polymorphic<_Tp>::value; template inline constexpr bool is_abstract_v = is_abstract<_Tp>::value; template inline constexpr bool is_final_v = is_final<_Tp>::value; template inline constexpr bool is_signed_v = is_signed<_Tp>::value; template inline constexpr bool is_unsigned_v = is_unsigned<_Tp>::value; template inline constexpr bool is_constructible_v = is_constructible<_Tp, _Args...>::value; template inline constexpr bool is_default_constructible_v = is_default_constructible<_Tp>::value; template inline constexpr bool is_copy_constructible_v = is_copy_constructible<_Tp>::value; template inline constexpr bool is_move_constructible_v = is_move_constructible<_Tp>::value; template inline constexpr bool is_assignable_v = is_assignable<_Tp, _Up>::value; template inline constexpr bool is_copy_assignable_v = is_copy_assignable<_Tp>::value; template inline constexpr bool is_move_assignable_v = is_move_assignable<_Tp>::value; template inline constexpr bool is_destructible_v = is_destructible<_Tp>::value; template inline constexpr bool is_trivially_constructible_v = is_trivially_constructible<_Tp, _Args...>::value; template inline constexpr bool is_trivially_default_constructible_v = is_trivially_default_constructible<_Tp>::value; template inline constexpr bool is_trivially_copy_constructible_v = is_trivially_copy_constructible<_Tp>::value; template inline constexpr bool is_trivially_move_constructible_v = is_trivially_move_constructible<_Tp>::value; template inline constexpr bool is_trivially_assignable_v = is_trivially_assignable<_Tp, _Up>::value; template inline constexpr bool is_trivially_copy_assignable_v = is_trivially_copy_assignable<_Tp>::value; template inline constexpr bool is_trivially_move_assignable_v = is_trivially_move_assignable<_Tp>::value; template inline constexpr bool is_trivially_destructible_v = is_trivially_destructible<_Tp>::value; template inline constexpr bool is_nothrow_constructible_v = is_nothrow_constructible<_Tp, _Args...>::value; template inline constexpr bool is_nothrow_default_constructible_v = is_nothrow_default_constructible<_Tp>::value; template inline constexpr bool is_nothrow_copy_constructible_v = is_nothrow_copy_constructible<_Tp>::value; template inline constexpr bool is_nothrow_move_constructible_v = is_nothrow_move_constructible<_Tp>::value; template inline constexpr bool is_nothrow_assignable_v = is_nothrow_assignable<_Tp, _Up>::value; template inline constexpr bool is_nothrow_copy_assignable_v = is_nothrow_copy_assignable<_Tp>::value; template inline constexpr bool is_nothrow_move_assignable_v = is_nothrow_move_assignable<_Tp>::value; template inline constexpr bool is_nothrow_destructible_v = is_nothrow_destructible<_Tp>::value; template inline constexpr bool has_virtual_destructor_v = has_virtual_destructor<_Tp>::value; template inline constexpr size_t alignment_of_v = alignment_of<_Tp>::value; template inline constexpr size_t rank_v = rank<_Tp>::value; template inline constexpr size_t extent_v = extent<_Tp, _Idx>::value; template inline constexpr bool is_same_v = is_same<_Tp, _Up>::value; template inline constexpr bool is_base_of_v = is_base_of<_Base, _Derived>::value; template inline constexpr bool is_convertible_v = is_convertible<_From, _To>::value; #ifdef _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP # define __cpp_lib_has_unique_object_representations 201606 /// has_unique_object_representations template struct has_unique_object_representations : bool_constant<__has_unique_object_representations( remove_cv_t> )> { }; template inline constexpr bool has_unique_object_representations_v = has_unique_object_representations<_Tp>::value; #endif #ifdef _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE # define __cpp_lib_is_aggregate 201703 /// is_aggregate template struct is_aggregate : bool_constant<__is_aggregate(remove_cv_t<_Tp>)> { }; /// is_aggregate_v template inline constexpr bool is_aggregate_v = is_aggregate<_Tp>::value; #endif #endif // C++17 #if __cplusplus > 201703L /// Remove references and cv-qualifiers. template struct remove_cvref { using type = __remove_cvref_t<_Tp>; }; template using remove_cvref_t = __remove_cvref_t<_Tp>; /// Identity metafunction. template struct type_identity { using type = _Tp; }; template using type_identity_t = typename type_identity<_Tp>::type; /// Unwrap a reference_wrapper template struct unwrap_reference { using type = _Tp; }; template struct unwrap_reference> { using type = _Tp&; }; template using unwrap_reference_t = typename unwrap_reference<_Tp>::type; /// Decay type and if it's a reference_wrapper, unwrap it template struct unwrap_ref_decay { using type = unwrap_reference_t>; }; template using unwrap_ref_decay_t = typename unwrap_ref_decay<_Tp>::type; #define __cpp_lib_bounded_array_traits 201902L /// True for a type that is an array of known bound. template struct is_bounded_array : public __is_array_known_bounds<_Tp> { }; /// True for a type that is an array of unknown bound. template struct is_unbounded_array : public __is_array_unknown_bounds<_Tp> { }; template inline constexpr bool is_bounded_array_v = is_bounded_array<_Tp>::value; template inline constexpr bool is_unbounded_array_v = is_unbounded_array<_Tp>::value; #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED #define __cpp_lib_is_constant_evaluated 201811L constexpr inline bool is_constant_evaluated() noexcept { return __builtin_is_constant_evaluated(); } #endif #endif // C++2a _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // C++11 #endif // _GLIBCXX_TYPE_TRAITS