[libcxx-commits] [libcxx] 2ff5a56 - [libcxx][type_traits] remove `std::is_literal_type` and `std::result_of` for C++20

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jul 2 10:22:01 PDT 2021


Author: wmbat
Date: 2021-07-02T17:10:19Z
New Revision: 2ff5a56e1ab2a95c36d3c5d2bef7c585125718ae

URL: https://github.com/llvm/llvm-project/commit/2ff5a56e1ab2a95c36d3c5d2bef7c585125718ae
DIFF: https://github.com/llvm/llvm-project/commit/2ff5a56e1ab2a95c36d3c5d2bef7c585125718ae.diff

LOG: [libcxx][type_traits] remove `std::is_literal_type` and `std::result_of` for C++20

C++17 deprecated `std::is_literal_type` and `std::result_of`, C++20 removed them.

Implements parts of:
    * P0174R2 'Deprecating Vestigial Library Parts in C++17'.
    * P0619R4 'Reviewing Deprecated Facilities of C++17 for C++20'.

Reviewed By: ldionne, Mordante, Quuxplusone, #libc

Differential Revision: https://reviews.llvm.org/D102992

Added: 
    libcxx/test/std/atomics/atomics.types.generic/standard_layout.compile.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/dtor.pass.cpp
    libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.deprecated.fail.cpp
    libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.deprecated.fail.cpp
    libcxx/test/support/atomic_helpers.h

Modified: 
    libcxx/docs/Cxx2aStatus.rst
    libcxx/docs/UsingLibcxx.rst
    libcxx/include/__config
    libcxx/include/type_traits
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/ctor.pass.cpp
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp
    libcxx/test/std/utilities/function.objects/func.invoke/invoke.pass.cpp
    libcxx/test/std/utilities/function.objects/func.invoke/invoke_constexpr.pass.cpp
    libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/common_type.pass.cpp
    libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of.pass.cpp
    libcxx/test/std/utilities/meta/meta.trans/meta.trans.other/result_of11.pass.cpp
    libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.pass.cpp
    libcxx/test/support/poisoned_hash_helper.h

Removed: 
    libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h
    libcxx/test/std/utilities/any/any.class/not_literal_type.pass.cpp


################################################################################
diff  --git a/libcxx/docs/Cxx2aStatus.rst b/libcxx/docs/Cxx2aStatus.rst
index 8bbf7d80c3aa4..ae23daf0238f7 100644
--- a/libcxx/docs/Cxx2aStatus.rst
+++ b/libcxx/docs/Cxx2aStatus.rst
@@ -42,7 +42,7 @@ Paper Status
 
    .. [#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 <https://llvm.org/PR45368>`__.
-   .. [#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
index 31ec90ce1ffbd..b967c986165e8 100644
--- a/libcxx/docs/UsingLibcxx.rst
+++ b/libcxx/docs/UsingLibcxx.rst
@@ -266,6 +266,9 @@ C++20 Specific Configuration Macros:
 **_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
index a408382385541..9a5343c14d5ff 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1359,6 +1359,7 @@ extern "C" _LIBCPP_FUNC_VIS void __sanitizer_annotate_contiguous_container(
 #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
index 09b66c7871d80..cc364ce3b1f49 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -99,7 +99,7 @@ namespace std
     template <class T> struct is_trivial;
     template <class T> struct is_trivially_copyable;
     template <class T> struct is_standard_layout;
-    template <class T> struct is_literal_type;
+    template <class T> struct is_literal_type; // Deprecated in C++17; removed in C++20
     template <class T> struct is_empty;
     template <class T> struct is_polymorphic;
     template <class T> struct is_abstract;
@@ -165,8 +165,8 @@ namespace std
     template <class T> struct decay;
     template <class... T> struct common_type;
     template <class T> struct underlying_type;
-    template <class> class result_of; // undefined
-    template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>;
+    template <class> class result_of; // undefined; deprecated in C++17; removed in C++20
+    template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>; // deprecated in C++17; removed in C++20
     template <class Fn, class... ArgTypes> struct invoke_result;  // C++17
 
     // const-volatile modifications:
@@ -233,7 +233,7 @@ namespace std
     template <class T>
       using underlying_type_t = typename underlying_type<T>::type;  // C++14
     template <class T>
-      using result_of_t       = typename result_of<T>::type;  // C++14
+      using result_of_t       = typename result_of<T>::type;  // C++14; deprecated in C++17; removed in C++20
     template <class Fn, class... ArgTypes>
       using invoke_result_t   = typename invoke_result<Fn, ArgTypes...>::type;  // C++17
 
@@ -302,7 +302,7 @@ namespace std
       template <class T> inline constexpr bool is_pod_v
         = is_pod<T>::value;                                              // C++17
       template <class T> inline constexpr bool is_literal_type_v
-        = is_literal_type<T>::value;                                     // C++17
+        = is_literal_type<T>::value;                                     // C++17; deprecated in C++17; removed in C++20
       template <class T> inline constexpr bool is_empty_v
         = is_empty<T>::value;                                            // C++17
       template <class T> inline constexpr bool is_polymorphic_v
@@ -3677,15 +3677,17 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_pod_v
 
 // is_literal_type;
 
-template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_literal_type
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
+template <class _Tp> struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 is_literal_type
     : public integral_constant<bool, __is_literal_type(_Tp)>
     {};
 
 #if _LIBCPP_STD_VER > 14 && !defined(_LIBCPP_HAS_NO_VARIABLE_TEMPLATES)
 template <class _Tp>
-_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 @@ struct __invoke_of
 
 // result_of
 
-template <class _Callable> class result_of;
+#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS)
+template <class _Callable> class _LIBCPP_DEPRECATED_IN_CXX17 result_of;
 
 #ifndef _LIBCPP_CXX03_LANG
 
@@ -4091,8 +4094,9 @@ class _LIBCPP_TEMPLATE_VIS result_of<_Fn(_Args...)>
 #endif // C++03
 
 #if _LIBCPP_STD_VER > 11
-template <class _Tp> using result_of_t = typename result_of<_Tp>::type;
-#endif
+template <class _Tp> 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/atomics.types.generic/standard_layout.compile.pass.cpp b/libcxx/test/std/atomics/atomics.types.generic/standard_layout.compile.pass.cpp
new file mode 100644
index 0000000000000..a95986283e2fa
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.generic/standard_layout.compile.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03
+
+// <atomic>
+
+#include <atomic>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "atomic_helpers.h"
+
+template <class Tp>
+struct CheckStandardLayout {
+  void operator()() const {
+    typedef std::atomic<Tp> Atomic;
+    static_assert(std::is_standard_layout<Atomic>::value, "");
+  }
+};
+
+int main(int, char**) {
+  TestEachIntegralType<CheckStandardLayout>()();
+  TestEachFloatingPointType<CheckStandardLayout>()();
+  TestEachPointerType<CheckStandardLayout>()();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h
deleted file mode 100644
index 40514f078ac51..0000000000000
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h
+++ /dev/null
@@ -1,131 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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 <cassert>
-
-#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 < template <class TestArg> class TestFunctor >
-struct TestEachIntegralType {
-    void operator()() const {
-        TestFunctor<char>()();
-        TestFunctor<signed char>()();
-        TestFunctor<unsigned char>()();
-        TestFunctor<short>()();
-        TestFunctor<unsigned short>()();
-        TestFunctor<int>()();
-        TestFunctor<unsigned int>()();
-        TestFunctor<long>()();
-        TestFunctor<unsigned long>()();
-        TestFunctor<long long>()();
-        TestFunctor<unsigned long long>()();
-        TestFunctor<wchar_t>();
-#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
-        TestFunctor<char8_t>()();
-#endif
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-        TestFunctor<char16_t>()();
-        TestFunctor<char32_t>()();
-#endif
-        TestFunctor<  int8_t>()();
-        TestFunctor< uint8_t>()();
-        TestFunctor< int16_t>()();
-        TestFunctor<uint16_t>()();
-        TestFunctor< int32_t>()();
-        TestFunctor<uint32_t>()();
-        TestFunctor< int64_t>()();
-        TestFunctor<uint64_t>()();
-    }
-};
-
-template < template <class TestArg> class TestFunctor >
-struct TestEachAtomicType {
-    void operator()() const {
-        TestEachIntegralType<TestFunctor>()();
-        TestFunctor<UserAtomicType>()();
-        /*
-            Note: These aren't going to be lock-free,
-            so some libatomic.a is necessary. To handle
-            the case where the support functions are
-            missing, all tests that use this file should add:
-            XFAIL: !non-lockfree-atomics
-        */
-        TestFunctor<LargeUserAtomicType>()();
-/*
-    Enable these once we have P0528 
-    
-        TestFunctor<PaddedUserAtomicType>()();
-        TestFunctor<WeirdUserAtomicType>()();
-*/
-        TestFunctor<int*>()();
-        TestFunctor<const int*>()();
-        TestFunctor<float>()();
-        TestFunctor<double>()();
-    }
-};
-
-
-#endif // ATOMIC_HELPER_H

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
index 5cfad1116dfe0..6036d8e05ac26 100644
--- 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
@@ -21,42 +21,37 @@
 #include "atomic_helpers.h"
 
 struct UserType {
-    int i;
+  int i;
 
-    UserType() noexcept {}
-    constexpr explicit UserType(int d) noexcept : i(d) {}
+  UserType() noexcept {}
+  constexpr explicit UserType(int d) noexcept : i(d) {}
 
-    friend bool operator==(const UserType& x, const UserType& y) {
-        return x.i == y.i;
-    }
+  friend bool operator==(const UserType& x, const UserType& y) { return x.i == y.i; }
 };
 
 template <class Tp>
 struct TestFunc {
-    void operator()() const {
-        typedef std::atomic<Tp> Atomic;
-        static_assert(std::is_literal_type<Atomic>::value, "");
-        constexpr Tp t(42);
-        {
-            constexpr Atomic a(t);
-            assert(a == t);
-        }
-        {
-            constexpr Atomic a{t};
-            assert(a == t);
-        }
-        {
-            constexpr Atomic a = ATOMIC_VAR_INIT(t);
-            assert(a == t);
-        }
+  void operator()() const {
+    typedef std::atomic<Tp> Atomic;
+    constexpr Tp t(42);
+    {
+      constexpr Atomic a(t);
+      assert(a == t);
+    }
+    {
+      constexpr Atomic a{t};
+      assert(a == t);
     }
+    {
+      constexpr Atomic a = ATOMIC_VAR_INIT(t);
+      assert(a == t);
+    }
+  }
 };
 
-
-int main(int, char**)
-{
-    TestFunc<UserType>()();
-    TestEachIntegralType<TestFunc>()();
+int main(int, char**) {
+  TestFunc<UserType>()();
+  TestEachIntegralType<TestFunc>()();
 
   return 0;
 }

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/dtor.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/dtor.pass.cpp
new file mode 100644
index 0000000000000..ea85cde7860a7
--- /dev/null
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/dtor.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// UNSUPPORTED: libcpp-has-no-threads
+// UNSUPPORTED: c++03
+
+// <atomic>
+
+// constexpr atomic<T>::~atomic()
+
+#include <atomic>
+#include <type_traits>
+#include <cassert>
+
+#include "test_macros.h"
+#include "atomic_helpers.h"
+
+template <class Tp>
+struct CheckTriviallyDestructible {
+  void operator()() const {
+    typedef std::atomic<Tp> Atomic;
+    static_assert(std::is_trivially_destructible<Atomic>::value, "");
+  }
+};
+
+int main(int, char**) {
+  TestEachIntegralType<CheckTriviallyDestructible>()();
+  TestEachFloatingPointType<CheckTriviallyDestructible>()();
+  TestEachPointerType<CheckTriviallyDestructible>()();
+
+  return 0;
+}

diff  --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp
index d2779aaa19f56..9e918e201dfda 100644
--- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.wait/atomic_wait.pass.cpp
@@ -23,7 +23,7 @@
 
 #include "make_test_thread.h"
 #include "test_macros.h"
-#include "../atomics.types.operations.req/atomic_helpers.h"
+#include "atomic_helpers.h"
 
 template <class T>
 struct TestFn {

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
index 455d8dd24779a..82849a815e7e3 100644
--- 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 @@
 
 // <functional>
 
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
 // template<class F, class... Args>
 // invoke_result_t<F, Args...> 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
index 8bfc7428fad9d..bfd8765b7d779 100644
--- 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 @@
 
 // <functional>
 
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
 // template<class F, class... Args>
 // constexpr  // constexpr in C++20
 // invoke_result_t<F, Args...> 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
index e4668b08d1d65..f070b2770d0a0 100644
--- 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 @@ void test_bullet_four() {
   }
 }
 
-
-// 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<result_of<S(int)>::type, short>::value), "Error!");
-static_assert((is_same<result_of<S&(unsigned char, int&)>::type, double>::value), "Error!");
-static_assert((is_same<result_of<PF1()>::type, bool>::value), "Error!");
-static_assert((is_same<result_of<PMF(unique_ptr<S>, int)>::type, void>::value), "Error!");
-#if TEST_STD_VER >= 11
-static_assert((is_same<result_of<PMD(S)>::type, char&&>::value), "Error!");
-#endif
-static_assert((is_same<result_of<PMD(const S*)>::type, const char&>::value), "Error!");
-
-} // namespace note_b_example
-
-
 int main(int, char**)
 {
     static_assert((std::is_same<std::common_type<int>::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
similarity index 69%
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
index d1b649dc46c44..aece06674cf01 100644
--- 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
@@ -7,18 +7,16 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
 
-// <any>
+// type_traits
 
-// [Note any is a not a literal type --end note]
+// result_of
 
-#include <any>
 #include <type_traits>
 
 #include "test_macros.h"
 
 int main(int, char**) {
-    static_assert(!std::is_literal_type<std::any>::value, "");
-
-  return 0;
+  [[maybe_unused]] std::result_of<int (*())()> a; // expected-warning {{'result_of<int (*())()>' is deprecated}}
 }

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
index 5efb568ce30b3..78ff8fbd1170c 100644
--- 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<Fn(ArgTypes...)>
 
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
 #include <type_traits>
 #include <cassert>
 #include <functional>

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
index 2589f17b437bc..e98df1ef96be9 100644
--- 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<Fn(ArgTypes...)>
 
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+
 #include <type_traits>
 #include <functional>
 #include <memory>

diff  --git a/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.deprecated.fail.cpp b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.deprecated.fail.cpp
new file mode 100644
index 0000000000000..c63524da5b40a
--- /dev/null
+++ b/libcxx/test/std/utilities/meta/meta.unary/meta.unary.prop/is_literal_type.deprecated.fail.cpp
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS
+
+// type_traits
+
+// is_literal_type
+
+#include <type_traits>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+  static_assert(std::is_literal_type<int>::value, ""); // expected-warning {{'is_literal_type<int>' 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
index b86ff5a854656..1c85560ba7b2a 100644
--- 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 <type_traits>
 #include <cstddef>       // for std::nullptr_t
 #include "test_macros.h"

diff  --git a/libcxx/test/support/atomic_helpers.h b/libcxx/test/support/atomic_helpers.h
new file mode 100644
index 0000000000000..a5c17035d0d90
--- /dev/null
+++ b/libcxx/test/support/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 <cassert>
+
+#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 <template <class TestArg> class TestFunctor>
+struct TestEachIntegralType {
+  void operator()() const {
+    TestFunctor<char>()();
+    TestFunctor<signed char>()();
+    TestFunctor<unsigned char>()();
+    TestFunctor<short>()();
+    TestFunctor<unsigned short>()();
+    TestFunctor<int>()();
+    TestFunctor<unsigned int>()();
+    TestFunctor<long>()();
+    TestFunctor<unsigned long>()();
+    TestFunctor<long long>()();
+    TestFunctor<unsigned long long>()();
+    TestFunctor<wchar_t>();
+#if TEST_STD_VER > 17 && defined(__cpp_char8_t)
+    TestFunctor<char8_t>()();
+#endif
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+    TestFunctor<char16_t>()();
+    TestFunctor<char32_t>()();
+#endif
+    TestFunctor<int8_t>()();
+    TestFunctor<uint8_t>()();
+    TestFunctor<int16_t>()();
+    TestFunctor<uint16_t>()();
+    TestFunctor<int32_t>()();
+    TestFunctor<uint32_t>()();
+    TestFunctor<int64_t>()();
+    TestFunctor<uint64_t>()();
+  }
+};
+
+template <template <class TestArg> class TestFunctor>
+struct TestEachFloatingPointType {
+  void operator()() const {
+    TestFunctor<float>()();
+    TestFunctor<double>()();
+    TestFunctor<long double>()();
+  }
+};
+
+template <template <class TestArg> class TestFunctor>
+struct TestEachPointerType {
+  void operator()() const {
+    TestFunctor<int*>()();
+    TestFunctor<const int*>()();
+  }
+};
+
+template <template <class TestArg> class TestFunctor>
+struct TestEachAtomicType {
+  void operator()() const {
+    TestEachIntegralType<TestFunctor>()();
+    TestFunctor<UserAtomicType>()();
+    /*
+            Note: These aren't going to be lock-free,
+            so some libatomic.a is necessary. To handle
+            the case where the support functions are
+            missing, all tests that use this file should add:
+            XFAIL: !non-lockfree-atomics
+        */
+    TestFunctor<LargeUserAtomicType>()();
+    /*
+    Enable these once we have P0528
+
+        TestFunctor<PaddedUserAtomicType>()();
+        TestFunctor<WeirdUserAtomicType>()();
+*/
+    TestFunctor<int*>()();
+    TestFunctor<const int*>()();
+    TestFunctor<float>()();
+    TestFunctor<double>()();
+  }
+};
+
+#endif // ATOMIC_HELPERS_H

diff  --git a/libcxx/test/support/poisoned_hash_helper.h b/libcxx/test/support/poisoned_hash_helper.h
index 1a81ead61b1d4..fbd35caae5a6b 100644
--- a/libcxx/test/support/poisoned_hash_helper.h
+++ b/libcxx/test/support/poisoned_hash_helper.h
@@ -118,14 +118,18 @@ struct ConvertibleTo {
   operator To const&&() const && { return std::move(to); }
 };
 
-template <class HashExpr,
-         class Res = typename std::result_of<HashExpr>::type>
+template <class Hasher, class Key, class Res = decltype(std::declval<Hasher&>()(std::declval<Key>()))>
 constexpr bool can_hash(int) {
   return std::is_same<Res, size_t>::value;
 }
-template <class> constexpr bool can_hash(long) { return false; }
-template <class T> constexpr bool can_hash() { return can_hash<T>(0); }
-
+template <class, class>
+constexpr bool can_hash(long) {
+  return false;
+}
+template <class Hasher, class Key>
+constexpr bool can_hash() {
+  return can_hash<Hasher, Key>(0);
+}
 } // namespace PoisonedHashDetail
 
 template <class Hash, class Key, class InputKey>
@@ -147,21 +151,21 @@ void test_hash_enabled(InputKey const& key) {
 #endif
 
   // Hashable requirements
-  static_assert(can_hash<Hash(Key&)>(), "");
-  static_assert(can_hash<Hash(Key const&)>(), "");
-  static_assert(can_hash<Hash(Key&&)>(), "");
-  static_assert(can_hash<Hash const&(Key&)>(), "");
-  static_assert(can_hash<Hash const&(Key const&)>(), "");
-  static_assert(can_hash<Hash const&(Key&&)>(), "");
-
-  static_assert(can_hash<Hash(ConvertibleToSimple<Key>&)>(), "");
-  static_assert(can_hash<Hash(ConvertibleToSimple<Key> const&)>(), "");
-  static_assert(can_hash<Hash(ConvertibleToSimple<Key>&&)>(), "");
-
-  static_assert(can_hash<Hash(ConvertibleTo<Key>&)>(), "");
-  static_assert(can_hash<Hash(ConvertibleTo<Key> const&)>(), "");
-  static_assert(can_hash<Hash(ConvertibleTo<Key> &&)>(), "");
-  static_assert(can_hash<Hash(ConvertibleTo<Key> const&&)>(), "");
+  static_assert(can_hash<Hash, Key&>(), "");
+  static_assert(can_hash<Hash, Key const&>(), "");
+  static_assert(can_hash<Hash, Key&&>(), "");
+  static_assert(can_hash<Hash const, Key&>(), "");
+  static_assert(can_hash<Hash const, Key const&>(), "");
+  static_assert(can_hash<Hash const, Key&&>(), "");
+
+  static_assert(can_hash<Hash, ConvertibleToSimple<Key>&>(), "");
+  static_assert(can_hash<Hash, ConvertibleToSimple<Key> const&>(), "");
+  static_assert(can_hash<Hash, ConvertibleToSimple<Key>&&>(), "");
+
+  static_assert(can_hash<Hash, ConvertibleTo<Key>&>(), "");
+  static_assert(can_hash<Hash, ConvertibleTo<Key> const&>(), "");
+  static_assert(can_hash<Hash, ConvertibleTo<Key>&&>(), "");
+  static_assert(can_hash<Hash, ConvertibleTo<Key> const&&>(), "");
 
   const Hash h{};
   assert(h(key) == h(key));
@@ -186,21 +190,21 @@ void test_hash_disabled() {
     >::value, "");
 
   // Hashable requirements
-  static_assert(!can_hash<Hash(Key&)>(), "");
-  static_assert(!can_hash<Hash(Key const&)>(), "");
-  static_assert(!can_hash<Hash(Key&&)>(), "");
-  static_assert(!can_hash<Hash const&(Key&)>(), "");
-  static_assert(!can_hash<Hash const&(Key const&)>(), "");
-  static_assert(!can_hash<Hash const&(Key&&)>(), "");
-
-  static_assert(!can_hash<Hash(ConvertibleToSimple<Key>&)>(), "");
-  static_assert(!can_hash<Hash(ConvertibleToSimple<Key> const&)>(), "");
-  static_assert(!can_hash<Hash(ConvertibleToSimple<Key>&&)>(), "");
-
-  static_assert(!can_hash<Hash(ConvertibleTo<Key>&)>(), "");
-  static_assert(!can_hash<Hash(ConvertibleTo<Key> const&)>(), "");
-  static_assert(!can_hash<Hash(ConvertibleTo<Key> &&)>(), "");
-  static_assert(!can_hash<Hash(ConvertibleTo<Key> const&&)>(), "");
+  static_assert(!can_hash<Hash, Key&>(), "");
+  static_assert(!can_hash<Hash, Key const&>(), "");
+  static_assert(!can_hash<Hash, Key&&>(), "");
+  static_assert(!can_hash<Hash const, Key&>(), "");
+  static_assert(!can_hash<Hash const, Key const&>(), "");
+  static_assert(!can_hash<Hash const, Key&&>(), "");
+
+  static_assert(!can_hash<Hash, ConvertibleToSimple<Key>&>(), "");
+  static_assert(!can_hash<Hash, ConvertibleToSimple<Key> const&>(), "");
+  static_assert(!can_hash<Hash, ConvertibleToSimple<Key>&&>(), "");
+
+  static_assert(!can_hash<Hash, ConvertibleTo<Key>&>(), "");
+  static_assert(!can_hash<Hash, ConvertibleTo<Key> const&>(), "");
+  static_assert(!can_hash<Hash, ConvertibleTo<Key>&&>(), "");
+  static_assert(!can_hash<Hash, ConvertibleTo<Key> const&&>(), "");
 }
 
 


        


More information about the libcxx-commits mailing list