diff --git a/libcxx/docs/Cxx2aStatus.rst b/libcxx/docs/Cxx2aStatus.rst --- a/libcxx/docs/Cxx2aStatus.rst +++ b/libcxx/docs/Cxx2aStatus.rst @@ -43,7 +43,7 @@ .. [#note-P0600] P0600: The missing bits in P0600 are in |sect|\ [mem.res.class], |sect|\ [mem.poly.allocator.class], and |sect|\ [container.node.overview]. .. [#note-P0966] P0966: It was previously erroneously marked as complete in version 8.0. See `bug 45368 `__. - .. [#note-P0619] P0619: Only sections D.9 and D.10 are implemented. Section D.8 is partly implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone. + .. [#note-P0619] P0619: Only sections D.9, D.10 and D.13 are implemented. Section D.8 is partly implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone. .. _issues-status-cxx2a: diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -263,6 +263,9 @@ **_LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR**: This macro is used to re-enable `raw_storage_iterator`. +**_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS**: + This macro is used to re-enable `is_literal_type`, `is_literal_type_v`, + `result_of` and `result_of_t`. Libc++ Extensions ================= diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -1375,6 +1375,7 @@ #define _LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS #define _LIBCPP_ENABLE_CXX20_REMOVED_NEGATORS #define _LIBCPP_ENABLE_CXX20_REMOVED_RAW_STORAGE_ITERATOR +#define _LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS #endif // _LIBCPP_ENABLE_CXX20_REMOVED_FEATURES #if !defined(__cpp_deduction_guides) || __cpp_deduction_guides < 201611 diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -99,7 +99,7 @@ template struct is_trivial; template struct is_trivially_copyable; template struct is_standard_layout; - template struct is_literal_type; + template struct is_literal_type; // Deprecated in C++17; removed in C++20 template struct is_empty; template struct is_polymorphic; template struct is_abstract; @@ -165,8 +165,8 @@ template struct decay; template struct common_type; template struct underlying_type; - template class result_of; // undefined - template class result_of; + template class result_of; // undefined; deprecated in C++17; removed in C++20 + template class result_of; // deprecated in C++17; removed in C++20 template struct invoke_result; // C++17 // const-volatile modifications: @@ -233,7 +233,7 @@ template using underlying_type_t = typename underlying_type::type; // C++14 template - using result_of_t = typename result_of::type; // C++14 + using result_of_t = typename result_of::type; // C++14; deprecated in C++17; removed in C++20 template using invoke_result_t = typename invoke_result::type; // C++17 @@ -302,7 +302,7 @@ template inline constexpr bool is_pod_v = is_pod::value; // C++17 template inline constexpr bool is_literal_type_v - = is_literal_type::value; // C++17 + = is_literal_type::value; // C++17; deprecated in C++17; removed in C++20 template inline constexpr bool is_empty_v = is_empty::value; // C++17 template inline constexpr bool is_polymorphic_v @@ -3717,7 +3717,8 @@ // is_literal_type; -template struct _LIBCPP_TEMPLATE_VIS is_literal_type +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) +template struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type : public integral_constant {}; @@ -3725,7 +3726,8 @@ template _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_literal_type_v = is_literal_type<_Tp>::value; -#endif +#endif // _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) // is_standard_layout; @@ -4043,7 +4045,8 @@ // result_of -template class result_of; +#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) +template class _LIBCPP_DEPRECATED_IN_CXX17 result_of; #ifndef _LIBCPP_CXX03_LANG @@ -4132,7 +4135,8 @@ #if _LIBCPP_STD_VER > 11 template using result_of_t = typename result_of<_Tp>::type; -#endif +#endif // _LIBCPP_STD_VER > 11 +#endif // _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) #if _LIBCPP_STD_VER > 14 diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp @@ -35,7 +35,7 @@ struct TestFunc { void operator()() const { typedef std::atomic Atomic; - static_assert(std::is_literal_type::value, ""); + static_assert(std::is_trivial::value, ""); constexpr Tp t(42); { constexpr Atomic a(t); diff --git a/libcxx/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp b/libcxx/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp --- a/libcxx/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp @@ -10,6 +10,9 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // invoke_result_t invoke(F&& f, Args&&... args) // C++17 // noexcept(is_nothrow_invocable_v<_Fn, _Args...>); diff --git a/libcxx/test/std/utilities/function.objects/func.invoke/invoke_constexpr.pass.cpp b/libcxx/test/std/utilities/function.objects/func.invoke/invoke_constexpr.pass.cpp --- a/libcxx/test/std/utilities/function.objects/func.invoke/invoke_constexpr.pass.cpp +++ b/libcxx/test/std/utilities/function.objects/func.invoke/invoke_constexpr.pass.cpp @@ -10,6 +10,9 @@ // +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + // template // constexpr // constexpr in C++20 // invoke_result_t invoke(F&& f, Args&&... args) diff --git a/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp --- a/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp +++ b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp @@ -261,39 +261,6 @@ } } - -// The example code specified in Note B for common_type -namespace note_b_example { - -typedef bool (&PF1)(); -typedef short (*PF2)(long); - -struct S { - operator PF2() const; - double operator()(char, int&); - void fn(long) const; - char data; -}; - -typedef void (S::*PMF)(long) const; -typedef char S::*PMD; - -using std::is_same; -using std::result_of; -using std::unique_ptr; - -static_assert((is_same::type, short>::value), "Error!"); -static_assert((is_same::type, double>::value), "Error!"); -static_assert((is_same::type, bool>::value), "Error!"); -static_assert((is_same, int)>::type, void>::value), "Error!"); -#if TEST_STD_VER >= 11 -static_assert((is_same::type, char&&>::value), "Error!"); -#endif -static_assert((is_same::type, const char&>::value), "Error!"); - -} // namespace note_b_example - - int main(int, char**) { static_assert((std::is_same::type, int>::value), ""); diff --git a/libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.deprecated.fail.cpp rename from libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp rename to libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.deprecated.fail.cpp --- a/libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp +++ b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.deprecated.fail.cpp @@ -8,17 +8,21 @@ // UNSUPPORTED: c++03, c++11, c++14 -// +// type_traits -// [Note any is a not a literal type --end note] +// result_of + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS -#include #include #include "test_macros.h" -int main(int, char**) { - static_assert(!std::is_literal_type::value, ""); +struct CallableStruct { + float operator()(int) { return 1.0; } +}; - return 0; +int main(int, char**) { + typedef std::result_of< // expected-warning {{'result_of' is deprecated}} + CallableStruct(int)>::type f; } diff --git a/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp --- a/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp +++ b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp @@ -10,6 +10,9 @@ // result_of +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + #include #include #include diff --git a/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp --- a/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp +++ b/libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp @@ -12,6 +12,9 @@ // // result_of +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + #include #include #include diff --git a/libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.deprecated.fail.cpp rename from libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp rename to libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.deprecated.fail.cpp --- a/libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp +++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.deprecated.fail.cpp @@ -8,17 +8,18 @@ // UNSUPPORTED: c++03, c++11, c++14 -// +// type_traits -// [Note any is a not a literal type --end note] +// is_literal_type + +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS -#include #include #include "test_macros.h" int main(int, char**) { - static_assert(!std::is_literal_type::value, ""); + static_assert(std::is_literal_type::value, ""); // expected-warning {{'is_literal_type' is deprecated}} return 0; } diff --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp --- a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp +++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp @@ -10,6 +10,9 @@ // is_literal_type +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS +// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS + #include #include // for std::nullptr_t #include "test_macros.h" diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp --- a/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp +++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.dtor/dtor.pass.cpp @@ -40,25 +40,21 @@ typedef int T; static_assert(std::is_trivially_destructible::value, ""); static_assert(std::is_trivially_destructible>::value, ""); - static_assert(std::is_literal_type>::value, ""); } { typedef double T; static_assert(std::is_trivially_destructible::value, ""); static_assert(std::is_trivially_destructible>::value, ""); - static_assert(std::is_literal_type>::value, ""); } { typedef PODType T; static_assert(std::is_trivially_destructible::value, ""); static_assert(std::is_trivially_destructible>::value, ""); - static_assert(std::is_literal_type>::value, ""); } { typedef X T; static_assert(!std::is_trivially_destructible::value, ""); static_assert(!std::is_trivially_destructible>::value, ""); - static_assert(!std::is_literal_type>::value, ""); { X x; optional opt{x}; diff --git a/libcxx/test/support/poisoned_hash_helper.h b/libcxx/test/support/poisoned_hash_helper.h --- a/libcxx/test/support/poisoned_hash_helper.h +++ b/libcxx/test/support/poisoned_hash_helper.h @@ -117,14 +117,18 @@ operator To const&&() const && { return std::move(to); } }; -template ::type> +template ()(std::declval()))> constexpr bool can_hash(int) { return std::is_same::value; } -template constexpr bool can_hash(long) { return false; } -template constexpr bool can_hash() { return can_hash(0); } - +template +constexpr bool can_hash(long) { + return false; +} +template +constexpr bool can_hash() { + return can_hash(0); +} } // namespace PoisonedHashDetail template @@ -146,21 +150,21 @@ #endif // Hashable requirements - static_assert(can_hash(), ""); - static_assert(can_hash(), ""); - static_assert(can_hash(), ""); - static_assert(can_hash(), ""); - static_assert(can_hash(), ""); - static_assert(can_hash(), ""); - - static_assert(can_hash&)>(), ""); - static_assert(can_hash const&)>(), ""); - static_assert(can_hash&&)>(), ""); - - static_assert(can_hash&)>(), ""); - static_assert(can_hash const&)>(), ""); - static_assert(can_hash &&)>(), ""); - static_assert(can_hash const&&)>(), ""); + static_assert(can_hash(), ""); + static_assert(can_hash(), ""); + static_assert(can_hash(), ""); + static_assert(can_hash(), ""); + static_assert(can_hash(), ""); + static_assert(can_hash(), ""); + + static_assert(can_hash&>(), ""); + static_assert(can_hash const&>(), ""); + static_assert(can_hash&&>(), ""); + + static_assert(can_hash&>(), ""); + static_assert(can_hash const&>(), ""); + static_assert(can_hash&&>(), ""); + static_assert(can_hash const&&>(), ""); const Hash h{}; assert(h(key) == h(key)); @@ -185,21 +189,21 @@ >::value, ""); // Hashable requirements - static_assert(!can_hash(), ""); - static_assert(!can_hash(), ""); - static_assert(!can_hash(), ""); - static_assert(!can_hash(), ""); - static_assert(!can_hash(), ""); - static_assert(!can_hash(), ""); - - static_assert(!can_hash&)>(), ""); - static_assert(!can_hash const&)>(), ""); - static_assert(!can_hash&&)>(), ""); - - static_assert(!can_hash&)>(), ""); - static_assert(!can_hash const&)>(), ""); - static_assert(!can_hash &&)>(), ""); - static_assert(!can_hash const&&)>(), ""); + static_assert(!can_hash(), ""); + static_assert(!can_hash(), ""); + static_assert(!can_hash(), ""); + static_assert(!can_hash(), ""); + static_assert(!can_hash(), ""); + static_assert(!can_hash(), ""); + + static_assert(!can_hash&>(), ""); + static_assert(!can_hash const&>(), ""); + static_assert(!can_hash&&>(), ""); + + static_assert(!can_hash&>(), ""); + static_assert(!can_hash const&>(), ""); + static_assert(!can_hash&&>(), ""); + static_assert(!can_hash const&&>(), ""); }