13e519524SHoward Hinnant// -*- C++ -*- 2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===// 33e519524SHoward Hinnant// 457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 73e519524SHoward Hinnant// 83e519524SHoward Hinnant//===----------------------------------------------------------------------===// 93e519524SHoward Hinnant 103e519524SHoward Hinnant#ifndef _LIBCPP_TYPE_TRAITS 113e519524SHoward Hinnant#define _LIBCPP_TYPE_TRAITS 123e519524SHoward Hinnant 133e519524SHoward Hinnant/* 143e519524SHoward Hinnant type_traits synopsis 153e519524SHoward Hinnant 163e519524SHoward Hinnantnamespace std 173e519524SHoward Hinnant{ 183e519524SHoward Hinnant 193e519524SHoward Hinnant // helper class: 203e519524SHoward Hinnant template <class T, T v> struct integral_constant; 21cd6615fdSMarshall Clow typedef integral_constant<bool, true> true_type; // C++11 22cd6615fdSMarshall Clow typedef integral_constant<bool, false> false_type; // C++11 23cd6615fdSMarshall Clow 24cd6615fdSMarshall Clow template <bool B> // C++14 25cd6615fdSMarshall Clow using bool_constant = integral_constant<bool, B>; // C++14 26cd6615fdSMarshall Clow typedef bool_constant<true> true_type; // C++14 27cd6615fdSMarshall Clow typedef bool_constant<false> false_type; // C++14 283e519524SHoward Hinnant 293e519524SHoward Hinnant // helper traits 303e519524SHoward Hinnant template <bool, class T = void> struct enable_if; 313e519524SHoward Hinnant template <bool, class T, class F> struct conditional; 323e519524SHoward Hinnant 333e519524SHoward Hinnant // Primary classification traits: 343e519524SHoward Hinnant template <class T> struct is_void; 35dbd2ebb0SMarshall Clow template <class T> struct is_null_pointer; // C++14 363e519524SHoward Hinnant template <class T> struct is_integral; 373e519524SHoward Hinnant template <class T> struct is_floating_point; 383e519524SHoward Hinnant template <class T> struct is_array; 393e519524SHoward Hinnant template <class T> struct is_pointer; 403e519524SHoward Hinnant template <class T> struct is_lvalue_reference; 413e519524SHoward Hinnant template <class T> struct is_rvalue_reference; 423e519524SHoward Hinnant template <class T> struct is_member_object_pointer; 433e519524SHoward Hinnant template <class T> struct is_member_function_pointer; 443e519524SHoward Hinnant template <class T> struct is_enum; 453e519524SHoward Hinnant template <class T> struct is_union; 463e519524SHoward Hinnant template <class T> struct is_class; 473e519524SHoward Hinnant template <class T> struct is_function; 483e519524SHoward Hinnant 493e519524SHoward Hinnant // Secondary classification traits: 503e519524SHoward Hinnant template <class T> struct is_reference; 513e519524SHoward Hinnant template <class T> struct is_arithmetic; 523e519524SHoward Hinnant template <class T> struct is_fundamental; 533e519524SHoward Hinnant template <class T> struct is_member_pointer; 541f125015SMarek Kurdej template <class T> struct is_scoped_enum; // C++2b 553e519524SHoward Hinnant template <class T> struct is_scalar; 563e519524SHoward Hinnant template <class T> struct is_object; 573e519524SHoward Hinnant template <class T> struct is_compound; 583e519524SHoward Hinnant 593e519524SHoward Hinnant // Const-volatile properties and transformations: 603e519524SHoward Hinnant template <class T> struct is_const; 613e519524SHoward Hinnant template <class T> struct is_volatile; 623e519524SHoward Hinnant template <class T> struct remove_const; 633e519524SHoward Hinnant template <class T> struct remove_volatile; 643e519524SHoward Hinnant template <class T> struct remove_cv; 653e519524SHoward Hinnant template <class T> struct add_const; 663e519524SHoward Hinnant template <class T> struct add_volatile; 673e519524SHoward Hinnant template <class T> struct add_cv; 683e519524SHoward Hinnant 693e519524SHoward Hinnant // Reference transformations: 703e519524SHoward Hinnant template <class T> struct remove_reference; 713e519524SHoward Hinnant template <class T> struct add_lvalue_reference; 723e519524SHoward Hinnant template <class T> struct add_rvalue_reference; 733e519524SHoward Hinnant 743e519524SHoward Hinnant // Pointer transformations: 753e519524SHoward Hinnant template <class T> struct remove_pointer; 763e519524SHoward Hinnant template <class T> struct add_pointer; 773e519524SHoward Hinnant 78cf49ccd0SMarshall Clow template<class T> struct type_identity; // C++20 79cf49ccd0SMarshall Clow template<class T> 80cf49ccd0SMarshall Clow using type_identity_t = typename type_identity<T>::type; // C++20 81cf49ccd0SMarshall Clow 823e519524SHoward Hinnant // Integral properties: 833e519524SHoward Hinnant template <class T> struct is_signed; 843e519524SHoward Hinnant template <class T> struct is_unsigned; 853e519524SHoward Hinnant template <class T> struct make_signed; 863e519524SHoward Hinnant template <class T> struct make_unsigned; 873e519524SHoward Hinnant 883e519524SHoward Hinnant // Array properties and transformations: 893e519524SHoward Hinnant template <class T> struct rank; 903e519524SHoward Hinnant template <class T, unsigned I = 0> struct extent; 913e519524SHoward Hinnant template <class T> struct remove_extent; 923e519524SHoward Hinnant template <class T> struct remove_all_extents; 933e519524SHoward Hinnant 9446c719ddSMarshall Clow template <class T> struct is_bounded_array; // C++20 9546c719ddSMarshall Clow template <class T> struct is_unbounded_array; // C++20 9646c719ddSMarshall Clow 973e519524SHoward Hinnant // Member introspection: 983e519524SHoward Hinnant template <class T> struct is_pod; 993e519524SHoward Hinnant template <class T> struct is_trivial; 1003e519524SHoward Hinnant template <class T> struct is_trivially_copyable; 1013e519524SHoward Hinnant template <class T> struct is_standard_layout; 1022ff5a56eSwmbat template <class T> struct is_literal_type; // Deprecated in C++17; removed in C++20 1033e519524SHoward Hinnant template <class T> struct is_empty; 1043e519524SHoward Hinnant template <class T> struct is_polymorphic; 1053e519524SHoward Hinnant template <class T> struct is_abstract; 10639bca1eaSMarshall Clow template <class T> struct is_final; // C++14 107da04d79aSEric Fiselier template <class T> struct is_aggregate; // C++17 10810b9b7b4SHoward Hinnant 1093e519524SHoward Hinnant template <class T, class... Args> struct is_constructible; 110ca740483SHoward Hinnant template <class T> struct is_default_constructible; 111ca740483SHoward Hinnant template <class T> struct is_copy_constructible; 112ca740483SHoward Hinnant template <class T> struct is_move_constructible; 113ca740483SHoward Hinnant template <class T, class U> struct is_assignable; 114ca740483SHoward Hinnant template <class T> struct is_copy_assignable; 115ca740483SHoward Hinnant template <class T> struct is_move_assignable; 116f07dd8d0SEric Fiselier template <class T, class U> struct is_swappable_with; // C++17 117f07dd8d0SEric Fiselier template <class T> struct is_swappable; // C++17 118ca740483SHoward Hinnant template <class T> struct is_destructible; 119ca740483SHoward Hinnant 120ca740483SHoward Hinnant template <class T, class... Args> struct is_trivially_constructible; 121ca740483SHoward Hinnant template <class T> struct is_trivially_default_constructible; 122ca740483SHoward Hinnant template <class T> struct is_trivially_copy_constructible; 123ca740483SHoward Hinnant template <class T> struct is_trivially_move_constructible; 124ca740483SHoward Hinnant template <class T, class U> struct is_trivially_assignable; 125ca740483SHoward Hinnant template <class T> struct is_trivially_copy_assignable; 126ca740483SHoward Hinnant template <class T> struct is_trivially_move_assignable; 127ca740483SHoward Hinnant template <class T> struct is_trivially_destructible; 128ca740483SHoward Hinnant 1293e519524SHoward Hinnant template <class T, class... Args> struct is_nothrow_constructible; 130ca740483SHoward Hinnant template <class T> struct is_nothrow_default_constructible; 131ca740483SHoward Hinnant template <class T> struct is_nothrow_copy_constructible; 132ca740483SHoward Hinnant template <class T> struct is_nothrow_move_constructible; 133ca740483SHoward Hinnant template <class T, class U> struct is_nothrow_assignable; 134ca740483SHoward Hinnant template <class T> struct is_nothrow_copy_assignable; 135ca740483SHoward Hinnant template <class T> struct is_nothrow_move_assignable; 136f07dd8d0SEric Fiselier template <class T, class U> struct is_nothrow_swappable_with; // C++17 137f07dd8d0SEric Fiselier template <class T> struct is_nothrow_swappable; // C++17 138ca740483SHoward Hinnant template <class T> struct is_nothrow_destructible; 13910b9b7b4SHoward Hinnant 1403e519524SHoward Hinnant template <class T> struct has_virtual_destructor; 1413e519524SHoward Hinnant 142dd74d83fSMarshall Clow template<class T> struct has_unique_object_representations; // C++17 143dd74d83fSMarshall Clow 1443e519524SHoward Hinnant // Relationships between types: 1453e519524SHoward Hinnant template <class T, class U> struct is_same; 1463e519524SHoward Hinnant template <class Base, class Derived> struct is_base_of; 147ab19068bSLouis Dionne 1483e519524SHoward Hinnant template <class From, class To> struct is_convertible; 149ab19068bSLouis Dionne template <typename From, typename To> struct is_nothrow_convertible; // C++20 150ab19068bSLouis Dionne template <typename From, typename To> inline constexpr bool is_nothrow_convertible_v; // C++20 1513e519524SHoward Hinnant 152bcde6e71SZhihao Yuan template <class Fn, class... ArgTypes> struct is_invocable; 153bcde6e71SZhihao Yuan template <class R, class Fn, class... ArgTypes> struct is_invocable_r; 154840fa745SEric Fiselier 155bcde6e71SZhihao Yuan template <class Fn, class... ArgTypes> struct is_nothrow_invocable; 156bcde6e71SZhihao Yuan template <class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r; 157840fa745SEric Fiselier 1583e519524SHoward Hinnant // Alignment properties and transformations: 1593e519524SHoward Hinnant template <class T> struct alignment_of; 1603e519524SHoward Hinnant template <size_t Len, size_t Align = most_stringent_alignment_requirement> 1613e519524SHoward Hinnant struct aligned_storage; 16220428e94SHoward Hinnant template <size_t Len, class... Types> struct aligned_union; 163fbb0a5aaSMarshall Clow template <class T> struct remove_cvref; // C++20 1643e519524SHoward Hinnant 1653e519524SHoward Hinnant template <class T> struct decay; 1663e519524SHoward Hinnant template <class... T> struct common_type; 1673e519524SHoward Hinnant template <class T> struct underlying_type; 1682ff5a56eSwmbat template <class> class result_of; // undefined; deprecated in C++17; removed in C++20 1692ff5a56eSwmbat template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>; // deprecated in C++17; removed in C++20 170bcde6e71SZhihao Yuan template <class Fn, class... ArgTypes> struct invoke_result; // C++17 1713e519524SHoward Hinnant 1725b2ef2b1SMarshall Clow // const-volatile modifications: 1735b2ef2b1SMarshall Clow template <class T> 1745b2ef2b1SMarshall Clow using remove_const_t = typename remove_const<T>::type; // C++14 1755b2ef2b1SMarshall Clow template <class T> 1765b2ef2b1SMarshall Clow using remove_volatile_t = typename remove_volatile<T>::type; // C++14 1775b2ef2b1SMarshall Clow template <class T> 1785b2ef2b1SMarshall Clow using remove_cv_t = typename remove_cv<T>::type; // C++14 1795b2ef2b1SMarshall Clow template <class T> 1805b2ef2b1SMarshall Clow using add_const_t = typename add_const<T>::type; // C++14 1815b2ef2b1SMarshall Clow template <class T> 1825b2ef2b1SMarshall Clow using add_volatile_t = typename add_volatile<T>::type; // C++14 1835b2ef2b1SMarshall Clow template <class T> 1845b2ef2b1SMarshall Clow using add_cv_t = typename add_cv<T>::type; // C++14 1855b2ef2b1SMarshall Clow 1865b2ef2b1SMarshall Clow // reference modifications: 1875b2ef2b1SMarshall Clow template <class T> 1885b2ef2b1SMarshall Clow using remove_reference_t = typename remove_reference<T>::type; // C++14 1895b2ef2b1SMarshall Clow template <class T> 1905b2ef2b1SMarshall Clow using add_lvalue_reference_t = typename add_lvalue_reference<T>::type; // C++14 1915b2ef2b1SMarshall Clow template <class T> 1925b2ef2b1SMarshall Clow using add_rvalue_reference_t = typename add_rvalue_reference<T>::type; // C++14 1935b2ef2b1SMarshall Clow 1945b2ef2b1SMarshall Clow // sign modifications: 1955b2ef2b1SMarshall Clow template <class T> 1965b2ef2b1SMarshall Clow using make_signed_t = typename make_signed<T>::type; // C++14 1975b2ef2b1SMarshall Clow template <class T> 1985b2ef2b1SMarshall Clow using make_unsigned_t = typename make_unsigned<T>::type; // C++14 1995b2ef2b1SMarshall Clow 2005b2ef2b1SMarshall Clow // array modifications: 2015b2ef2b1SMarshall Clow template <class T> 2025b2ef2b1SMarshall Clow using remove_extent_t = typename remove_extent<T>::type; // C++14 2035b2ef2b1SMarshall Clow template <class T> 2045b2ef2b1SMarshall Clow using remove_all_extents_t = typename remove_all_extents<T>::type; // C++14 2055b2ef2b1SMarshall Clow 20646c719ddSMarshall Clow template <class T> 20746c719ddSMarshall Clow inline constexpr bool is_bounded_array_v 20846c719ddSMarshall Clow = is_bounded_array<T>::value; // C++20 20946c719ddSMarshall Clow inline constexpr bool is_unbounded_array_v 21046c719ddSMarshall Clow = is_unbounded_array<T>::value; // C++20 21146c719ddSMarshall Clow 2125b2ef2b1SMarshall Clow // pointer modifications: 2135b2ef2b1SMarshall Clow template <class T> 2145b2ef2b1SMarshall Clow using remove_pointer_t = typename remove_pointer<T>::type; // C++14 2155b2ef2b1SMarshall Clow template <class T> 2165b2ef2b1SMarshall Clow using add_pointer_t = typename add_pointer<T>::type; // C++14 2175b2ef2b1SMarshall Clow 2185b2ef2b1SMarshall Clow // other transformations: 2190b8da5faSArthur O'Dwyer template <size_t Len, size_t Align=default-alignment> 2205b2ef2b1SMarshall Clow using aligned_storage_t = typename aligned_storage<Len,Align>::type; // C++14 2210b8da5faSArthur O'Dwyer template <size_t Len, class... Types> 2225b2ef2b1SMarshall Clow using aligned_union_t = typename aligned_union<Len,Types...>::type; // C++14 2235b2ef2b1SMarshall Clow template <class T> 224fbb0a5aaSMarshall Clow using remove_cvref_t = typename remove_cvref<T>::type; // C++20 225fbb0a5aaSMarshall Clow template <class T> 2265b2ef2b1SMarshall Clow using decay_t = typename decay<T>::type; // C++14 2275b2ef2b1SMarshall Clow template <bool b, class T=void> 2285b2ef2b1SMarshall Clow using enable_if_t = typename enable_if<b,T>::type; // C++14 2295b2ef2b1SMarshall Clow template <bool b, class T, class F> 2305b2ef2b1SMarshall Clow using conditional_t = typename conditional<b,T,F>::type; // C++14 2315b2ef2b1SMarshall Clow template <class... T> 2325b2ef2b1SMarshall Clow using common_type_t = typename common_type<T...>::type; // C++14 2335b2ef2b1SMarshall Clow template <class T> 2345b2ef2b1SMarshall Clow using underlying_type_t = typename underlying_type<T>::type; // C++14 235bcde6e71SZhihao Yuan template <class T> 2362ff5a56eSwmbat using result_of_t = typename result_of<T>::type; // C++14; deprecated in C++17; removed in C++20 237bcde6e71SZhihao Yuan template <class Fn, class... ArgTypes> 238bcde6e71SZhihao Yuan using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type; // C++17 2395b2ef2b1SMarshall Clow 2403687d3c2SMarshall Clow template <class...> 241dd0ef099SMarshall Clow using void_t = void; // C++17 242dd0ef099SMarshall Clow 243dd0ef099SMarshall Clow // See C++14 20.10.4.1, primary type categories 24440a01d53SMarshall Clow template <class T> inline constexpr bool is_void_v 245dd0ef099SMarshall Clow = is_void<T>::value; // C++17 24640a01d53SMarshall Clow template <class T> inline constexpr bool is_null_pointer_v 247dd0ef099SMarshall Clow = is_null_pointer<T>::value; // C++17 24840a01d53SMarshall Clow template <class T> inline constexpr bool is_integral_v 249dd0ef099SMarshall Clow = is_integral<T>::value; // C++17 25040a01d53SMarshall Clow template <class T> inline constexpr bool is_floating_point_v 251dd0ef099SMarshall Clow = is_floating_point<T>::value; // C++17 25240a01d53SMarshall Clow template <class T> inline constexpr bool is_array_v 253dd0ef099SMarshall Clow = is_array<T>::value; // C++17 25440a01d53SMarshall Clow template <class T> inline constexpr bool is_pointer_v 255dd0ef099SMarshall Clow = is_pointer<T>::value; // C++17 25640a01d53SMarshall Clow template <class T> inline constexpr bool is_lvalue_reference_v 257dd0ef099SMarshall Clow = is_lvalue_reference<T>::value; // C++17 25840a01d53SMarshall Clow template <class T> inline constexpr bool is_rvalue_reference_v 259dd0ef099SMarshall Clow = is_rvalue_reference<T>::value; // C++17 26040a01d53SMarshall Clow template <class T> inline constexpr bool is_member_object_pointer_v 261dd0ef099SMarshall Clow = is_member_object_pointer<T>::value; // C++17 26240a01d53SMarshall Clow template <class T> inline constexpr bool is_member_function_pointer_v 263dd0ef099SMarshall Clow = is_member_function_pointer<T>::value; // C++17 26440a01d53SMarshall Clow template <class T> inline constexpr bool is_enum_v 265dd0ef099SMarshall Clow = is_enum<T>::value; // C++17 26640a01d53SMarshall Clow template <class T> inline constexpr bool is_union_v 267dd0ef099SMarshall Clow = is_union<T>::value; // C++17 26840a01d53SMarshall Clow template <class T> inline constexpr bool is_class_v 269dd0ef099SMarshall Clow = is_class<T>::value; // C++17 27040a01d53SMarshall Clow template <class T> inline constexpr bool is_function_v 271dd0ef099SMarshall Clow = is_function<T>::value; // C++17 272dd0ef099SMarshall Clow 273dd0ef099SMarshall Clow // See C++14 20.10.4.2, composite type categories 27440a01d53SMarshall Clow template <class T> inline constexpr bool is_reference_v 275dd0ef099SMarshall Clow = is_reference<T>::value; // C++17 27640a01d53SMarshall Clow template <class T> inline constexpr bool is_arithmetic_v 277dd0ef099SMarshall Clow = is_arithmetic<T>::value; // C++17 27840a01d53SMarshall Clow template <class T> inline constexpr bool is_fundamental_v 279dd0ef099SMarshall Clow = is_fundamental<T>::value; // C++17 28040a01d53SMarshall Clow template <class T> inline constexpr bool is_object_v 281dd0ef099SMarshall Clow = is_object<T>::value; // C++17 28240a01d53SMarshall Clow template <class T> inline constexpr bool is_scalar_v 283dd0ef099SMarshall Clow = is_scalar<T>::value; // C++17 28440a01d53SMarshall Clow template <class T> inline constexpr bool is_compound_v 285dd0ef099SMarshall Clow = is_compound<T>::value; // C++17 28640a01d53SMarshall Clow template <class T> inline constexpr bool is_member_pointer_v 287dd0ef099SMarshall Clow = is_member_pointer<T>::value; // C++17 2881f125015SMarek Kurdej template <class T> inline constexpr bool is_scoped_enum_v 2891f125015SMarek Kurdej = is_scoped_enum<T>::value; // C++2b 290dd0ef099SMarshall Clow 291dd0ef099SMarshall Clow // See C++14 20.10.4.3, type properties 29240a01d53SMarshall Clow template <class T> inline constexpr bool is_const_v 293dd0ef099SMarshall Clow = is_const<T>::value; // C++17 29440a01d53SMarshall Clow template <class T> inline constexpr bool is_volatile_v 295dd0ef099SMarshall Clow = is_volatile<T>::value; // C++17 29640a01d53SMarshall Clow template <class T> inline constexpr bool is_trivial_v 297dd0ef099SMarshall Clow = is_trivial<T>::value; // C++17 29840a01d53SMarshall Clow template <class T> inline constexpr bool is_trivially_copyable_v 299dd0ef099SMarshall Clow = is_trivially_copyable<T>::value; // C++17 30040a01d53SMarshall Clow template <class T> inline constexpr bool is_standard_layout_v 301dd0ef099SMarshall Clow = is_standard_layout<T>::value; // C++17 30240a01d53SMarshall Clow template <class T> inline constexpr bool is_pod_v 303dd0ef099SMarshall Clow = is_pod<T>::value; // C++17 30440a01d53SMarshall Clow template <class T> inline constexpr bool is_literal_type_v 3052ff5a56eSwmbat = is_literal_type<T>::value; // C++17; deprecated in C++17; removed in C++20 30640a01d53SMarshall Clow template <class T> inline constexpr bool is_empty_v 307dd0ef099SMarshall Clow = is_empty<T>::value; // C++17 30840a01d53SMarshall Clow template <class T> inline constexpr bool is_polymorphic_v 309dd0ef099SMarshall Clow = is_polymorphic<T>::value; // C++17 31040a01d53SMarshall Clow template <class T> inline constexpr bool is_abstract_v 311dd0ef099SMarshall Clow = is_abstract<T>::value; // C++17 31240a01d53SMarshall Clow template <class T> inline constexpr bool is_final_v 313dd0ef099SMarshall Clow = is_final<T>::value; // C++17 31440a01d53SMarshall Clow template <class T> inline constexpr bool is_aggregate_v 315da04d79aSEric Fiselier = is_aggregate<T>::value; // C++17 31640a01d53SMarshall Clow template <class T> inline constexpr bool is_signed_v 317dd0ef099SMarshall Clow = is_signed<T>::value; // C++17 31840a01d53SMarshall Clow template <class T> inline constexpr bool is_unsigned_v 319dd0ef099SMarshall Clow = is_unsigned<T>::value; // C++17 32040a01d53SMarshall Clow template <class T, class... Args> inline constexpr bool is_constructible_v 321dd0ef099SMarshall Clow = is_constructible<T, Args...>::value; // C++17 32240a01d53SMarshall Clow template <class T> inline constexpr bool is_default_constructible_v 323dd0ef099SMarshall Clow = is_default_constructible<T>::value; // C++17 32440a01d53SMarshall Clow template <class T> inline constexpr bool is_copy_constructible_v 325dd0ef099SMarshall Clow = is_copy_constructible<T>::value; // C++17 32640a01d53SMarshall Clow template <class T> inline constexpr bool is_move_constructible_v 327dd0ef099SMarshall Clow = is_move_constructible<T>::value; // C++17 32840a01d53SMarshall Clow template <class T, class U> inline constexpr bool is_assignable_v 329dd0ef099SMarshall Clow = is_assignable<T, U>::value; // C++17 33040a01d53SMarshall Clow template <class T> inline constexpr bool is_copy_assignable_v 331dd0ef099SMarshall Clow = is_copy_assignable<T>::value; // C++17 33240a01d53SMarshall Clow template <class T> inline constexpr bool is_move_assignable_v 333dd0ef099SMarshall Clow = is_move_assignable<T>::value; // C++17 33440a01d53SMarshall Clow template <class T, class U> inline constexpr bool is_swappable_with_v 335f07dd8d0SEric Fiselier = is_swappable_with<T, U>::value; // C++17 33640a01d53SMarshall Clow template <class T> inline constexpr bool is_swappable_v 337f07dd8d0SEric Fiselier = is_swappable<T>::value; // C++17 33840a01d53SMarshall Clow template <class T> inline constexpr bool is_destructible_v 339dd0ef099SMarshall Clow = is_destructible<T>::value; // C++17 34040a01d53SMarshall Clow template <class T, class... Args> inline constexpr bool is_trivially_constructible_v 341dd0ef099SMarshall Clow = is_trivially_constructible<T, Args...>::value; // C++17 34240a01d53SMarshall Clow template <class T> inline constexpr bool is_trivially_default_constructible_v 343dd0ef099SMarshall Clow = is_trivially_default_constructible<T>::value; // C++17 34440a01d53SMarshall Clow template <class T> inline constexpr bool is_trivially_copy_constructible_v 345dd0ef099SMarshall Clow = is_trivially_copy_constructible<T>::value; // C++17 34640a01d53SMarshall Clow template <class T> inline constexpr bool is_trivially_move_constructible_v 347dd0ef099SMarshall Clow = is_trivially_move_constructible<T>::value; // C++17 34840a01d53SMarshall Clow template <class T, class U> inline constexpr bool is_trivially_assignable_v 349dd0ef099SMarshall Clow = is_trivially_assignable<T, U>::value; // C++17 35040a01d53SMarshall Clow template <class T> inline constexpr bool is_trivially_copy_assignable_v 351dd0ef099SMarshall Clow = is_trivially_copy_assignable<T>::value; // C++17 35240a01d53SMarshall Clow template <class T> inline constexpr bool is_trivially_move_assignable_v 353dd0ef099SMarshall Clow = is_trivially_move_assignable<T>::value; // C++17 35440a01d53SMarshall Clow template <class T> inline constexpr bool is_trivially_destructible_v 355dd0ef099SMarshall Clow = is_trivially_destructible<T>::value; // C++17 35640a01d53SMarshall Clow template <class T, class... Args> inline constexpr bool is_nothrow_constructible_v 357dd0ef099SMarshall Clow = is_nothrow_constructible<T, Args...>::value; // C++17 35840a01d53SMarshall Clow template <class T> inline constexpr bool is_nothrow_default_constructible_v 359dd0ef099SMarshall Clow = is_nothrow_default_constructible<T>::value; // C++17 36040a01d53SMarshall Clow template <class T> inline constexpr bool is_nothrow_copy_constructible_v 361dd0ef099SMarshall Clow = is_nothrow_copy_constructible<T>::value; // C++17 36240a01d53SMarshall Clow template <class T> inline constexpr bool is_nothrow_move_constructible_v 363dd0ef099SMarshall Clow = is_nothrow_move_constructible<T>::value; // C++17 36440a01d53SMarshall Clow template <class T, class U> inline constexpr bool is_nothrow_assignable_v 365dd0ef099SMarshall Clow = is_nothrow_assignable<T, U>::value; // C++17 36640a01d53SMarshall Clow template <class T> inline constexpr bool is_nothrow_copy_assignable_v 367dd0ef099SMarshall Clow = is_nothrow_copy_assignable<T>::value; // C++17 36840a01d53SMarshall Clow template <class T> inline constexpr bool is_nothrow_move_assignable_v 369dd0ef099SMarshall Clow = is_nothrow_move_assignable<T>::value; // C++17 37040a01d53SMarshall Clow template <class T, class U> inline constexpr bool is_nothrow_swappable_with_v 371f07dd8d0SEric Fiselier = is_nothrow_swappable_with<T, U>::value; // C++17 37240a01d53SMarshall Clow template <class T> inline constexpr bool is_nothrow_swappable_v 373f07dd8d0SEric Fiselier = is_nothrow_swappable<T>::value; // C++17 37440a01d53SMarshall Clow template <class T> inline constexpr bool is_nothrow_destructible_v 375dd0ef099SMarshall Clow = is_nothrow_destructible<T>::value; // C++17 37640a01d53SMarshall Clow template <class T> inline constexpr bool has_virtual_destructor_v 377dd0ef099SMarshall Clow = has_virtual_destructor<T>::value; // C++17 378dd74d83fSMarshall Clow template<class T> inline constexpr bool has_unique_object_representations_v // C++17 379dd74d83fSMarshall Clow = has_unique_object_representations<T>::value; 380dd0ef099SMarshall Clow 381dd0ef099SMarshall Clow // See C++14 20.10.5, type property queries 38240a01d53SMarshall Clow template <class T> inline constexpr size_t alignment_of_v 383dd0ef099SMarshall Clow = alignment_of<T>::value; // C++17 38440a01d53SMarshall Clow template <class T> inline constexpr size_t rank_v 385dd0ef099SMarshall Clow = rank<T>::value; // C++17 38640a01d53SMarshall Clow template <class T, unsigned I = 0> inline constexpr size_t extent_v 387dd0ef099SMarshall Clow = extent<T, I>::value; // C++17 388dd0ef099SMarshall Clow 389dd0ef099SMarshall Clow // See C++14 20.10.6, type relations 39040a01d53SMarshall Clow template <class T, class U> inline constexpr bool is_same_v 391dd0ef099SMarshall Clow = is_same<T, U>::value; // C++17 39240a01d53SMarshall Clow template <class Base, class Derived> inline constexpr bool is_base_of_v 393dd0ef099SMarshall Clow = is_base_of<Base, Derived>::value; // C++17 39440a01d53SMarshall Clow template <class From, class To> inline constexpr bool is_convertible_v 395dd0ef099SMarshall Clow = is_convertible<From, To>::value; // C++17 39640a01d53SMarshall Clow template <class Fn, class... ArgTypes> inline constexpr bool is_invocable_v 397bcde6e71SZhihao Yuan = is_invocable<Fn, ArgTypes...>::value; // C++17 39840a01d53SMarshall Clow template <class R, class Fn, class... ArgTypes> inline constexpr bool is_invocable_r_v 399bcde6e71SZhihao Yuan = is_invocable_r<R, Fn, ArgTypes...>::value; // C++17 40040a01d53SMarshall Clow template <class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_v 401bcde6e71SZhihao Yuan = is_nothrow_invocable<Fn, ArgTypes...>::value; // C++17 40240a01d53SMarshall Clow template <class R, class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_r_v 403bcde6e71SZhihao Yuan = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value; // C++17 404dd1b261fSMarshall Clow 405dd1b261fSMarshall Clow // [meta.logical], logical operator traits: 406dd1b261fSMarshall Clow template<class... B> struct conjunction; // C++17 407dd1b261fSMarshall Clow template<class... B> 40840a01d53SMarshall Clow inline constexpr bool conjunction_v = conjunction<B...>::value; // C++17 409dd1b261fSMarshall Clow template<class... B> struct disjunction; // C++17 410dd1b261fSMarshall Clow template<class... B> 41140a01d53SMarshall Clow inline constexpr bool disjunction_v = disjunction<B...>::value; // C++17 412dd1b261fSMarshall Clow template<class B> struct negation; // C++17 413dd1b261fSMarshall Clow template<class B> 41440a01d53SMarshall Clow inline constexpr bool negation_v = negation<B>::value; // C++17 415dd1b261fSMarshall Clow 416dd0ef099SMarshall Clow} 4173e519524SHoward Hinnant 4183e519524SHoward Hinnant*/ 419385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler 4203e519524SHoward Hinnant#include <__config> 4211972d1e8SNikolas Klauser#include <__functional/invoke.h> 42230c37fb8SNikolas Klauser#include <__type_traits/add_const.h> 42330c37fb8SNikolas Klauser#include <__type_traits/add_cv.h> 42430c37fb8SNikolas Klauser#include <__type_traits/add_lvalue_reference.h> 425eebc1fb7SNikolas Klauser#include <__type_traits/add_pointer.h> 42630c37fb8SNikolas Klauser#include <__type_traits/add_rvalue_reference.h> 42730c37fb8SNikolas Klauser#include <__type_traits/add_volatile.h> 428*b7aa9c4aSNikolas Klauser#include <__type_traits/aligned_storage.h> 429*b7aa9c4aSNikolas Klauser#include <__type_traits/aligned_union.h> 4301972d1e8SNikolas Klauser#include <__type_traits/alignment_of.h> 4311972d1e8SNikolas Klauser#include <__type_traits/apply_cv.h> 432*b7aa9c4aSNikolas Klauser#include <__type_traits/common_reference.h> 433*b7aa9c4aSNikolas Klauser#include <__type_traits/common_type.h> 434eebc1fb7SNikolas Klauser#include <__type_traits/conditional.h> 435a29a1a33SNikolas Klauser#include <__type_traits/conjunction.h> 436eebc1fb7SNikolas Klauser#include <__type_traits/decay.h> 437a29a1a33SNikolas Klauser#include <__type_traits/disjunction.h> 438eebc1fb7SNikolas Klauser#include <__type_traits/enable_if.h> 43930c37fb8SNikolas Klauser#include <__type_traits/extent.h> 4401972d1e8SNikolas Klauser#include <__type_traits/has_unique_object_representation.h> 4411972d1e8SNikolas Klauser#include <__type_traits/has_virtual_destructor.h> 44208920cc0SNikolas Klauser#include <__type_traits/integral_constant.h> 44330c37fb8SNikolas Klauser#include <__type_traits/is_abstract.h> 44430c37fb8SNikolas Klauser#include <__type_traits/is_aggregate.h> 44530c37fb8SNikolas Klauser#include <__type_traits/is_arithmetic.h> 446eebc1fb7SNikolas Klauser#include <__type_traits/is_array.h> 4471972d1e8SNikolas Klauser#include <__type_traits/is_assignable.h> 448eebc1fb7SNikolas Klauser#include <__type_traits/is_base_of.h> 44930c37fb8SNikolas Klauser#include <__type_traits/is_bounded_array.h> 45008920cc0SNikolas Klauser#include <__type_traits/is_callable.h> 45130c37fb8SNikolas Klauser#include <__type_traits/is_class.h> 45230c37fb8SNikolas Klauser#include <__type_traits/is_compound.h> 453eebc1fb7SNikolas Klauser#include <__type_traits/is_const.h> 4541972d1e8SNikolas Klauser#include <__type_traits/is_constant_evaluated.h> 4553abaefe6SNikolas Klauser#include <__type_traits/is_constructible.h> 456eebc1fb7SNikolas Klauser#include <__type_traits/is_convertible.h> 4571972d1e8SNikolas Klauser#include <__type_traits/is_copy_assignable.h> 4583abaefe6SNikolas Klauser#include <__type_traits/is_copy_constructible.h> 4593abaefe6SNikolas Klauser#include <__type_traits/is_default_constructible.h> 4603abaefe6SNikolas Klauser#include <__type_traits/is_destructible.h> 46130c37fb8SNikolas Klauser#include <__type_traits/is_empty.h> 46230c37fb8SNikolas Klauser#include <__type_traits/is_enum.h> 46330c37fb8SNikolas Klauser#include <__type_traits/is_final.h> 464eebc1fb7SNikolas Klauser#include <__type_traits/is_floating_point.h> 465eebc1fb7SNikolas Klauser#include <__type_traits/is_function.h> 46630c37fb8SNikolas Klauser#include <__type_traits/is_fundamental.h> 467eebc1fb7SNikolas Klauser#include <__type_traits/is_integral.h> 4681972d1e8SNikolas Klauser#include <__type_traits/is_literal_type.h> 469eebc1fb7SNikolas Klauser#include <__type_traits/is_member_function_pointer.h> 470eebc1fb7SNikolas Klauser#include <__type_traits/is_member_object_pointer.h> 47130c37fb8SNikolas Klauser#include <__type_traits/is_member_pointer.h> 4721972d1e8SNikolas Klauser#include <__type_traits/is_move_assignable.h> 4733abaefe6SNikolas Klauser#include <__type_traits/is_move_constructible.h> 4743abaefe6SNikolas Klauser#include <__type_traits/is_nothrow_assignable.h> 4753abaefe6SNikolas Klauser#include <__type_traits/is_nothrow_constructible.h> 476*b7aa9c4aSNikolas Klauser#include <__type_traits/is_nothrow_convertible.h> 4773abaefe6SNikolas Klauser#include <__type_traits/is_nothrow_copy_assignable.h> 4783abaefe6SNikolas Klauser#include <__type_traits/is_nothrow_copy_constructible.h> 4793abaefe6SNikolas Klauser#include <__type_traits/is_nothrow_default_constructible.h> 4803abaefe6SNikolas Klauser#include <__type_traits/is_nothrow_destructible.h> 4813abaefe6SNikolas Klauser#include <__type_traits/is_nothrow_move_assignable.h> 4823abaefe6SNikolas Klauser#include <__type_traits/is_nothrow_move_constructible.h> 483eebc1fb7SNikolas Klauser#include <__type_traits/is_null_pointer.h> 48430c37fb8SNikolas Klauser#include <__type_traits/is_object.h> 4851972d1e8SNikolas Klauser#include <__type_traits/is_pod.h> 48630c37fb8SNikolas Klauser#include <__type_traits/is_pointer.h> 4871972d1e8SNikolas Klauser#include <__type_traits/is_polymorphic.h> 488eebc1fb7SNikolas Klauser#include <__type_traits/is_reference.h> 489eebc1fb7SNikolas Klauser#include <__type_traits/is_reference_wrapper.h> 490eebc1fb7SNikolas Klauser#include <__type_traits/is_referenceable.h> 491eebc1fb7SNikolas Klauser#include <__type_traits/is_same.h> 49230c37fb8SNikolas Klauser#include <__type_traits/is_scalar.h> 4931972d1e8SNikolas Klauser#include <__type_traits/is_scoped_enum.h> 49430c37fb8SNikolas Klauser#include <__type_traits/is_signed.h> 4951972d1e8SNikolas Klauser#include <__type_traits/is_standard_layout.h> 4961972d1e8SNikolas Klauser#include <__type_traits/is_trivial.h> 4973abaefe6SNikolas Klauser#include <__type_traits/is_trivially_assignable.h> 4983abaefe6SNikolas Klauser#include <__type_traits/is_trivially_constructible.h> 4993abaefe6SNikolas Klauser#include <__type_traits/is_trivially_copy_assignable.h> 5003abaefe6SNikolas Klauser#include <__type_traits/is_trivially_copy_constructible.h> 5011972d1e8SNikolas Klauser#include <__type_traits/is_trivially_copyable.h> 5023abaefe6SNikolas Klauser#include <__type_traits/is_trivially_default_constructible.h> 5033abaefe6SNikolas Klauser#include <__type_traits/is_trivially_destructible.h> 5043abaefe6SNikolas Klauser#include <__type_traits/is_trivially_move_assignable.h> 5053abaefe6SNikolas Klauser#include <__type_traits/is_trivially_move_constructible.h> 50630c37fb8SNikolas Klauser#include <__type_traits/is_unbounded_array.h> 50730c37fb8SNikolas Klauser#include <__type_traits/is_union.h> 50830c37fb8SNikolas Klauser#include <__type_traits/is_unsigned.h> 509eebc1fb7SNikolas Klauser#include <__type_traits/is_void.h> 510eebc1fb7SNikolas Klauser#include <__type_traits/is_volatile.h> 511*b7aa9c4aSNikolas Klauser#include <__type_traits/make_signed.h> 512*b7aa9c4aSNikolas Klauser#include <__type_traits/make_unsigned.h> 5133abaefe6SNikolas Klauser#include <__type_traits/negation.h> 51430c37fb8SNikolas Klauser#include <__type_traits/rank.h> 51530c37fb8SNikolas Klauser#include <__type_traits/remove_all_extents.h> 516eebc1fb7SNikolas Klauser#include <__type_traits/remove_const.h> 517eebc1fb7SNikolas Klauser#include <__type_traits/remove_cv.h> 518eebc1fb7SNikolas Klauser#include <__type_traits/remove_extent.h> 51930c37fb8SNikolas Klauser#include <__type_traits/remove_pointer.h> 520eebc1fb7SNikolas Klauser#include <__type_traits/remove_reference.h> 521eebc1fb7SNikolas Klauser#include <__type_traits/remove_volatile.h> 52230c37fb8SNikolas Klauser#include <__type_traits/type_identity.h> 5231972d1e8SNikolas Klauser#include <__type_traits/underlying_type.h> 5243abaefe6SNikolas Klauser#include <__type_traits/void_t.h> 52508920cc0SNikolas Klauser#include <__utility/declval.h> 5263e519524SHoward Hinnant#include <cstddef> 527cf927669SMark de Wever#include <cstdint> 528f56972e2SMarshall Clow#include <version> 5293e519524SHoward Hinnant 530073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 5313e519524SHoward Hinnant# pragma GCC system_header 532073458b1SHoward Hinnant#endif 5333e519524SHoward Hinnant 5343e519524SHoward Hinnant_LIBCPP_BEGIN_NAMESPACE_STD 5353e519524SHoward Hinnant 536e2f2d1edSEric Fiseliertemplate <class _T1, class _T2> struct _LIBCPP_TEMPLATE_VIS pair; 537e2f2d1edSEric Fiseliertemplate <class _Tp> struct _LIBCPP_TEMPLATE_VIS hash; 538fa1f613fSEric Fiselier 53951a741c8SEric Fiselier// Member detector base 54051a741c8SEric Fiselier 54165500d4bSEric Fiseliertemplate <class _Tp, bool> 542e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS __dependent_type : public _Tp {}; 54365500d4bSEric Fiselier 5443e519524SHoward Hinnant// is_integral 5453e519524SHoward Hinnant 546c32ee047SEric Fiseliertemplate <class _Tp> 547c32ee047SEric Fiselierstruct __unconstref { 5483557c7c1SLouis Dionne typedef _LIBCPP_NODEBUG typename remove_const<typename remove_reference<_Tp>::type>::type type; 549c32ee047SEric Fiselier}; 550c32ee047SEric Fiselier 551e16f2cb6SLouis Dionne#ifndef _LIBCPP_CXX03_LANG 552e16f2cb6SLouis Dionne// First of all, we can't implement this check in C++03 mode because the {} 553e16f2cb6SLouis Dionne// default initialization syntax isn't valid. 554e16f2cb6SLouis Dionne// Second, we implement the trait in a funny manner with two defaulted template 555e16f2cb6SLouis Dionne// arguments to workaround Clang's PR43454. 556e16f2cb6SLouis Dionnetemplate <class _Tp> 557e16f2cb6SLouis Dionnevoid __test_implicit_default_constructible(_Tp); 558e16f2cb6SLouis Dionne 559a3ab5120SLouis Dionnetemplate <class _Tp, class = void, class = typename is_default_constructible<_Tp>::type> 560e16f2cb6SLouis Dionnestruct __is_implicitly_default_constructible 561e16f2cb6SLouis Dionne : false_type 562e16f2cb6SLouis Dionne{ }; 563e16f2cb6SLouis Dionne 564e16f2cb6SLouis Dionnetemplate <class _Tp> 565a3ab5120SLouis Dionnestruct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), true_type> 566e16f2cb6SLouis Dionne : true_type 567e16f2cb6SLouis Dionne{ }; 568e16f2cb6SLouis Dionne 569e16f2cb6SLouis Dionnetemplate <class _Tp> 570a3ab5120SLouis Dionnestruct __is_implicitly_default_constructible<_Tp, decltype(__test_implicit_default_constructible<_Tp const&>({})), false_type> 571e16f2cb6SLouis Dionne : false_type 572e16f2cb6SLouis Dionne{ }; 573e16f2cb6SLouis Dionne#endif // !C++03 574e16f2cb6SLouis Dionne 575840fa745SEric Fiselier// result_of 576840fa745SEric Fiselier 5772ff5a56eSwmbat#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) 5782ff5a56eSwmbattemplate <class _Callable> class _LIBCPP_DEPRECATED_IN_CXX17 result_of; 579a3c28ccdSLouis Dionne 580f08ebab2SHoward Hinnanttemplate <class _Fp, class ..._Args> 581e2f2d1edSEric Fiselierclass _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)> 582f08ebab2SHoward Hinnant : public __invoke_of<_Fp, _Args...> 583f08ebab2SHoward Hinnant{ 584f08ebab2SHoward Hinnant}; 585f08ebab2SHoward Hinnant 5865b2ef2b1SMarshall Clow#if _LIBCPP_STD_VER > 11 5872ff5a56eSwmbattemplate <class _Tp> using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type; 5882ff5a56eSwmbat#endif // _LIBCPP_STD_VER > 11 5892ff5a56eSwmbat#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) 5905b2ef2b1SMarshall Clow 5916adbc83eSChristopher Di Bella// __swappable 5926adbc83eSChristopher Di Bella 593f07dd8d0SEric Fiseliertemplate <class _Tp> struct __is_swappable; 594f07dd8d0SEric Fiseliertemplate <class _Tp> struct __is_nothrow_swappable; 595f07dd8d0SEric Fiselier 596b51d5605SZoe Carver 597cafae056SChristopher Di Bella#ifndef _LIBCPP_CXX03_LANG 598cafae056SChristopher Di Bellatemplate <class _Tp> 599cafae056SChristopher Di Bellausing __swap_result_t = typename enable_if<is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value>::type; 600cafae056SChristopher Di Bella#else 601cafae056SChristopher Di Bellatemplate <class> 602cafae056SChristopher Di Bellausing __swap_result_t = void; 603cafae056SChristopher Di Bella#endif 604cafae056SChristopher Di Bella 6053e519524SHoward Hinnanttemplate <class _Tp> 6063e519524SHoward Hinnantinline _LIBCPP_INLINE_VISIBILITY 607cafae056SChristopher Di Bella_LIBCPP_CONSTEXPR_AFTER_CXX17 __swap_result_t<_Tp> 608a676f7d3SHoward Hinnantswap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value && 6096adbc83eSChristopher Di Bella is_nothrow_move_assignable<_Tp>::value); 6103e519524SHoward Hinnant 611f07dd8d0SEric Fiseliertemplate<class _Tp, size_t _Np> 61228e01871SZoe Carverinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 613f07dd8d0SEric Fiseliertypename enable_if< 614f07dd8d0SEric Fiselier __is_swappable<_Tp>::value 615f07dd8d0SEric Fiselier>::type 6166adbc83eSChristopher Di Bellaswap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value); 61727d0a2a7SHoward Hinnant 6183739fe79SHoward Hinnantnamespace __detail 6193739fe79SHoward Hinnant{ 620f07dd8d0SEric Fiselier// ALL generic swap overloads MUST already have a declaration available at this point. 62127d0a2a7SHoward Hinnant 622f07dd8d0SEric Fiseliertemplate <class _Tp, class _Up = _Tp, 623f07dd8d0SEric Fiselier bool _NotVoid = !is_void<_Tp>::value && !is_void<_Up>::value> 624f07dd8d0SEric Fiselierstruct __swappable_with 62527d0a2a7SHoward Hinnant{ 6260774aa96SEric Fiselier template <class _LHS, class _RHS> 627ab3fcc50SArthur O'Dwyer static decltype(swap(declval<_LHS>(), declval<_RHS>())) 6280774aa96SEric Fiselier __test_swap(int); 6290774aa96SEric Fiselier template <class, class> 6300774aa96SEric Fiselier static __nat __test_swap(long); 6310774aa96SEric Fiselier 6320774aa96SEric Fiselier // Extra parens are needed for the C++03 definition of decltype. 6330774aa96SEric Fiselier typedef decltype((__test_swap<_Tp, _Up>(0))) __swap1; 6340774aa96SEric Fiselier typedef decltype((__test_swap<_Up, _Tp>(0))) __swap2; 635f07dd8d0SEric Fiselier 6363359a17bSEric Fiselier static const bool value = _IsNotSame<__swap1, __nat>::value 6373359a17bSEric Fiselier && _IsNotSame<__swap2, __nat>::value; 63827d0a2a7SHoward Hinnant}; 63927d0a2a7SHoward Hinnant 640f07dd8d0SEric Fiseliertemplate <class _Tp, class _Up> 641f07dd8d0SEric Fiselierstruct __swappable_with<_Tp, _Up, false> : false_type {}; 642f07dd8d0SEric Fiselier 643f07dd8d0SEric Fiseliertemplate <class _Tp, class _Up = _Tp, bool _Swappable = __swappable_with<_Tp, _Up>::value> 644f07dd8d0SEric Fiselierstruct __nothrow_swappable_with { 645f07dd8d0SEric Fiselier static const bool value = 646f07dd8d0SEric Fiselier#ifndef _LIBCPP_HAS_NO_NOEXCEPT 647ab3fcc50SArthur O'Dwyer noexcept(swap(declval<_Tp>(), declval<_Up>())) 648ab3fcc50SArthur O'Dwyer && noexcept(swap(declval<_Up>(), declval<_Tp>())); 649f07dd8d0SEric Fiselier#else 650f07dd8d0SEric Fiselier false; 651f07dd8d0SEric Fiselier#endif 652f07dd8d0SEric Fiselier}; 653f07dd8d0SEric Fiselier 654f07dd8d0SEric Fiseliertemplate <class _Tp, class _Up> 655f07dd8d0SEric Fiselierstruct __nothrow_swappable_with<_Tp, _Up, false> : false_type {}; 656f07dd8d0SEric Fiselier 657d2b0df35SNikolas Klauser} // namespace __detail 6583739fe79SHoward Hinnant 65927d0a2a7SHoward Hinnanttemplate <class _Tp> 66027d0a2a7SHoward Hinnantstruct __is_swappable 661f07dd8d0SEric Fiselier : public integral_constant<bool, __detail::__swappable_with<_Tp&>::value> 66227d0a2a7SHoward Hinnant{ 66327d0a2a7SHoward Hinnant}; 66427d0a2a7SHoward Hinnant 66527d0a2a7SHoward Hinnanttemplate <class _Tp> 66627d0a2a7SHoward Hinnantstruct __is_nothrow_swappable 667f07dd8d0SEric Fiselier : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp&>::value> 66827d0a2a7SHoward Hinnant{ 66927d0a2a7SHoward Hinnant}; 67027d0a2a7SHoward Hinnant 671f07dd8d0SEric Fiselier#if _LIBCPP_STD_VER > 14 672f07dd8d0SEric Fiselier 673f07dd8d0SEric Fiseliertemplate <class _Tp, class _Up> 674e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS is_swappable_with 675f07dd8d0SEric Fiselier : public integral_constant<bool, __detail::__swappable_with<_Tp, _Up>::value> 676f07dd8d0SEric Fiselier{ 677f07dd8d0SEric Fiselier}; 67827d0a2a7SHoward Hinnant 67927d0a2a7SHoward Hinnanttemplate <class _Tp> 680e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS is_swappable 681f07dd8d0SEric Fiselier : public conditional< 682f07dd8d0SEric Fiselier __is_referenceable<_Tp>::value, 683f07dd8d0SEric Fiselier is_swappable_with< 684f07dd8d0SEric Fiselier typename add_lvalue_reference<_Tp>::type, 685f07dd8d0SEric Fiselier typename add_lvalue_reference<_Tp>::type>, 686f07dd8d0SEric Fiselier false_type 687f07dd8d0SEric Fiselier >::type 68827d0a2a7SHoward Hinnant{ 68927d0a2a7SHoward Hinnant}; 69027d0a2a7SHoward Hinnant 691f07dd8d0SEric Fiseliertemplate <class _Tp, class _Up> 692e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable_with 693f07dd8d0SEric Fiselier : public integral_constant<bool, __detail::__nothrow_swappable_with<_Tp, _Up>::value> 694f07dd8d0SEric Fiselier{ 695f07dd8d0SEric Fiselier}; 696f07dd8d0SEric Fiselier 697f07dd8d0SEric Fiseliertemplate <class _Tp> 698e2f2d1edSEric Fiselierstruct _LIBCPP_TEMPLATE_VIS is_nothrow_swappable 699f07dd8d0SEric Fiselier : public conditional< 700f07dd8d0SEric Fiselier __is_referenceable<_Tp>::value, 701f07dd8d0SEric Fiselier is_nothrow_swappable_with< 702f07dd8d0SEric Fiselier typename add_lvalue_reference<_Tp>::type, 703f07dd8d0SEric Fiselier typename add_lvalue_reference<_Tp>::type>, 704f07dd8d0SEric Fiselier false_type 705f07dd8d0SEric Fiselier >::type 706f07dd8d0SEric Fiselier{ 707f07dd8d0SEric Fiselier}; 708f07dd8d0SEric Fiselier 709f07dd8d0SEric Fiseliertemplate <class _Tp, class _Up> 710cb793e1aSLouis Dionneinline constexpr bool is_swappable_with_v = is_swappable_with<_Tp, _Up>::value; 711f07dd8d0SEric Fiselier 712f07dd8d0SEric Fiseliertemplate <class _Tp> 713cb793e1aSLouis Dionneinline constexpr bool is_swappable_v = is_swappable<_Tp>::value; 714f07dd8d0SEric Fiselier 715f07dd8d0SEric Fiseliertemplate <class _Tp, class _Up> 716cb793e1aSLouis Dionneinline constexpr bool is_nothrow_swappable_with_v = is_nothrow_swappable_with<_Tp, _Up>::value; 717f07dd8d0SEric Fiselier 718f07dd8d0SEric Fiseliertemplate <class _Tp> 719cb793e1aSLouis Dionneinline constexpr bool is_nothrow_swappable_v = is_nothrow_swappable<_Tp>::value; 720f07dd8d0SEric Fiselier 721f07dd8d0SEric Fiselier#endif // _LIBCPP_STD_VER > 14 72227d0a2a7SHoward Hinnant 72353df829bSEric Fiseliertemplate <class _Tp, bool = is_enum<_Tp>::value> 72451544023SEric Fiselierstruct __sfinae_underlying_type 72551544023SEric Fiselier{ 72651544023SEric Fiselier typedef typename underlying_type<_Tp>::type type; 72751544023SEric Fiselier typedef decltype(((type)1) + 0) __promoted_type; 72851544023SEric Fiselier}; 72951544023SEric Fiselier 73051544023SEric Fiseliertemplate <class _Tp> 73151544023SEric Fiselierstruct __sfinae_underlying_type<_Tp, false> {}; 73251544023SEric Fiselier 73312f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 73451544023SEric Fiselierint __convert_to_integral(int __val) { return __val; } 73551544023SEric Fiselier 73612f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 73751544023SEric Fiselierunsigned __convert_to_integral(unsigned __val) { return __val; } 73851544023SEric Fiselier 73912f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 74051544023SEric Fiselierlong __convert_to_integral(long __val) { return __val; } 74151544023SEric Fiselier 74212f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 74351544023SEric Fiselierunsigned long __convert_to_integral(unsigned long __val) { return __val; } 74451544023SEric Fiselier 74512f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 74651544023SEric Fiselierlong long __convert_to_integral(long long __val) { return __val; } 74751544023SEric Fiselier 74812f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 74951544023SEric Fiselierunsigned long long __convert_to_integral(unsigned long long __val) {return __val; } 75051544023SEric Fiselier 751feb83432SMarshall Clowtemplate<typename _Fp> 75212f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 753feb83432SMarshall Clowtypename enable_if<is_floating_point<_Fp>::value, long long>::type 754feb83432SMarshall Clow __convert_to_integral(_Fp __val) { return __val; } 755feb83432SMarshall Clow 75651544023SEric Fiselier#ifndef _LIBCPP_HAS_NO_INT128 75712f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 75851544023SEric Fiselier__int128_t __convert_to_integral(__int128_t __val) { return __val; } 75951544023SEric Fiselier 76012f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 76151544023SEric Fiselier__uint128_t __convert_to_integral(__uint128_t __val) { return __val; } 76251544023SEric Fiselier#endif 76351544023SEric Fiselier 76451544023SEric Fiseliertemplate <class _Tp> 76512f0a779SMarshall Clowinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 76651544023SEric Fiseliertypename __sfinae_underlying_type<_Tp>::__promoted_type 76751544023SEric Fiselier__convert_to_integral(_Tp __val) { return __val; } 76851544023SEric Fiselier 769fa1f613fSEric Fiselier// These traits are used in __tree and __hash_table 770fa1f613fSEric Fiselierstruct __extract_key_fail_tag {}; 771fa1f613fSEric Fiselierstruct __extract_key_self_tag {}; 772fa1f613fSEric Fiselierstruct __extract_key_first_tag {}; 773fa1f613fSEric Fiselier 774fa1f613fSEric Fiseliertemplate <class _ValTy, class _Key, 775fa1f613fSEric Fiselier class _RawValTy = typename __unconstref<_ValTy>::type> 776fa1f613fSEric Fiselierstruct __can_extract_key 7773359a17bSEric Fiselier : conditional<_IsSame<_RawValTy, _Key>::value, __extract_key_self_tag, 778fa1f613fSEric Fiselier __extract_key_fail_tag>::type {}; 779fa1f613fSEric Fiselier 780fa1f613fSEric Fiseliertemplate <class _Pair, class _Key, class _First, class _Second> 781fa1f613fSEric Fiselierstruct __can_extract_key<_Pair, _Key, pair<_First, _Second> > 7823359a17bSEric Fiselier : conditional<_IsSame<typename remove_const<_First>::type, _Key>::value, 783fa1f613fSEric Fiselier __extract_key_first_tag, __extract_key_fail_tag>::type {}; 78450088684SEric Fiselier 78550088684SEric Fiselier// __can_extract_map_key uses true_type/false_type instead of the tags. 78650088684SEric Fiselier// It returns true if _Key != _ContainerValueTy (the container is a map not a set) 78750088684SEric Fiselier// and _ValTy == _Key. 78850088684SEric Fiseliertemplate <class _ValTy, class _Key, class _ContainerValueTy, 78950088684SEric Fiselier class _RawValTy = typename __unconstref<_ValTy>::type> 79050088684SEric Fiselierstruct __can_extract_map_key 7913359a17bSEric Fiselier : integral_constant<bool, _IsSame<_RawValTy, _Key>::value> {}; 79250088684SEric Fiselier 79350088684SEric Fiselier// This specialization returns __extract_key_fail_tag for non-map containers 79450088684SEric Fiselier// because _Key == _ContainerValueTy 79550088684SEric Fiseliertemplate <class _ValTy, class _Key, class _RawValTy> 79650088684SEric Fiselierstruct __can_extract_map_key<_ValTy, _Key, _Key, _RawValTy> 79750088684SEric Fiselier : false_type {}; 79850088684SEric Fiselier 799d1523f7aSEric Fiseliertemplate <class _CharT> 800d1523f7aSEric Fiselierusing _IsCharLikeType = _And<is_standard_layout<_CharT>, is_trivial<_CharT> >; 801d1523f7aSEric Fiselier 8027959d590SChristopher Di Bellatemplate<class _Tp> 8037959d590SChristopher Di Bellausing __make_const_lvalue_ref = const typename remove_reference<_Tp>::type&; 8047959d590SChristopher Di Bella 8050e09a41bSzoecarvertemplate<bool _Const, class _Tp> 80616719cd0SHui Xieusing __maybe_const = typename conditional<_Const, const _Tp, _Tp>::type; 8070e09a41bSzoecarver 8083e519524SHoward Hinnant_LIBCPP_END_NAMESPACE_STD 8093e519524SHoward Hinnant 8103e519524SHoward Hinnant#endif // _LIBCPP_TYPE_TRAITS 811