[libcxx-commits] [libcxx] 06e2b73 - [libc++] [P1032] Misc constexpr bits in <iterator>, <string_view>, <tuple>, <utility>.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Thu Mar 25 07:35:04 PDT 2021


Author: Arthur O'Dwyer
Date: 2021-03-25T10:34:35-04:00
New Revision: 06e2b737aa0347b42e8bf37cb00a053eab0a9393

URL: https://github.com/llvm/llvm-project/commit/06e2b737aa0347b42e8bf37cb00a053eab0a9393
DIFF: https://github.com/llvm/llvm-project/commit/06e2b737aa0347b42e8bf37cb00a053eab0a9393.diff

LOG: [libc++] [P1032] Misc constexpr bits in <iterator>, <string_view>, <tuple>, <utility>.

This completes the implementation of P1032's changes to <iterator>,
<string_view>, <tuple>, and <utility> in C++20.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1032r1.html

Drive-by fix a couple of unintended rvalues in "*iterators*/*.fail.cpp".

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

Added: 
    libcxx/test/support/test_constexpr_container.h

Modified: 
    libcxx/docs/Cxx2aStatusPaperStatus.csv
    libcxx/docs/FeatureTestMacroTable.rst
    libcxx/include/iterator
    libcxx/include/string_view
    libcxx/include/tuple
    libcxx/include/utility
    libcxx/include/version
    libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.cons/container.compile.fail.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/post.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/pre.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/lv_value.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/rv_value.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op_astrk/test.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.compile.fail.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/post.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/pre.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/lv_value.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/rv_value.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op_astrk/test.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.inserter/test.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.cons/test.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/post.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/pre.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op_astrk/test.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/inserter/test.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp
    libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
    libcxx/test/std/strings/string.view/string.view.ops/copy.pass.cpp
    libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp
    libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp
    libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp
    libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
    libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp
    libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp
    libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp
    libcxx/test/std/utilities/tuple/tuple.tuple/tuple.swap/member_swap.pass.cpp
    libcxx/test/std/utilities/utility/pairs/pair.piecewise/piecewise_construct.pass.cpp
    libcxx/utils/generate_feature_test_macro_components.py

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Cxx2aStatusPaperStatus.csv b/libcxx/docs/Cxx2aStatusPaperStatus.csv
index fd73d8978fc1..fa93be072c1b 100644
--- a/libcxx/docs/Cxx2aStatusPaperStatus.csv
+++ b/libcxx/docs/Cxx2aStatusPaperStatus.csv
@@ -68,7 +68,7 @@
 "`P1006R1 <https://wg21.link/P1006R1>`__","LWG","Constexpr in std::pointer_traits","San Diego","|Complete|","8.0"
 "`P1007R3 <https://wg21.link/P1007R3>`__","LWG","``std::assume_aligned``\ ","San Diego","* *",""
 "`P1020R1 <https://wg21.link/P1020R1>`__","LWG","Smart pointer creation with default initialization","San Diego","* *",""
-"`P1032R1 <https://wg21.link/P1032R1>`__","LWG","Misc constexpr bits","San Diego","* *",""
+"`P1032R1 <https://wg21.link/P1032R1>`__","LWG","Misc constexpr bits","San Diego","|Complete|","13.0"
 "`P1085R2 <https://wg21.link/P1085R2>`__","LWG","Should Span be Regular?","San Diego","|Complete|","8.0"
 "`P1123R0 <https://wg21.link/P1123R0>`__","LWG","Editorial Guidance for merging P0019r8 and P0528r3","San Diego","* *",""
 "`P1148R0 <https://wg21.link/P1148R0>`__","LWG","Cleaning up Clause 20","San Diego","* *",""

diff  --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 693a6683f702..40a6bdaf3a4b 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -208,17 +208,17 @@ Status
     ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_functional``                ``201907L``
     ------------------------------------------------- -----------------
-    ``__cpp_lib_constexpr_iterator``                  *unimplemented*
+    ``__cpp_lib_constexpr_iterator``                  ``201811L``
     ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_memory``                    ``201811L``
     ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_numeric``                   ``201911L``
     ------------------------------------------------- -----------------
-    ``__cpp_lib_constexpr_string``                    *unimplemented*
+    ``__cpp_lib_constexpr_string``                    ``201811L``
     ------------------------------------------------- -----------------
-    ``__cpp_lib_constexpr_string_view``               *unimplemented*
+    ``__cpp_lib_constexpr_string_view``               ``201811L``
     ------------------------------------------------- -----------------
-    ``__cpp_lib_constexpr_tuple``                     *unimplemented*
+    ``__cpp_lib_constexpr_tuple``                     ``201811L``
     ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_utility``                   ``201811L``
     ------------------------------------------------- -----------------

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index 684312e0dfc7..c02f5232880d 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -152,14 +152,14 @@ public:
     typedef void                        reference;
     typedef void                        pointer;
 
-    explicit back_insert_iterator(Container& x);
-    back_insert_iterator& operator=(const typename Container::value_type& value);
-    back_insert_iterator& operator*();
-    back_insert_iterator& operator++();
-    back_insert_iterator  operator++(int);
+    explicit back_insert_iterator(Container& x);  // constexpr in C++20
+    back_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
+    back_insert_iterator& operator*();  // constexpr in C++20
+    back_insert_iterator& operator++();  // constexpr in C++20
+    back_insert_iterator  operator++(int);  // constexpr in C++20
 };
 
-template <class Container> back_insert_iterator<Container> back_inserter(Container& x);
+template <class Container> back_insert_iterator<Container> back_inserter(Container& x);  // constexpr in C++20
 
 template <class Container>
 class front_insert_iterator
@@ -173,14 +173,14 @@ public:
     typedef void                         reference;
     typedef void                         pointer;
 
-    explicit front_insert_iterator(Container& x);
-    front_insert_iterator& operator=(const typename Container::value_type& value);
-    front_insert_iterator& operator*();
-    front_insert_iterator& operator++();
-    front_insert_iterator  operator++(int);
+    explicit front_insert_iterator(Container& x);  // constexpr in C++20
+    front_insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
+    front_insert_iterator& operator*();  // constexpr in C++20
+    front_insert_iterator& operator++();  // constexpr in C++20
+    front_insert_iterator  operator++(int);  // constexpr in C++20
 };
 
-template <class Container> front_insert_iterator<Container> front_inserter(Container& x);
+template <class Container> front_insert_iterator<Container> front_inserter(Container& x);  // constexpr in C++20
 
 template <class Container>
 class insert_iterator
@@ -195,15 +195,15 @@ public:
     typedef void                   reference;
     typedef void                   pointer;
 
-    insert_iterator(Container& x, typename Container::iterator i);
-    insert_iterator& operator=(const typename Container::value_type& value);
-    insert_iterator& operator*();
-    insert_iterator& operator++();
-    insert_iterator& operator++(int);
+    insert_iterator(Container& x, typename Container::iterator i);  // constexpr in C++20
+    insert_iterator& operator=(const typename Container::value_type& value);  // constexpr in C++20
+    insert_iterator& operator*();  // constexpr in C++20
+    insert_iterator& operator++();  // constexpr in C++20
+    insert_iterator& operator++(int);  // constexpr in C++20
 };
 
 template <class Container, class Iterator>
-insert_iterator<Container> inserter(Container& x, Iterator i);
+insert_iterator<Container> inserter(Container& x, Iterator i);  // constexpr in C++20
 
 template <class Iterator>
 class move_iterator {
@@ -932,20 +932,20 @@ protected:
 public:
     typedef _Container container_type;
 
-    _LIBCPP_INLINE_VISIBILITY explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
-    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(const typename _Container::value_type& __value_)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_)
         {container->push_back(__value_); return *this;}
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator=(typename _Container::value_type&& __value_)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(typename _Container::value_type&& __value_)
         {container->push_back(_VSTD::move(__value_)); return *this;}
 #endif  // _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator*()     {return *this;}
-    _LIBCPP_INLINE_VISIBILITY back_insert_iterator& operator++()    {return *this;}
-    _LIBCPP_INLINE_VISIBILITY back_insert_iterator  operator++(int) {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator  operator++(int) {return *this;}
 };
 
 template <class _Container>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 back_insert_iterator<_Container>
 back_inserter(_Container& __x)
 {
@@ -965,20 +965,20 @@ protected:
 public:
     typedef _Container container_type;
 
-    _LIBCPP_INLINE_VISIBILITY explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
-    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(const typename _Container::value_type& __value_)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_)
         {container->push_front(__value_); return *this;}
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator=(typename _Container::value_type&& __value_)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(typename _Container::value_type&& __value_)
         {container->push_front(_VSTD::move(__value_)); return *this;}
 #endif  // _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator*()     {return *this;}
-    _LIBCPP_INLINE_VISIBILITY front_insert_iterator& operator++()    {return *this;}
-    _LIBCPP_INLINE_VISIBILITY front_insert_iterator  operator++(int) {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator*()     {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator++()    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator  operator++(int) {return *this;}
 };
 
 template <class _Container>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 front_insert_iterator<_Container>
 front_inserter(_Container& __x)
 {
@@ -999,21 +999,21 @@ protected:
 public:
     typedef _Container container_type;
 
-    _LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i)
         : container(_VSTD::addressof(__x)), iter(__i) {}
-    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(const typename _Container::value_type& __value_)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_)
         {iter = container->insert(iter, __value_); ++iter; return *this;}
 #ifndef _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator=(typename _Container::value_type&& __value_)
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(typename _Container::value_type&& __value_)
         {iter = container->insert(iter, _VSTD::move(__value_)); ++iter; return *this;}
 #endif  // _LIBCPP_CXX03_LANG
-    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator*()        {return *this;}
-    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++()       {return *this;}
-    _LIBCPP_INLINE_VISIBILITY insert_iterator& operator++(int)    {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator*()        {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++()       {return *this;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator++(int)    {return *this;}
 };
 
 template <class _Container>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 insert_iterator<_Container>
 inserter(_Container& __x, typename _Container::iterator __i)
 {

diff  --git a/libcxx/include/string_view b/libcxx/include/string_view
index 6af16117ba5b..bc92dd5b1cb2 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -107,7 +107,7 @@ namespace std {
       constexpr void remove_suffix(size_type n);
       constexpr void swap(basic_string_view& s) noexcept;
 
-      size_type copy(charT* s, size_type n, size_type pos = 0) const;
+      size_type copy(charT* s, size_type n, size_type pos = 0) const;  // constexpr in C++20
 
       constexpr basic_string_view substr(size_type pos = 0, size_type n = npos) const;
       constexpr int compare(basic_string_view s) const noexcept;
@@ -359,7 +359,7 @@ public:
         __other.__size = __sz;
     }
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     size_type copy(_CharT* __s, size_type __n, size_type __pos = 0) const
     {
         if (__pos > size())

diff  --git a/libcxx/include/tuple b/libcxx/include/tuple
index b3d3bae69019..6e07892f9479 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -38,39 +38,39 @@ public:
     template <class Alloc>
         tuple(allocator_arg_t, const Alloc& a);
     template <class Alloc>
-        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...);
+        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...);          // constexpr in C++20
     template <class Alloc, class... U>
-        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...);
+        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...);               // constexpr in C++20
     template <class Alloc>
-        tuple(allocator_arg_t, const Alloc& a, const tuple&);
+        tuple(allocator_arg_t, const Alloc& a, const tuple&);                             // constexpr in C++20
     template <class Alloc>
-        tuple(allocator_arg_t, const Alloc& a, tuple&&);
+        tuple(allocator_arg_t, const Alloc& a, tuple&&);                                  // constexpr in C++20
     template <class Alloc, class... U>
-        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);
+        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);   // constexpr in C++20
     template <class Alloc, class... U>
-        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);
+        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);        // constexpr in C++20
     template <class Alloc, class U1, class U2>
-        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
+        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);  // constexpr in C++20
     template <class Alloc, class U1, class U2>
-        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
+        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);       // constexpr in C++20
 
-    tuple& operator=(const tuple&);
-    tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...);
+    tuple& operator=(const tuple&);                                                       // constexpr in C++20
+    tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...);           // constexpr in C++20
     template <class... U>
-        tuple& operator=(const tuple<U...>&);
+        tuple& operator=(const tuple<U...>&);                                             // constexpr in C++20
     template <class... U>
-        tuple& operator=(tuple<U...>&&);
+        tuple& operator=(tuple<U...>&&);                                                  // constexpr in C++20
     template <class U1, class U2>
-        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
+        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2                   // constexpr in C++20
     template <class U1, class U2>
-        tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2
+        tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2                        // constexpr in C++20
 
     template<class U, size_t N>
         tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
     template<class U, size_t N>
         tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
 
-    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
+    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));               // constexpr in C++20
 };
 
 template <class ...T>
@@ -174,7 +174,7 @@ template <size_t _Ip, class _Hp,
 class __tuple_leaf;
 
 template <size_t _Ip, class _Hp, bool _Ep>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
     _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
 {
@@ -195,29 +195,30 @@ class __tuple_leaf
 #endif
     }
 
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
     __tuple_leaf& operator=(const __tuple_leaf&);
 public:
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
+    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
              _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
        {static_assert(!is_reference<_Hp>::value,
               "Attempted to default construct a reference element in a tuple");}
 
     template <class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY constexpr
         __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
             : __value_()
         {static_assert(!is_reference<_Hp>::value,
               "Attempted to default construct a reference element in a tuple");}
 
     template <class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY constexpr
         __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
             : __value_(allocator_arg_t(), __a)
         {static_assert(!is_reference<_Hp>::value,
               "Attempted to default construct a reference element in a tuple");}
 
     template <class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY constexpr
         __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
             : __value_(__a)
         {static_assert(!is_reference<_Hp>::value,
@@ -238,21 +239,21 @@ public:
        "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
 
     template <class _Tp, class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
             : __value_(_VSTD::forward<_Tp>(__t))
         {static_assert(__can_bind_reference<_Tp&&>(),
        "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
 
     template <class _Tp, class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
             : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
         {static_assert(!is_reference<_Hp>::value,
             "Attempted to uses-allocator construct a reference element in a tuple");}
 
     template <class _Tp, class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
             : __value_(_VSTD::forward<_Tp>(__t), __a)
         {static_assert(!is_reference<_Hp>::value,
@@ -261,7 +262,7 @@ public:
     __tuple_leaf(const __tuple_leaf& __t) = default;
     __tuple_leaf(__tuple_leaf&& __t) = default;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
     {
         _VSTD::swap(*this, __t);
@@ -276,23 +277,23 @@ template <size_t _Ip, class _Hp>
 class __tuple_leaf<_Ip, _Hp, true>
     : private _Hp
 {
-
+    _LIBCPP_CONSTEXPR_AFTER_CXX11
     __tuple_leaf& operator=(const __tuple_leaf&);
 public:
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
+    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
              _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
 
     template <class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY constexpr
         __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
 
     template <class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY constexpr
         __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
             : _Hp(allocator_arg_t(), __a) {}
 
     template <class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY constexpr
         __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
             : _Hp(__a) {}
 
@@ -309,24 +310,24 @@ public:
             : _Hp(_VSTD::forward<_Tp>(__t)) {}
 
     template <class _Tp, class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY constexpr
         explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
             : _Hp(_VSTD::forward<_Tp>(__t)) {}
 
     template <class _Tp, class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY constexpr
         explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
             : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
 
     template <class _Tp, class _Alloc>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY constexpr
         explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
             : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
 
     __tuple_leaf(__tuple_leaf const &) = default;
     __tuple_leaf(__tuple_leaf &&) = default;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     int
     swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
     {
@@ -339,7 +340,7 @@ public:
 };
 
 template <class ..._Tp>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 void __swallow(_Tp&&...) _NOEXCEPT {}
 
 template <class _Tp>
@@ -359,7 +360,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
     : public __tuple_leaf<_Indx, _Tp>...
 {
     _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR __tuple_impl()
+    constexpr __tuple_impl()
         _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
 
     template <size_t ..._Uf, class ..._Tf,
@@ -377,7 +378,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
 
     template <class _Alloc, size_t ..._Uf, class ..._Tf,
               size_t ..._Ul, class ..._Tl, class ..._Up>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         explicit
         __tuple_impl(allocator_arg_t, const _Alloc& __a,
                      __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
@@ -407,7 +408,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
                          __tuple_constructible<_Tuple, tuple<_Tp...> >::value
                       >::type
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
         __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
             : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
                                        typename __make_tuple_types<_Tuple>::type>::type>(), __a,
@@ -418,7 +419,7 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
     __tuple_impl(const __tuple_impl&) = default;
     __tuple_impl(__tuple_impl&&) = default;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     void swap(__tuple_impl& __t)
         _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
     {
@@ -427,13 +428,13 @@ struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp.
 };
 
 template<class _Dest, class _Source, size_t ..._Np>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
     _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
 }
 
 template<class _Dest, class _Source, class ..._Up, size_t ..._Np>
-_LIBCPP_INLINE_VISIBILITY
+_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
     _VSTD::__swallow(((
         _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
@@ -619,14 +620,14 @@ public:
     template <bool _Dummy = true, _EnableIf<
         _CheckArgsConstructor<_Dummy>::__enable_implicit_default()
     , void*> = nullptr>
-    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    _LIBCPP_INLINE_VISIBILITY constexpr
     tuple()
         _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
 
     template <bool _Dummy = true, _EnableIf<
         _CheckArgsConstructor<_Dummy>::__enable_explicit_default()
     , void*> = nullptr>
-    explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
+    explicit _LIBCPP_INLINE_VISIBILITY constexpr
     tuple()
         _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
 
@@ -637,7 +638,7 @@ public:
              _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value >::__enable_implicit_default()
       , void*> = nullptr
     >
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple(_AllocArgT, _Alloc const& __a)
       : __base_(allocator_arg_t(), __a,
                     __tuple_indices<>(), __tuple_types<>(),
@@ -648,7 +649,7 @@ public:
              _CheckArgsConstructor<_IsSame<allocator_arg_t, _AllocArgT>::value>::__enable_explicit_default()
       , void*> = nullptr
     >
-    explicit _LIBCPP_INLINE_VISIBILITY
+    explicit _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple(_AllocArgT, _Alloc const& __a)
       : __base_(allocator_arg_t(), __a,
                     __tuple_indices<>(), __tuple_types<>(),
@@ -700,7 +701,7 @@ public:
                          bool
                       >::type = false
         >
-      _LIBCPP_INLINE_VISIBILITY
+      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
       tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
         : __base_(allocator_arg_t(), __a,
                 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
@@ -719,7 +720,7 @@ public:
                          bool
                       >::type = false
         >
-      _LIBCPP_INLINE_VISIBILITY
+      _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
       explicit
       tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
         : __base_(allocator_arg_t(), __a,
@@ -806,7 +807,7 @@ public:
                          bool
                       >::type = false
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
             : __base_(allocator_arg_t(), __a,
                     typename __make_tuple_indices<sizeof...(_Up)>::type(),
@@ -825,7 +826,7 @@ public:
                          bool
                       >::type = false
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         explicit
         tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
             : __base_(allocator_arg_t(), __a,
@@ -865,7 +866,7 @@ public:
                          bool
                       >::type = false
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
             : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
 
@@ -878,13 +879,13 @@ public:
                          bool
                       >::type = false
              >
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         explicit
         tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
             : __base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
 
     // [tuple.assign]
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
         _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
     {
@@ -893,7 +894,7 @@ public:
         return *this;
     }
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
         _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
     {
@@ -909,7 +910,7 @@ public:
             is_assignable<_Tp&, _Up const&>...
         >::value
     ,int> = 0>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple& operator=(tuple<_Up...> const& __tuple)
         _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
     {
@@ -924,7 +925,7 @@ public:
             is_assignable<_Tp&, _Up>...
         >::value
     ,int> = 0>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple& operator=(tuple<_Up...>&& __tuple)
         _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
     {
@@ -941,7 +942,7 @@ public:
             is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
         >::value
     ,int> = 0>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple& operator=(pair<_Up1, _Up2> const& __pair)
         _NOEXCEPT_((_And<
             is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
@@ -960,7 +961,7 @@ public:
             is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
         >::value
     ,int> = 0>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple& operator=(pair<_Up1, _Up2>&& __pair)
         _NOEXCEPT_((_And<
             is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
@@ -979,7 +980,7 @@ public:
             is_assignable<_Tp&, _Up const&>...
         >::value
     > >
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple& operator=(array<_Up, _Np> const& __array)
         _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
     {
@@ -995,7 +996,7 @@ public:
             is_assignable<_Tp&, _Up>...
         >::value
     > >
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     tuple& operator=(array<_Up, _Np>&& __array)
         _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
     {
@@ -1006,7 +1007,7 @@ public:
     }
 
     // [tuple.swap]
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
         {__base_.swap(__t.__base_);}
 };
@@ -1015,21 +1016,21 @@ template <>
 class _LIBCPP_TEMPLATE_VIS tuple<>
 {
 public:
-    _LIBCPP_INLINE_VISIBILITY
-    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT = default;
+    _LIBCPP_INLINE_VISIBILITY constexpr
+        tuple() _NOEXCEPT = default;
     template <class _Alloc>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
     template <class _Alloc>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
     template <class _Up>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         tuple(array<_Up, 0>) _NOEXCEPT {}
     template <class _Alloc, class _Up>
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
         tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
     void swap(tuple&) _NOEXCEPT {}
 };
 
@@ -1047,7 +1048,7 @@ tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
 #endif
 
 template <class ..._Tp>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
 typename enable_if
 <
     __all<__is_swappable<_Tp>::value...>::value,

diff  --git a/libcxx/include/utility b/libcxx/include/utility
index ca3d3fe7dbaa..181919c15ef2 100644
--- a/libcxx/include/utility
+++ b/libcxx/include/utility
@@ -76,15 +76,15 @@ struct pair
     template <class U, class V> explicit(see-below) pair(pair<U, V>&& p);        // constexpr in C++14
     template <class... Args1, class... Args2>
         pair(piecewise_construct_t, tuple<Args1...> first_args,
-             tuple<Args2...> second_args);
+             tuple<Args2...> second_args);                                       // constexpr in C++20
 
-    template <class U, class V> pair& operator=(const pair<U, V>& p);
+    template <class U, class V> pair& operator=(const pair<U, V>& p);            // constexpr in C++20
     pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value &&
-                                       is_nothrow_move_assignable<T2>::value);
-    template <class U, class V> pair& operator=(pair<U, V>&& p);
+                                       is_nothrow_move_assignable<T2>::value);   // constexpr in C++20
+    template <class U, class V> pair& operator=(pair<U, V>&& p);                 // constexpr in C++20
 
     void swap(pair& p) noexcept(is_nothrow_swappable_v<T1> &&
-                                is_nothrow_swappable_v<T2>);
+                                is_nothrow_swappable_v<T2>);                     // constexpr in C++20
 };
 
 template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
@@ -94,10 +94,10 @@ template <class T1, class T2> bool operator> (const pair<T1,T2>&, const pair<T1,
 template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
 template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); // constexpr in C++14
 
-template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&);   // constexpr in C++14
+template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&);                // constexpr in C++14
 template <class T1, class T2>
 void
-swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));
+swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y)));            // constexpr in C++20
 
 struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
 inline constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();

diff  --git a/libcxx/include/version b/libcxx/include/version
index 469f1cea82b4..040d72e1254b 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -56,7 +56,7 @@ __cpp_lib_constexpr_functional                          201907L <functional>
 __cpp_lib_constexpr_iterator                            201811L <iterator>
 __cpp_lib_constexpr_memory                              201811L <memory>
 __cpp_lib_constexpr_numeric                             201911L <numeric>
-__cpp_lib_constexpr_string                              201907L <string>
+__cpp_lib_constexpr_string                              201811L <string>
 __cpp_lib_constexpr_string_view                         201811L <string_view>
 __cpp_lib_constexpr_tuple                               201811L <tuple>
 __cpp_lib_constexpr_utility                             201811L <utility>
@@ -303,12 +303,12 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_constexpr_complex                    201711L
 # define __cpp_lib_constexpr_dynamic_alloc              201907L
 # define __cpp_lib_constexpr_functional                 201907L
-// # define __cpp_lib_constexpr_iterator                   201811L
+# define __cpp_lib_constexpr_iterator                   201811L
 # define __cpp_lib_constexpr_memory                     201811L
 # define __cpp_lib_constexpr_numeric                    201911L
-// # define __cpp_lib_constexpr_string                     201907L
-// # define __cpp_lib_constexpr_string_view                201811L
-// # define __cpp_lib_constexpr_tuple                      201811L
+# define __cpp_lib_constexpr_string                     201811L
+# define __cpp_lib_constexpr_string_view                201811L
+# define __cpp_lib_constexpr_tuple                      201811L
 # define __cpp_lib_constexpr_utility                    201811L
 // # define __cpp_lib_constexpr_vector                     201907L
 // # define __cpp_lib_coroutine                            201902L

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.cons/container.compile.fail.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.cons/container.compile.fail.cpp
index 9aad14992f56..42aab385ce4b 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.cons/container.compile.fail.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.cons/container.compile.fail.cpp
@@ -19,7 +19,8 @@
 
 int main(int, char**)
 {
-    std::back_insert_iterator<std::vector<int> > i = std::vector<int>();
+    std::vector<int> v;
+    std::back_insert_iterator<std::vector<int> > i = v;
 
   return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/post.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/post.pass.cpp
index c6f93d222830..4157f45c0bb3 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/post.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/post.pass.cpp
@@ -15,12 +15,13 @@
 #include <iterator>
 #include <vector>
 #include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::back_insert_iterator<C> i(c);
@@ -28,12 +29,16 @@ test(C c)
     r = 0;
     assert(c.size() == 1);
     assert(c.back() == 0);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::vector<int>());
     test(nasty_vector<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/pre.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/pre.pass.cpp
index a104d46b4dd4..d0d043fe75b8 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/pre.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op++/pre.pass.cpp
@@ -12,26 +12,31 @@
 
 // back_insert_iterator<Cont>& operator++();
 
+#include <cassert>
 #include <iterator>
 #include <vector>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::back_insert_iterator<C> i(c);
     std::back_insert_iterator<C>& r = ++i;
     assert(&r == &i);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::vector<int>());
     test(nasty_vector<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/lv_value.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/lv_value.pass.cpp
index 9e8cad2bb387..d1e7c7897c8e 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/lv_value.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/lv_value.pass.cpp
@@ -19,15 +19,17 @@
 #include <cassert>
 
 #include "test_macros.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX14 bool
 test(C c)
 {
     const typename C::value_type v = typename C::value_type();
     std::back_insert_iterator<C> i(c);
     i = v;
     assert(c.back() == v);
+    return true;
 }
 
 class Copyable
@@ -44,6 +46,9 @@ class Copyable
 int main(int, char**)
 {
     test(std::vector<Copyable>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/rv_value.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/rv_value.pass.cpp
index 14d397755521..8b0355cc6c15 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/rv_value.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op=/rv_value.pass.cpp
@@ -23,19 +23,24 @@
 #include <cassert>
 
 #include "test_macros.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX14 bool
 test(C c)
 {
     std::back_insert_iterator<C> i(c);
     i = typename C::value_type();
     assert(c.back() == typename C::value_type());
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::vector<std::unique_ptr<int> >());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op_astrk/test.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op_astrk/test.pass.cpp
index 22180f5a6f15..35d399e0068e 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op_astrk/test.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iter.ops/back.insert.iter.op_astrk/test.pass.cpp
@@ -12,26 +12,31 @@
 
 // back_insert_iterator<Cont>& operator*();
 
+#include <cassert>
 #include <iterator>
 #include <vector>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::back_insert_iterator<C> i(c);
     std::back_insert_iterator<C>& r = *i;
     assert(&r == &i);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::vector<int>());
     test(nasty_vector<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.compile.fail.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.compile.fail.cpp
index eb3346b2e7ae..7ff5e6eb05fa 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.compile.fail.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.compile.fail.cpp
@@ -19,7 +19,8 @@
 
 int main(int, char**)
 {
-    std::front_insert_iterator<std::list<int> > i = std::list<int>();
+    std::list<int> l;
+    std::front_insert_iterator<std::list<int> > i = l;
 
   return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.pass.cpp
index 7fac5f31a99e..ccdb444f11b3 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.cons/container.pass.cpp
@@ -14,21 +14,26 @@
 
 #include <iterator>
 #include <list>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::front_insert_iterator<C> i(c);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::list<int>());
     test(nasty_list<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/post.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/post.pass.cpp
index 44a42713a2b2..f67e5d4629a5 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/post.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/post.pass.cpp
@@ -12,15 +12,16 @@
 
 // front_insert_iterator<Cont> operator++(int);
 
+#include <cassert>
 #include <iterator>
 #include <list>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::front_insert_iterator<C> i(c);
@@ -28,12 +29,16 @@ test(C c)
     r = 0;
     assert(c.size() == 1);
     assert(c.back() == 0);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::list<int>());
     test(nasty_list<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/pre.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/pre.pass.cpp
index ac58374ae417..e21f9078c450 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/pre.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op++/pre.pass.cpp
@@ -12,26 +12,31 @@
 
 // front_insert_iterator<Cont>& operator++();
 
+#include <cassert>
 #include <iterator>
 #include <list>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::front_insert_iterator<C> i(c);
     std::front_insert_iterator<C>& r = ++i;
     assert(&r == &i);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::list<int>());
     test(nasty_list<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/lv_value.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/lv_value.pass.cpp
index ceeacb4bf452..922a95b931d4 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/lv_value.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/lv_value.pass.cpp
@@ -13,21 +13,23 @@
 // front_insert_iterator<Cont>&
 //   operator=(const Cont::value_type& value);
 
+#include <cassert>
 #include <iterator>
 #include <list>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     const typename C::value_type v = typename C::value_type();
     std::front_insert_iterator<C> i(c);
     i = v;
     assert(c.front() == v);
+    return true;
 }
 
 class Copyable
@@ -45,6 +47,9 @@ int main(int, char**)
 {
     test(std::list<Copyable>());
     test(nasty_list<Copyable>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/rv_value.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/rv_value.pass.cpp
index a2c7f4b1de6d..fe12cff7df56 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/rv_value.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op=/rv_value.pass.cpp
@@ -15,25 +15,30 @@
 // front_insert_iterator<Cont>&
 //   operator=(Cont::value_type&& value);
 
+#include <cassert>
 #include <iterator>
 #include <list>
 #include <memory>
-#include <cassert>
 
 #include "test_macros.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::front_insert_iterator<C> i(c);
     i = typename C::value_type();
     assert(c.front() == typename C::value_type());
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::list<std::unique_ptr<int> >());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op_astrk/test.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op_astrk/test.pass.cpp
index 1c2e62ebf3e4..d4d5351ac7b9 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op_astrk/test.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.insert.iter.op_astrk/test.pass.cpp
@@ -12,26 +12,31 @@
 
 // front_insert_iterator<Cont>& operator*();
 
+#include <cassert>
 #include <iterator>
 #include <list>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::front_insert_iterator<C> i(c);
     std::front_insert_iterator<C>& r = *i;
     assert(&r == &i);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::list<int>());
     test(nasty_list<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.inserter/test.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.inserter/test.pass.cpp
index e7e09c9998f8..f27178941936 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.inserter/test.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iter.ops/front.inserter/test.pass.cpp
@@ -12,27 +12,32 @@
 //   front_insert_iterator<Cont>
 //   front_inserter(Cont& x);
 
+#include <cassert>
 #include <iterator>
 #include <list>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::front_insert_iterator<C> i = std::front_inserter(c);
     i = 0;
     assert(c.size() == 1);
     assert(c.front() == 0);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::list<int>());
     test(nasty_list<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.cons/test.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.cons/test.pass.cpp
index c8650e400ee1..8def436a0cc9 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.cons/test.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.cons/test.pass.cpp
@@ -14,21 +14,26 @@
 
 #include <iterator>
 #include <vector>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::insert_iterator<C> i(c, c.begin());
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::vector<int>());
     test(nasty_vector<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/post.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/post.pass.cpp
index e8a1780a40b8..3447df97993a 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/post.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/post.pass.cpp
@@ -12,15 +12,16 @@
 
 // insert_iterator<Cont> operator++(int);
 
+#include <cassert>
 #include <iterator>
 #include <vector>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::insert_iterator<C> i(c, c.end());
@@ -28,12 +29,16 @@ test(C c)
     r = 0;
     assert(c.size() == 1);
     assert(c.back() == 0);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::vector<int>());
     test(nasty_vector<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/pre.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/pre.pass.cpp
index 5f6a359d2ed3..0bfb5724e6eb 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/pre.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op++/pre.pass.cpp
@@ -12,26 +12,31 @@
 
 // insert_iterator<Cont>& operator++();
 
+#include <cassert>
 #include <iterator>
 #include <vector>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::insert_iterator<C> i(c, c.end());
     std::insert_iterator<C>& r = ++i;
     assert(&r == &i);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::vector<int>());
     test(nasty_vector<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op_astrk/test.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op_astrk/test.pass.cpp
index 57080a26c8fa..d63497b6409e 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op_astrk/test.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/insert.iter.op_astrk/test.pass.cpp
@@ -12,26 +12,31 @@
 
 // insert_iterator<Cont>& operator*();
 
+#include <cassert>
 #include <iterator>
 #include <vector>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::insert_iterator<C> i(c, c.end());
     std::insert_iterator<C>& r = *i;
     assert(&r == &i);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::vector<int>());
     test(nasty_vector<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/inserter/test.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/inserter/test.pass.cpp
index 77916a496fcf..088989fe96c1 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/inserter/test.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iter.ops/inserter/test.pass.cpp
@@ -12,27 +12,32 @@
 //   insert_iterator<Cont>
 //   inserter(Cont& x, Cont::iterator i);
 
+#include <cassert>
 #include <iterator>
 #include <vector>
-#include <cassert>
-#include "nasty_containers.h"
 
 #include "test_macros.h"
+#include "nasty_containers.h"
+#include "test_constexpr_container.h"
 
 template <class C>
-void
+TEST_CONSTEXPR_CXX20 bool
 test(C c)
 {
     std::insert_iterator<C> i = std::inserter(c, c.end());
     i = 0;
     assert(c.size() == 1);
     assert(c.back() == 0);
+    return true;
 }
 
 int main(int, char**)
 {
     test(std::vector<int>());
     test(nasty_vector<int>());
-
-  return 0;
+#if TEST_STD_VER >= 20
+    test(ConstexprFixedCapacityDeque<int, 10>());
+    static_assert(test(ConstexprFixedCapacityDeque<int, 10>()));
+#endif
+    return 0;
 }

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp
index 27318c51a0a0..4234cc9a142d 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.pass.cpp
@@ -146,17 +146,11 @@
 #   error "__cpp_lib_array_constexpr should have the value 201811L in c++20"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_iterator
-#     error "__cpp_lib_constexpr_iterator should be defined in c++20"
-#   endif
-#   if __cpp_lib_constexpr_iterator != 201811L
-#     error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_iterator
-#     error "__cpp_lib_constexpr_iterator should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_iterator
+#   error "__cpp_lib_constexpr_iterator should be defined in c++20"
+# endif
+# if __cpp_lib_constexpr_iterator != 201811L
+#   error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
 # endif
 
 # ifndef __cpp_lib_make_reverse_iterator
@@ -209,17 +203,11 @@
 #   error "__cpp_lib_array_constexpr should have the value 201811L in c++2b"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_iterator
-#     error "__cpp_lib_constexpr_iterator should be defined in c++2b"
-#   endif
-#   if __cpp_lib_constexpr_iterator != 201811L
-#     error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_iterator
-#     error "__cpp_lib_constexpr_iterator should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_iterator
+#   error "__cpp_lib_constexpr_iterator should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_iterator != 201811L
+#   error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
 # endif
 
 # ifndef __cpp_lib_make_reverse_iterator

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp
index f65078736f8f..165744010499 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/string.version.pass.cpp
@@ -18,7 +18,7 @@
 /*  Constant                                      Value
     __cpp_lib_allocator_traits_is_always_equal    201411L [C++17]
     __cpp_lib_char8_t                             201811L [C++20]
-    __cpp_lib_constexpr_string                    201907L [C++20]
+    __cpp_lib_constexpr_string                    201811L [C++20]
     __cpp_lib_erase_if                            202002L [C++20]
     __cpp_lib_nonmember_container_access          201411L [C++17]
     __cpp_lib_starts_ends_with                    201711L [C++20]
@@ -182,17 +182,11 @@
 #   endif
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_string
-#     error "__cpp_lib_constexpr_string should be defined in c++20"
-#   endif
-#   if __cpp_lib_constexpr_string != 201907L
-#     error "__cpp_lib_constexpr_string should have the value 201907L in c++20"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_string
-#     error "__cpp_lib_constexpr_string should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_string
+#   error "__cpp_lib_constexpr_string should be defined in c++20"
+# endif
+# if __cpp_lib_constexpr_string != 201811L
+#   error "__cpp_lib_constexpr_string should have the value 201811L in c++20"
 # endif
 
 # ifndef __cpp_lib_erase_if
@@ -256,17 +250,11 @@
 #   endif
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_string
-#     error "__cpp_lib_constexpr_string should be defined in c++2b"
-#   endif
-#   if __cpp_lib_constexpr_string != 201907L
-#     error "__cpp_lib_constexpr_string should have the value 201907L in c++2b"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_string
-#     error "__cpp_lib_constexpr_string should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_string
+#   error "__cpp_lib_constexpr_string should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_string != 201811L
+#   error "__cpp_lib_constexpr_string should have the value 201811L in c++2b"
 # endif
 
 # ifndef __cpp_lib_erase_if

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp
index 30c351888c08..22d9297cca51 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/string_view.version.pass.cpp
@@ -111,17 +111,11 @@
 #   endif
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_string_view
-#     error "__cpp_lib_constexpr_string_view should be defined in c++20"
-#   endif
-#   if __cpp_lib_constexpr_string_view != 201811L
-#     error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_string_view
-#     error "__cpp_lib_constexpr_string_view should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_string_view
+#   error "__cpp_lib_constexpr_string_view should be defined in c++20"
+# endif
+# if __cpp_lib_constexpr_string_view != 201811L
+#   error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
 # endif
 
 # ifndef __cpp_lib_starts_ends_with
@@ -157,17 +151,11 @@
 #   endif
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_string_view
-#     error "__cpp_lib_constexpr_string_view should be defined in c++2b"
-#   endif
-#   if __cpp_lib_constexpr_string_view != 201811L
-#     error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_string_view
-#     error "__cpp_lib_constexpr_string_view should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_string_view
+#   error "__cpp_lib_constexpr_string_view should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_string_view != 201811L
+#   error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
 # endif
 
 # ifndef __cpp_lib_starts_ends_with

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp
index ef9f61428782..5d870a8cd0c1 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/tuple.version.pass.cpp
@@ -119,17 +119,11 @@
 #   error "__cpp_lib_apply should have the value 201603L in c++20"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_tuple
-#     error "__cpp_lib_constexpr_tuple should be defined in c++20"
-#   endif
-#   if __cpp_lib_constexpr_tuple != 201811L
-#     error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_tuple
-#     error "__cpp_lib_constexpr_tuple should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_tuple
+#   error "__cpp_lib_constexpr_tuple should be defined in c++20"
+# endif
+# if __cpp_lib_constexpr_tuple != 201811L
+#   error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
 # endif
 
 # ifndef __cpp_lib_make_from_tuple
@@ -162,17 +156,11 @@
 #   error "__cpp_lib_apply should have the value 201603L in c++2b"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_tuple
-#     error "__cpp_lib_constexpr_tuple should be defined in c++2b"
-#   endif
-#   if __cpp_lib_constexpr_tuple != 201811L
-#     error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_tuple
-#     error "__cpp_lib_constexpr_tuple should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_tuple
+#   error "__cpp_lib_constexpr_tuple should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_tuple != 201811L
+#   error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
 # endif
 
 # ifndef __cpp_lib_make_from_tuple

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
index 023f8c1b2317..83b286b05630 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
@@ -53,7 +53,7 @@
     __cpp_lib_constexpr_iterator                   201811L [C++20]
     __cpp_lib_constexpr_memory                     201811L [C++20]
     __cpp_lib_constexpr_numeric                    201911L [C++20]
-    __cpp_lib_constexpr_string                     201907L [C++20]
+    __cpp_lib_constexpr_string                     201811L [C++20]
     __cpp_lib_constexpr_string_view                201811L [C++20]
     __cpp_lib_constexpr_tuple                      201811L [C++20]
     __cpp_lib_constexpr_utility                    201811L [C++20]
@@ -2436,17 +2436,11 @@
 #   error "__cpp_lib_constexpr_functional should have the value 201907L in c++20"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_iterator
-#     error "__cpp_lib_constexpr_iterator should be defined in c++20"
-#   endif
-#   if __cpp_lib_constexpr_iterator != 201811L
-#     error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_iterator
-#     error "__cpp_lib_constexpr_iterator should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_iterator
+#   error "__cpp_lib_constexpr_iterator should be defined in c++20"
+# endif
+# if __cpp_lib_constexpr_iterator != 201811L
+#   error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20"
 # endif
 
 # ifndef __cpp_lib_constexpr_memory
@@ -2463,43 +2457,25 @@
 #   error "__cpp_lib_constexpr_numeric should have the value 201911L in c++20"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_string
-#     error "__cpp_lib_constexpr_string should be defined in c++20"
-#   endif
-#   if __cpp_lib_constexpr_string != 201907L
-#     error "__cpp_lib_constexpr_string should have the value 201907L in c++20"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_string
-#     error "__cpp_lib_constexpr_string should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_string
+#   error "__cpp_lib_constexpr_string should be defined in c++20"
+# endif
+# if __cpp_lib_constexpr_string != 201811L
+#   error "__cpp_lib_constexpr_string should have the value 201811L in c++20"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_string_view
-#     error "__cpp_lib_constexpr_string_view should be defined in c++20"
-#   endif
-#   if __cpp_lib_constexpr_string_view != 201811L
-#     error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_string_view
-#     error "__cpp_lib_constexpr_string_view should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_string_view
+#   error "__cpp_lib_constexpr_string_view should be defined in c++20"
+# endif
+# if __cpp_lib_constexpr_string_view != 201811L
+#   error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_tuple
-#     error "__cpp_lib_constexpr_tuple should be defined in c++20"
-#   endif
-#   if __cpp_lib_constexpr_tuple != 201811L
-#     error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_tuple
-#     error "__cpp_lib_constexpr_tuple should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_tuple
+#   error "__cpp_lib_constexpr_tuple should be defined in c++20"
+# endif
+# if __cpp_lib_constexpr_tuple != 201811L
+#   error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20"
 # endif
 
 # ifndef __cpp_lib_constexpr_utility
@@ -3647,17 +3623,11 @@
 #   error "__cpp_lib_constexpr_functional should have the value 201907L in c++2b"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_iterator
-#     error "__cpp_lib_constexpr_iterator should be defined in c++2b"
-#   endif
-#   if __cpp_lib_constexpr_iterator != 201811L
-#     error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_iterator
-#     error "__cpp_lib_constexpr_iterator should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_iterator
+#   error "__cpp_lib_constexpr_iterator should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_iterator != 201811L
+#   error "__cpp_lib_constexpr_iterator should have the value 201811L in c++2b"
 # endif
 
 # ifndef __cpp_lib_constexpr_memory
@@ -3674,43 +3644,25 @@
 #   error "__cpp_lib_constexpr_numeric should have the value 201911L in c++2b"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_string
-#     error "__cpp_lib_constexpr_string should be defined in c++2b"
-#   endif
-#   if __cpp_lib_constexpr_string != 201907L
-#     error "__cpp_lib_constexpr_string should have the value 201907L in c++2b"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_string
-#     error "__cpp_lib_constexpr_string should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_string
+#   error "__cpp_lib_constexpr_string should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_string != 201811L
+#   error "__cpp_lib_constexpr_string should have the value 201811L in c++2b"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_string_view
-#     error "__cpp_lib_constexpr_string_view should be defined in c++2b"
-#   endif
-#   if __cpp_lib_constexpr_string_view != 201811L
-#     error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_string_view
-#     error "__cpp_lib_constexpr_string_view should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_string_view
+#   error "__cpp_lib_constexpr_string_view should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_string_view != 201811L
+#   error "__cpp_lib_constexpr_string_view should have the value 201811L in c++2b"
 # endif
 
-# if !defined(_LIBCPP_VERSION)
-#   ifndef __cpp_lib_constexpr_tuple
-#     error "__cpp_lib_constexpr_tuple should be defined in c++2b"
-#   endif
-#   if __cpp_lib_constexpr_tuple != 201811L
-#     error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
-#   endif
-# else // _LIBCPP_VERSION
-#   ifdef __cpp_lib_constexpr_tuple
-#     error "__cpp_lib_constexpr_tuple should not be defined because it is unimplemented in libc++!"
-#   endif
+# ifndef __cpp_lib_constexpr_tuple
+#   error "__cpp_lib_constexpr_tuple should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_tuple != 201811L
+#   error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
 # endif
 
 # ifndef __cpp_lib_constexpr_utility

diff  --git a/libcxx/test/std/strings/string.view/string.view.ops/copy.pass.cpp b/libcxx/test/std/strings/string.view/string.view.ops/copy.pass.cpp
index e96650992cba..300650c5c4fa 100644
--- a/libcxx/test/std/strings/string.view/string.view.ops/copy.pass.cpp
+++ b/libcxx/test/std/strings/string.view/string.view.ops/copy.pass.cpp
@@ -6,6 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+// XFAIL: gcc-10
+//     GCC's __builtin_strlen isn't constexpr yet
+
 // <string_view>
 
 // size_type copy(charT* s, size_type n, size_type pos = 0) const;
@@ -74,7 +77,16 @@ void test ( const CharT *s ) {
     test1(sv1, sv1.size() + 1, 0);
     test1(sv1, sv1.size() + 1, 1);
     test1(sv1, sv1.size() + 1, string_view_t::npos);
+}
 
+template<typename CharT>
+TEST_CONSTEXPR_CXX20 bool test_constexpr_copy(const CharT *abcde, const CharT *ghijk, const CharT *bcdjk)
+{
+    CharT buf[6] = {};
+    std::basic_string_view<CharT> lval(ghijk); lval.copy(buf, 6);
+    std::basic_string_view<CharT>(abcde).copy(buf, 3, 1);
+    assert(std::basic_string_view<CharT>(buf) == bcdjk);
+    return true;
 }
 
 int main(int, char**) {
@@ -100,5 +112,22 @@ int main(int, char**) {
     test ( U"" );
 #endif
 
+    test_constexpr_copy("ABCDE", "GHIJK", "BCDJK");
+    test_constexpr_copy(L"ABCDE", L"GHIJK", L"BCDJK");
+#if TEST_STD_VER >= 11
+    test_constexpr_copy(u"ABCDE", u"GHIJK", u"BCDJK");
+    test_constexpr_copy(U"ABCDE", U"GHIJK", U"BCDJK");
+#endif
+#if TEST_STD_VER >= 17
+    test_constexpr_copy(u8"ABCDE", u8"GHIJK", u8"BCDJK");
+#endif
+#if TEST_STD_VER >= 20
+    static_assert(test_constexpr_copy("ABCDE", "GHIJK", "BCDJK"));
+    static_assert(test_constexpr_copy(L"ABCDE", L"GHIJK", L"BCDJK"));
+    static_assert(test_constexpr_copy(u"ABCDE", u"GHIJK", u"BCDJK"));
+    static_assert(test_constexpr_copy(U"ABCDE", U"GHIJK", U"BCDJK"));
+    static_assert(test_constexpr_copy(u8"ABCDE", u8"GHIJK", u8"BCDJK"));
+#endif
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp
index 02c59948d7f8..e922d70062b8 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/const_pair.pass.cpp
@@ -30,7 +30,8 @@ struct PotentiallyThrowingCopyAssignable {
 
 #include "test_macros.h"
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
         typedef std::pair<long, char> T0;
@@ -41,6 +42,16 @@ int main(int, char**)
         assert(std::get<0>(t1) == 2);
         assert(std::get<1>(t1) == short('a'));
     }
+    return true;
+}
+
+int main(int, char**)
+{
+    test();
+#if TEST_STD_VER >= 20
+    static_assert(test());
+#endif
+
     {
         // test that the implicitly generated copy assignment operator
         // is properly deleted

diff  --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp
index b50cbdef8abf..c04baef71ff4 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_copy.pass.cpp
@@ -21,35 +21,31 @@
 
 #include "test_macros.h"
 
-struct B
-{
+struct B {
     int id_;
 
-    explicit B(int i = 0) : id_(i) {}
+    constexpr explicit B(int i = 0) : id_(i) {}
 };
 
-struct D
-    : B
-{
-    explicit D(int i = 0) : B(i) {}
+struct D : B {
+    constexpr explicit D(int i = 0) : B(i) {}
 };
 
 struct NonAssignable {
-  NonAssignable& operator=(NonAssignable const&) = delete;
-  NonAssignable& operator=(NonAssignable&&) = delete;
+    NonAssignable& operator=(NonAssignable const&) = delete;
+    NonAssignable& operator=(NonAssignable&&) = delete;
 };
 
-struct NothrowCopyAssignable
-{
+struct NothrowCopyAssignable {
     NothrowCopyAssignable& operator=(NothrowCopyAssignable const&) noexcept { return *this; }
 };
 
-struct PotentiallyThrowingCopyAssignable
-{
+struct PotentiallyThrowingCopyAssignable {
     PotentiallyThrowingCopyAssignable& operator=(PotentiallyThrowingCopyAssignable const&) { return *this; }
 };
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
         typedef std::tuple<long> T0;
@@ -102,6 +98,16 @@ int main(int, char**)
         assert(std::get<0>(t) == 43);
         assert(&std::get<0>(t) == &x);
     }
+    return true;
+}
+
+int main(int, char**)
+{
+    test();
+#if TEST_STD_VER >= 20
+    static_assert(test());
+#endif
+
     {
         using T = std::tuple<int, NonAssignable>;
         using U = std::tuple<NonAssignable, int>;
@@ -116,6 +122,7 @@ int main(int, char**)
     {
         typedef std::tuple<PotentiallyThrowingCopyAssignable, long> T0;
         typedef std::tuple<PotentiallyThrowingCopyAssignable, int> T1;
+        static_assert(std::is_assignable<T0&, T1 const&>::value, "");
         static_assert(!std::is_nothrow_assignable<T0&, T1 const&>::value, "");
     }
 

diff  --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp
index 0d09c3be0b60..d1c3cfb0479f 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/convert_move.pass.cpp
@@ -23,24 +23,19 @@
 
 #include "test_macros.h"
 
-struct B
-{
+struct B {
     int id_;
-
-    explicit B(int i= 0) : id_(i) {}
-
+    explicit B(int i = 0) : id_(i) {}
     virtual ~B() {}
 };
 
-struct D
-    : B
-{
+struct D : B {
     explicit D(int i) : B(i) {}
 };
 
 struct E {
-  E() = default;
-  E& operator=(int) {
+  constexpr E() = default;
+  TEST_CONSTEXPR_CXX14 E& operator=(int) {
       return *this;
   }
 };
@@ -92,7 +87,8 @@ struct TrackMove
     bool moved_from;
 };
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
         typedef std::tuple<long> T0;
@@ -111,6 +107,29 @@ int main(int, char**)
         assert(std::get<0>(t1) == 2);
         assert(std::get<1>(t1) == int('a'));
     }
+    {
+        // Test that tuple evaluates correctly applies an lvalue reference
+        // before evaluating is_assignable (i.e. 'is_assignable<int&, int&&>')
+        // instead of evaluating 'is_assignable<int&&, int&&>' which is false.
+        int x = 42;
+        int y = 43;
+        std::tuple<int&&, E> t(std::move(x), E{});
+        std::tuple<int&&, int> t2(std::move(y), 44);
+        t = std::move(t2);
+        assert(std::get<0>(t) == 43);
+        assert(&std::get<0>(t) == &x);
+    }
+
+    return true;
+}
+
+int main(int, char**)
+{
+    test();
+#if TEST_STD_VER >= 20
+    static_assert(test());
+#endif
+
     {
         typedef std::tuple<long, char, D> T0;
         typedef std::tuple<long long, int, B> T1;
@@ -143,18 +162,7 @@ int main(int, char**)
         assert(std::get<1>(t1) == int('a'));
         assert(std::get<2>(t1)->id_ == 3);
     }
-    {
-        // Test that tuple evaluates correctly applies an lvalue reference
-        // before evaluating is_assignable (i.e. 'is_assignable<int&, int&&>')
-        // instead of evaluating 'is_assignable<int&&, int&&>' which is false.
-        int x = 42;
-        int y = 43;
-        std::tuple<int&&, E> t(std::move(x), E{});
-        std::tuple<int&&, int> t2(std::move(y), 44);
-        t = std::move(t2);
-        assert(std::get<0>(t) == 43);
-        assert(&std::get<0>(t) == &x);
-    }
+
     {
         using T = std::tuple<int, NonAssignable>;
         using U = std::tuple<NonAssignable, int>;
@@ -169,6 +177,7 @@ int main(int, char**)
     {
         typedef std::tuple<PotentiallyThrowingMoveAssignable, long> T0;
         typedef std::tuple<PotentiallyThrowingMoveAssignable, int> T1;
+        static_assert(std::is_assignable<T0&, T1&&>::value, "");
         static_assert(!std::is_nothrow_assignable<T0&, T1&&>::value, "");
     }
     {

diff  --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
index a0356464adfc..71a878a7a0d5 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
@@ -45,7 +45,8 @@ struct CopyAssignableInt {
   CopyAssignableInt& operator=(int&) { return *this; }
 };
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
         typedef std::tuple<> T;
@@ -68,15 +69,6 @@ int main(int, char**)
         assert(std::get<0>(t) == 2);
         assert(std::get<1>(t) == 'a');
     }
-    {
-        typedef std::tuple<int, char, std::string> T;
-        const T t0(2, 'a', "some text");
-        T t;
-        t = t0;
-        assert(std::get<0>(t) == 2);
-        assert(std::get<1>(t) == 'a');
-        assert(std::get<2>(t) == "some text");
-    }
     {
         // test reference assignment.
         using T = std::tuple<int&, int&&>;
@@ -92,6 +84,27 @@ int main(int, char**)
         assert(std::get<1>(t) == y2);
         assert(&std::get<1>(t) == &y);
     }
+
+    return true;
+}
+
+int main(int, char**)
+{
+    test();
+#if TEST_STD_VER >= 20
+    static_assert(test());
+#endif
+
+    {
+        // cannot be constexpr because of std::string
+        typedef std::tuple<int, char, std::string> T;
+        const T t0(2, 'a', "some text");
+        T t;
+        t = t0;
+        assert(std::get<0>(t) == 2);
+        assert(std::get<1>(t) == 'a');
+        assert(std::get<2>(t) == "some text");
+    }
     {
         // test that the implicitly generated copy assignment operator
         // is properly deleted
@@ -99,8 +112,8 @@ int main(int, char**)
         static_assert(!std::is_copy_assignable<T>::value, "");
     }
     {
-      using T = std::tuple<int, NonAssignable>;
-      static_assert(!std::is_copy_assignable<T>::value, "");
+        using T = std::tuple<int, NonAssignable>;
+        static_assert(!std::is_copy_assignable<T>::value, "");
     }
     {
         using T = std::tuple<int, CopyAssignable>;
@@ -132,6 +145,7 @@ int main(int, char**)
     }
     {
         using T = std::tuple<PotentiallyThrowingCopyAssignable, int>;
+        static_assert(std::is_copy_assignable<T>::value, "");
         static_assert(!std::is_nothrow_copy_assignable<T>::value, "");
     }
 

diff  --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp
index a89c4eab900e..91e513909c30 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp
@@ -53,7 +53,8 @@ struct CountAssign {
 int CountAssign::copied = 0;
 int CountAssign::moved = 0;
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
         typedef std::tuple<> T;
@@ -100,6 +101,16 @@ int main(int, char**)
         assert(std::get<1>(t) == y2);
         assert(&std::get<1>(t) == &y);
     }
+    return true;
+}
+
+int main(int, char**)
+{
+    test();
+#if TEST_STD_VER >= 20
+    static_assert(test());
+#endif
+
     {
         // test that the implicitly generated move assignment operator
         // is properly deleted
@@ -108,8 +119,8 @@ int main(int, char**)
         static_assert(!std::is_copy_assignable<T>::value, "");
     }
     {
-      using T = std::tuple<int, NonAssignable>;
-      static_assert(!std::is_move_assignable<T>::value, "");
+        using T = std::tuple<int, NonAssignable>;
+        static_assert(!std::is_move_assignable<T>::value, "");
     }
     {
         using T = std::tuple<int, MoveAssignable>;

diff  --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp
index f67d285eab80..9a6526e9af3a 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/make_tuple.pass.cpp
@@ -21,26 +21,36 @@
 
 #include "test_macros.h"
 
+TEST_CONSTEXPR_CXX20
+bool test()
+{
+    int i = 0;
+    float j = 0;
+    std::tuple<int, int&, float&> t =
+        std::make_tuple(1, std::ref(i), std::ref(j));
+    assert(std::get<0>(t) == 1);
+    assert(std::get<1>(t) == 0);
+    assert(std::get<2>(t) == 0);
+    i = 2;
+    j = 3.5;
+    assert(std::get<0>(t) == 1);
+    assert(std::get<1>(t) == 2);
+    assert(std::get<2>(t) == 3.5);
+    std::get<1>(t) = 0;
+    std::get<2>(t) = 0;
+    assert(i == 0);
+    assert(j == 0);
+
+    return true;
+}
+
 int main(int, char**)
 {
-    {
-        int i = 0;
-        float j = 0;
-        std::tuple<int, int&, float&> t = std::make_tuple(1, std::ref(i),
-                                                          std::ref(j));
-        assert(std::get<0>(t) == 1);
-        assert(std::get<1>(t) == 0);
-        assert(std::get<2>(t) == 0);
-        i = 2;
-        j = 3.5;
-        assert(std::get<0>(t) == 1);
-        assert(std::get<1>(t) == 2);
-        assert(std::get<2>(t) == 3.5);
-        std::get<1>(t) = 0;
-        std::get<2>(t) = 0;
-        assert(i == 0);
-        assert(j == 0);
-    }
+    test();
+#if TEST_STD_VER >= 20
+    static_assert(test());
+#endif
+
 #if TEST_STD_VER > 11
     {
         constexpr auto t1 = std::make_tuple(0, 1, 3.14);
@@ -51,5 +61,5 @@ int main(int, char**)
     }
 #endif
 
-  return 0;
+    return 0;
 }

diff  --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp
index 4cd91be2bc16..0c6e6291c8bf 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.creation/tie.pass.cpp
@@ -21,8 +21,9 @@
 
 #include "test_macros.h"
 
-#if TEST_STD_VER > 11
-constexpr bool test_tie_constexpr() {
+TEST_CONSTEXPR_CXX14
+bool test_tie()
+{
     {
         int i = 42;
         double f = 1.1;
@@ -32,15 +33,23 @@ constexpr bool test_tie_constexpr() {
         assert(&std::get<0>(res) == &i);
         assert(&std::get<1>(res) == &std::ignore);
         assert(&std::get<2>(res) == &f);
-        // FIXME: If/when tuple gets constexpr assignment
-        //res = std::make_tuple(101, nullptr, -1.0);
+
+#if TEST_STD_VER >= 20
+        res = std::make_tuple(101, nullptr, -1.0);
+        assert(i == 101);
+        assert(f == -1.0);
+#endif
     }
     return true;
 }
-#endif
 
 int main(int, char**)
 {
+    test_tie();
+#if TEST_STD_VER >= 14
+    static_assert(test_tie(), "");
+#endif
+
     {
         int i = 0;
         std::string s;
@@ -48,18 +57,6 @@ int main(int, char**)
         assert(i == 42);
         assert(s == "C++");
     }
-#if TEST_STD_VER > 11
-    {
-        static constexpr int i = 42;
-        static constexpr double f = 1.1;
-        constexpr std::tuple<const int &, const double &> t = std::tie(i, f);
-        static_assert ( std::get<0>(t) == 42, "" );
-        static_assert ( std::get<1>(t) == 1.1, "" );
-    }
-    {
-        static_assert(test_tie_constexpr(), "");
-    }
-#endif
 
-  return 0;
+    return 0;
 }

diff  --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.swap/member_swap.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.swap/member_swap.pass.cpp
index 767d2dd0abdd..e479a61e49f2 100644
--- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.swap/member_swap.pass.cpp
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.swap/member_swap.pass.cpp
@@ -20,7 +20,8 @@
 #include "test_macros.h"
 #include "MoveOnly.h"
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     {
         typedef std::tuple<> T;
@@ -58,6 +59,15 @@ int main(int, char**)
         assert(std::get<1>(t1) == 1);
         assert(std::get<2>(t1) == 2);
     }
+    return true;
+}
+
+int main(int, char**)
+{
+    test();
+#if TEST_STD_VER >= 20
+    static_assert(test());
+#endif
 
-  return 0;
+    return 0;
 }

diff  --git a/libcxx/test/std/utilities/utility/pairs/pair.piecewise/piecewise_construct.pass.cpp b/libcxx/test/std/utilities/utility/pairs/pair.piecewise/piecewise_construct.pass.cpp
index 0178f5dffd0b..65f6d62ec09a 100644
--- a/libcxx/test/std/utilities/utility/pairs/pair.piecewise/piecewise_construct.pass.cpp
+++ b/libcxx/test/std/utilities/utility/pairs/pair.piecewise/piecewise_construct.pass.cpp
@@ -26,9 +26,9 @@ class A
     int i_;
     char c_;
 public:
-    A(int i, char c) : i_(i), c_(c) {}
-    int get_i() const {return i_;}
-    char get_c() const {return c_;}
+    constexpr A(int i, char c) : i_(i), c_(c) {}
+    constexpr int get_i() const {return i_;}
+    constexpr char get_c() const {return c_;}
 };
 
 class B
@@ -37,13 +37,14 @@ class B
     unsigned u1_;
     unsigned u2_;
 public:
-    B(double d, unsigned u1, unsigned u2) : d_(d), u1_(u1), u2_(u2) {}
-    double get_d() const {return d_;}
-    unsigned get_u1() const {return u1_;}
-    unsigned get_u2() const {return u2_;}
+    constexpr explicit B(double d, unsigned u1, unsigned u2) : d_(d), u1_(u1), u2_(u2) {}
+    constexpr double get_d() const {return d_;}
+    constexpr unsigned get_u1() const {return u1_;}
+    constexpr unsigned get_u2() const {return u2_;}
 };
 
-int main(int, char**)
+TEST_CONSTEXPR_CXX20
+bool test()
 {
     std::pair<A, B> p(std::piecewise_construct,
                       std::make_tuple(4, 'a'),
@@ -54,5 +55,15 @@ int main(int, char**)
     assert(p.second.get_u1() == 6u);
     assert(p.second.get_u2() == 2u);
 
-  return 0;
+    return true;
+}
+
+int main(int, char**)
+{
+    test();
+#if TEST_STD_VER >= 20
+    static_assert(test());
+#endif
+
+    return 0;
 }

diff  --git a/libcxx/test/support/test_constexpr_container.h b/libcxx/test/support/test_constexpr_container.h
new file mode 100644
index 000000000000..3f466d517ccc
--- /dev/null
+++ b/libcxx/test/support/test_constexpr_container.h
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 SUPPORT_TEST_CONSTEXPR_CONTAINER_H
+#define SUPPORT_TEST_CONSTEXPR_CONTAINER_H
+
+// A dummy container with enough constexpr support to test the standard
+// insert iterators, such as `back_insert_iterator`.
+
+#include <algorithm>
+#include <cassert>
+#include <utility>
+
+#include "test_macros.h"
+
+#if TEST_STD_VER >= 14
+
+template<class T, int N>
+class ConstexprFixedCapacityDeque {
+    T data_[N];
+    int size_ = 0;
+public:
+    using value_type = T;
+    using iterator = T *;
+    using const_iterator = T const *;
+
+    constexpr ConstexprFixedCapacityDeque() = default;
+    constexpr iterator begin() { return data_; }
+    constexpr iterator end() { return data_ + size_; }
+    constexpr const_iterator begin() const { return data_; }
+    constexpr const_iterator end() const { return data_ + size_; }
+    constexpr size_t size() const { return size_; }
+    constexpr const T& front() const { assert(size_ >= 1); return data_[0]; }
+    constexpr const T& back() const { assert(size_ >= 1); return data_[size_-1]; }
+
+    constexpr iterator insert(const_iterator pos, T t) {
+        int i = (pos - data_);
+        if (i != size_) {
+            std::move_backward(data_ + i, data_ + size_, data_ + size_ + 1);
+        }
+        data_[i] = std::move(t);
+        size_ += 1;
+        return data_ + i;
+    }
+
+    constexpr void push_back(T t) { insert(end(), std::move(t)); }
+    constexpr void push_front(T t) { insert(begin(), std::move(t)); }
+};
+
+#endif // TEST_STD_VER >= 14
+
+#endif // SUPPORT_TEST_CONSTEXPR_CONTAINER_H

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index e69c7c1f9442..d6fa8361853f 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -198,7 +198,6 @@ def add_version_header(tc):
     "name": "__cpp_lib_constexpr_iterator",
     "values": { "c++20": 201811 },
     "headers": ["iterator"],
-    "unimplemented": True,
   }, {
     "name": "__cpp_lib_constexpr_memory",
     "values": { "c++20": 201811 },
@@ -209,19 +208,16 @@ def add_version_header(tc):
     "headers": ["numeric"],
   }, {
     "name": "__cpp_lib_constexpr_string",
-    "values": { "c++20": 201907 },
+    "values": { "c++20": 201811 },  # because P1032R1 is implemented; but should become 201907 after P0980R1
     "headers": ["string"],
-    "unimplemented": True,
   }, {
     "name": "__cpp_lib_constexpr_string_view",
     "values": { "c++20": 201811 },
     "headers": ["string_view"],
-    "unimplemented": True,
   }, {
     "name": "__cpp_lib_constexpr_tuple",
     "values": { "c++20": 201811 },
     "headers": ["tuple"],
-    "unimplemented": True,
   }, {
     "name": "__cpp_lib_constexpr_utility",
     "values": { "c++20": 201811 },


        


More information about the libcxx-commits mailing list