diff --git a/libcxx/docs/Cxx2aStatus.rst b/libcxx/docs/Cxx2aStatus.rst --- a/libcxx/docs/Cxx2aStatus.rst +++ b/libcxx/docs/Cxx2aStatus.rst @@ -42,7 +42,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.8, D.9, and D.10 are implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone. + .. [#note-P0619] P0619: Only sections D.8, D.9, D.10 and D.13 are implemented. Sections D.4, D.7, D.11, D.12, and D.14 remain undone. .. [#note-P0883] P0883: shared_ptr and floating-point changes weren't applied as they themselves aren't implemented yet. diff --git a/libcxx/docs/UsingLibcxx.rst b/libcxx/docs/UsingLibcxx.rst --- a/libcxx/docs/UsingLibcxx.rst +++ b/libcxx/docs/UsingLibcxx.rst @@ -266,6 +266,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 @@ -1359,6 +1359,7 @@ #define _LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS #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 @@ -3677,15 +3677,17 @@ // 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 {}; #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES) template -_LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_literal_type_v +_LIBCPP_DEPRECATED_IN_CXX17 _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; @@ -4003,7 +4005,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 @@ -4091,8 +4094,9 @@ #endif // C++03 #if _LIBCPP_STD_VER > 11 -template using result_of_t = typename result_of<_Tp>::type; -#endif +template using result_of_t _LIBCPP_DEPRECATED_IN_CXX17 = typename result_of<_Tp>::type; +#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/atomic_helpers.h b/libcxx/test/std/atomics/atomic_helpers.h new file mode 100644 --- /dev/null +++ b/libcxx/test/std/atomics/atomic_helpers.h @@ -0,0 +1,142 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef ATOMIC_HELPERS_H +#define ATOMIC_HELPERS_H + +#include + +#include "test_macros.h" + +struct UserAtomicType { + int i; + + explicit UserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {} + + friend bool operator==(const UserAtomicType& x, const UserAtomicType& y) { return x.i == y.i; } +}; + +/* + +Enable these once we have P0528 + +struct WeirdUserAtomicType +{ + char i, j, k; // the 3 chars of doom + + explicit WeirdUserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {} + + friend bool operator==(const WeirdUserAtomicType& x, const WeirdUserAtomicType& y) + { return x.i == y.i; } +}; + +struct PaddedUserAtomicType +{ + char i; int j; // probably lock-free? + + explicit PaddedUserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {} + + friend bool operator==(const PaddedUserAtomicType& x, const PaddedUserAtomicType& y) + { return x.i == y.i; } +}; + +*/ + +struct LargeUserAtomicType { + int a[128]; /* decidedly not lock-free */ + + LargeUserAtomicType(int d = 0) TEST_NOEXCEPT { + for (auto&& e : a) + e = d++; + } + + friend bool operator==(LargeUserAtomicType const& x, LargeUserAtomicType const& y) TEST_NOEXCEPT { + for (int i = 0; i < 128; ++i) + if (x.a[i] != y.a[i]) + return false; + return true; + } +}; + +template