[libcxx-commits] [libcxx] f02120f - [libc++] Implement P2417R2 (A more constexpr bitset)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Sun Aug 14 01:34:06 PDT 2022


Author: Nikolas Klauser
Date: 2022-08-14T10:34:01+02:00
New Revision: f02120fba28f2352fd9396683892fc6671caa137

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

LOG: [libc++] Implement P2417R2 (A more constexpr bitset)

Reviewed By: ldionne, #libc

Spies: jloser, arichardson, libcxx-commits, arphaman

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

Added: 
    libcxx/test/std/language.support/support.limits/support.limits.general/bitset.version.compile.pass.cpp

Modified: 
    libcxx/docs/FeatureTestMacroTable.rst
    libcxx/docs/ReleaseNotes.rst
    libcxx/docs/Status/Cxx2bPapers.csv
    libcxx/include/__bit_reference
    libcxx/include/__config
    libcxx/include/bitset
    libcxx/include/version
    libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/all.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/any.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/count.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.out_of_range.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/none.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.out_of_range.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/set_one.out_of_range.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/size.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/test.out_of_range.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/to_ullong.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.members/to_ulong.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp
    libcxx/test/std/utilities/template.bitset/bitset_test_cases.h
    libcxx/test/support/test_macros.h
    libcxx/utils/generate_feature_test_macro_components.py

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index e5a06dcced65a..0ffd44dbb33c7 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -308,6 +308,8 @@ Status
     ------------------------------------------------- -----------------
     ``__cpp_lib_byteswap``                            ``202110L``
     ------------------------------------------------- -----------------
+    ``__cpp_lib_constexpr_bitset``                    ``202207L``
+    ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_cmath``                     *unimplemented*
     ------------------------------------------------- -----------------
     ``__cpp_lib_constexpr_typeinfo``                  *unimplemented*

diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 9eed86811406a..f69b4d90d3688 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -38,6 +38,7 @@ What's New in Libc++ 16.0.0?
 Implemented Papers
 ------------------
 - P2499R0 - ``string_view`` range constructor should be ``explicit``
+- P2417R2 - A more constexpr bitset
 
 Improvements and New Features
 -----------------------------

diff  --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv
index e9b10554da4fe..f7839f0d4a58d 100644
--- a/libcxx/docs/Status/Cxx2bPapers.csv
+++ b/libcxx/docs/Status/Cxx2bPapers.csv
@@ -69,7 +69,7 @@
 "`P2374R4 <https://wg21.link/P2374R4>`__","LWG","``views::cartesian_product``","July 2022","",""
 "`P2404R3 <https://wg21.link/P2404R3>`__","LWG","Move-only types for ``equality_comparable_with``, ``totally_ordered_with``, and ``three_way_comparable_with``","July 2022","",""
 "`P2408R5 <https://wg21.link/P2408R5>`__","LWG","Ranges iterators as inputs to non-Ranges algorithms","July 2022","",""
-"`P2417R2 <https://wg21.link/P2417R2>`__","LWG","A more ``constexpr`` ``bitset``","July 2022","",""
+"`P2417R2 <https://wg21.link/P2417R2>`__","LWG","A more ``constexpr`` ``bitset``","July 2022","|Complete|","16.0"
 "`P2419R2 <https://wg21.link/P2419R2>`__","LWG","Clarify handling of encodings in localized formatting of chrono types","July 2022","",""
 "`P2438R2 <https://wg21.link/P2438R2>`__","LWG","``std::string::substr() &&``","July 2022","",""
 "`P2445R1 <https://wg21.link/P2445R1>`__","LWG","``forward_like``","July 2022","",""

diff  --git a/libcxx/include/__bit_reference b/libcxx/include/__bit_reference
index 025b86644b090..17f32afd17533 100644
--- a/libcxx/include/__bit_reference
+++ b/libcxx/include/__bit_reference
@@ -263,7 +263,7 @@ find(__bit_iterator<_Cp, _IsConst> __first, __bit_iterator<_Cp, _IsConst> __last
 // count
 
 template <class _Cp, bool _IsConst>
-_LIBCPP_HIDE_FROM_ABI typename __bit_iterator<_Cp, _IsConst>::
diff erence_type
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 typename __bit_iterator<_Cp, _IsConst>::
diff erence_type
 __count_bool_true(__bit_iterator<_Cp, _IsConst> __first, typename _Cp::size_type __n)
 {
     typedef __bit_iterator<_Cp, _IsConst> _It;
@@ -1344,6 +1344,7 @@ private:
     _LIBCPP_CONSTEXPR_AFTER_CXX17
     friend __bit_iterator<_Dp, _IC> __find_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
     template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::
diff erence_type
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
                    __count_bool_true(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);
     template <class _Dp, bool _IC> friend typename __bit_iterator<_Dp, _IC>::
diff erence_type
                    __count_bool_false(__bit_iterator<_Dp, _IC>, typename _Dp::size_type);

diff  --git a/libcxx/include/__config b/libcxx/include/__config
index e2564c93f4117..11acaa33d722f 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -155,7 +155,7 @@
 #    define _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
 #  endif
 
-#  define _LIBCPP_TOSTRING2(x) #  x
+#  define _LIBCPP_TOSTRING2(x) #x
 #  define _LIBCPP_TOSTRING(x) _LIBCPP_TOSTRING2(x)
 
 #  if __cplusplus < 201103L
@@ -842,6 +842,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
 #    define _LIBCPP_CONSTEXPR_AFTER_CXX17
 #  endif
 
+#  if _LIBCPP_STD_VER > 20
+#    define _LIBCPP_CONSTEXPR_AFTER_CXX20 constexpr
+#  else
+#    define _LIBCPP_CONSTEXPR_AFTER_CXX20
+#  endif
+
 #  if __has_cpp_attribute(nodiscard)
 #    define _LIBCPP_NODISCARD [[nodiscard]]
 #  else

diff  --git a/libcxx/include/bitset b/libcxx/include/bitset
index 67760a75662dd..ea6ced6cc6ac6 100644
--- a/libcxx/include/bitset
+++ b/libcxx/include/bitset
@@ -42,61 +42,61 @@ public:
     template <class charT>
         explicit bitset(const charT* str,
                         typename basic_string<charT>::size_type n = basic_string<charT>::npos,
-                        charT zero = charT('0'), charT one = charT('1'));
+                        charT zero = charT('0'), charT one = charT('1')); // constexpr since C++23
     template<class charT, class traits, class Allocator>
         explicit bitset(const basic_string<charT,traits,Allocator>& str,
                         typename basic_string<charT,traits,Allocator>::size_type pos = 0,
                         typename basic_string<charT,traits,Allocator>::size_type n =
                                  basic_string<charT,traits,Allocator>::npos,
-                        charT zero = charT('0'), charT one = charT('1'));
+                        charT zero = charT('0'), charT one = charT('1')); // constexpr since C++23
 
     // 23.3.5.2 bitset operations:
-    bitset& operator&=(const bitset& rhs) noexcept;
-    bitset& operator|=(const bitset& rhs) noexcept;
-    bitset& operator^=(const bitset& rhs) noexcept;
-    bitset& operator<<=(size_t pos) noexcept;
-    bitset& operator>>=(size_t pos) noexcept;
-    bitset& set() noexcept;
-    bitset& set(size_t pos, bool val = true);
-    bitset& reset() noexcept;
-    bitset& reset(size_t pos);
-    bitset operator~() const noexcept;
-    bitset& flip() noexcept;
-    bitset& flip(size_t pos);
+    bitset& operator&=(const bitset& rhs) noexcept; // constexpr since C++23
+    bitset& operator|=(const bitset& rhs) noexcept; // constexpr since C++23
+    bitset& operator^=(const bitset& rhs) noexcept; // constexpr since C++23
+    bitset& operator<<=(size_t pos) noexcept;       // constexpr since C++23
+    bitset& operator>>=(size_t pos) noexcept;       // constexpr since C++23
+    bitset& set() noexcept;                         // constexpr since C++23
+    bitset& set(size_t pos, bool val = true);       // constexpr since C++23
+    bitset& reset() noexcept;                       // constexpr since C++23
+    bitset& reset(size_t pos);                      // constexpr since C++23
+    bitset operator~() const noexcept;              // constexpr since C++23
+    bitset& flip() noexcept;                        // constexpr since C++23
+    bitset& flip(size_t pos);                       // constexpr since C++23
 
     // element access:
-    constexpr bool operator[](size_t pos) const; // for b[i];
-    reference operator[](size_t pos);            // for b[i];
-    unsigned long to_ulong() const;
-    unsigned long long to_ullong() const;
-    template <class charT, class traits, class Allocator>
+    constexpr bool operator[](size_t pos) const;
+    reference operator[](size_t pos);            // constexpr since C++23
+    unsigned long to_ulong() const;              // constexpr since C++23
+    unsigned long long to_ullong() const;        // constexpr since C++23
+    template <class charT, class traits, class Allocator> // constexpr since C++23
         basic_string<charT, traits, Allocator> to_string(charT zero = charT('0'), charT one = charT('1')) const;
-    template <class charT, class traits>
+    template <class charT, class traits> // constexpr since C++23
         basic_string<charT, traits, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;
-    template <class charT>
+    template <class charT> // constexpr since C++23
         basic_string<charT, char_traits<charT>, allocator<charT> > to_string(charT zero = charT('0'), charT one = charT('1')) const;
-    basic_string<char, char_traits<char>, allocator<char> > to_string(char zero = '0', char one = '1') const;
-    size_t count() const noexcept;
-    constexpr size_t size() const noexcept;
-    bool operator==(const bitset& rhs) const noexcept;
-    bool operator!=(const bitset& rhs) const noexcept;
-    bool test(size_t pos) const;
-    bool all() const noexcept;
-    bool any() const noexcept;
-    bool none() const noexcept;
-    bitset operator<<(size_t pos) const noexcept;
-    bitset operator>>(size_t pos) const noexcept;
+    basic_string<char, char_traits<char>, allocator<char> > to_string(char zero = '0', char one = '1') const; // constexpr since C++23
+    size_t count() const noexcept;                     // constexpr since C++23
+    constexpr size_t size() const noexcept;            // constexpr since C++23
+    bool operator==(const bitset& rhs) const noexcept; // constexpr since C++23
+    bool operator!=(const bitset& rhs) const noexcept; // constexpr since C++23
+    bool test(size_t pos) const;                       // constexpr since C++23
+    bool all() const noexcept;                         // constexpr since C++23
+    bool any() const noexcept;                         // constexpr since C++23
+    bool none() const noexcept;                        // constexpr since C++23
+    bitset<N> operator<<(size_t pos) const noexcept;   // constexpr since C++23
+    bitset<N> operator>>(size_t pos) const noexcept;   // constexpr since C++23
 };
 
 // 23.3.5.3 bitset operators:
 template <size_t N>
-bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept;
+bitset<N> operator&(const bitset<N>&, const bitset<N>&) noexcept; // constexpr since C++23
 
 template <size_t N>
-bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept;
+bitset<N> operator|(const bitset<N>&, const bitset<N>&) noexcept; // constexpr since C++23
 
 template <size_t N>
-bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept;
+bitset<N> operator^(const bitset<N>&, const bitset<N>&) noexcept; // constexpr since C++23
 
 template <class charT, class traits, size_t N>
 basic_istream<charT, traits>&
@@ -178,30 +178,30 @@ protected:
     _LIBCPP_INLINE_VISIBILITY
     explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 reference __make_ref(size_t __pos) _NOEXCEPT
         {return reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT
         {return const_reference(__first_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
-    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 iterator __make_iter(size_t __pos) _NOEXCEPT
         {return iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
-    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 const_iterator __make_iter(size_t __pos) const _NOEXCEPT
         {return const_iterator(__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     void operator&=(const __bitset& __v) _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     void operator|=(const __bitset& __v) _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     void operator^=(const __bitset& __v) _NOEXCEPT;
 
-    void flip() _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 void flip() _NOEXCEPT;
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long to_ulong() const
         {return to_ulong(integral_constant<bool, _Size < sizeof(unsigned long) * CHAR_BIT>());}
-    _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long long to_ullong() const
         {return to_ullong(integral_constant<bool, _Size < sizeof(unsigned long long) * CHAR_BIT>());}
 
-    bool all() const _NOEXCEPT;
-    bool any() const _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 bool all() const _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 bool any() const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY
     size_t __hash_code() const _NOEXCEPT;
 private:
@@ -210,14 +210,17 @@ private:
     _LIBCPP_INLINE_VISIBILITY
     void __init(unsigned long long __v, true_type) _NOEXCEPT;
 #endif // _LIBCPP_CXX03_LANG
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long to_ulong(false_type) const;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long to_ulong(true_type) const;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long long to_ullong(false_type) const;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long long to_ullong(true_type) const;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long long to_ullong(true_type, false_type) const;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long long to_ullong(true_type, true_type) const;
 };
 
@@ -290,7 +293,7 @@ __bitset<_N_words, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
 
 template <size_t _N_words, size_t _Size>
 inline
-void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 void
 __bitset<_N_words, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
 {
     for (size_type __i = 0; __i < _N_words; ++__i)
@@ -299,7 +302,7 @@ __bitset<_N_words, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
 
 template <size_t _N_words, size_t _Size>
 inline
-void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 void
 __bitset<_N_words, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
 {
     for (size_type __i = 0; __i < _N_words; ++__i)
@@ -308,7 +311,7 @@ __bitset<_N_words, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
 
 template <size_t _N_words, size_t _Size>
 inline
-void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 void
 __bitset<_N_words, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
 {
     for (size_type __i = 0; __i < _N_words; ++__i)
@@ -316,7 +319,7 @@ __bitset<_N_words, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
 }
 
 template <size_t _N_words, size_t _Size>
-void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 void
 __bitset<_N_words, _Size>::flip() _NOEXCEPT
 {
     // do middle whole words
@@ -335,7 +338,7 @@ __bitset<_N_words, _Size>::flip() _NOEXCEPT
 }
 
 template <size_t _N_words, size_t _Size>
-unsigned long
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long
 __bitset<_N_words, _Size>::to_ulong(false_type) const
 {
     const_iterator __e = __make_iter(_Size);
@@ -348,14 +351,14 @@ __bitset<_N_words, _Size>::to_ulong(false_type) const
 
 template <size_t _N_words, size_t _Size>
 inline
-unsigned long
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long
 __bitset<_N_words, _Size>::to_ulong(true_type) const
 {
     return __first_[0];
 }
 
 template <size_t _N_words, size_t _Size>
-unsigned long long
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long long
 __bitset<_N_words, _Size>::to_ullong(false_type) const
 {
     const_iterator __e = __make_iter(_Size);
@@ -368,7 +371,7 @@ __bitset<_N_words, _Size>::to_ullong(false_type) const
 
 template <size_t _N_words, size_t _Size>
 inline
-unsigned long long
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long long
 __bitset<_N_words, _Size>::to_ullong(true_type) const
 {
     return to_ullong(true_type(), integral_constant<bool, sizeof(__storage_type) < sizeof(unsigned long long)>());
@@ -376,14 +379,14 @@ __bitset<_N_words, _Size>::to_ullong(true_type) const
 
 template <size_t _N_words, size_t _Size>
 inline
-unsigned long long
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long long
 __bitset<_N_words, _Size>::to_ullong(true_type, false_type) const
 {
     return __first_[0];
 }
 
 template <size_t _N_words, size_t _Size>
-unsigned long long
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long long
 __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const
 {
     unsigned long long __r = __first_[0];
@@ -393,7 +396,7 @@ __bitset<_N_words, _Size>::to_ullong(true_type, true_type) const
 }
 
 template <size_t _N_words, size_t _Size>
-bool
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 bool
 __bitset<_N_words, _Size>::all() const _NOEXCEPT
 {
     // do middle whole words
@@ -413,7 +416,7 @@ __bitset<_N_words, _Size>::all() const _NOEXCEPT
 }
 
 template <size_t _N_words, size_t _Size>
-bool
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 bool
 __bitset<_N_words, _Size>::any() const _NOEXCEPT
 {
     // do middle whole words
@@ -474,33 +477,33 @@ protected:
     _LIBCPP_INLINE_VISIBILITY
     explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long __v) _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t __pos) _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 reference __make_ref(size_t __pos) _NOEXCEPT
         {return reference(&__first_, __storage_type(1) << __pos);}
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t __pos) const _NOEXCEPT
         {return const_reference(&__first_, __storage_type(1) << __pos);}
-    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t __pos) _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 iterator __make_iter(size_t __pos) _NOEXCEPT
         {return iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
-    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t __pos) const _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 const_iterator __make_iter(size_t __pos) const _NOEXCEPT
         {return const_iterator(&__first_ + __pos / __bits_per_word, __pos % __bits_per_word);}
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     void operator&=(const __bitset& __v) _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     void operator|=(const __bitset& __v) _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     void operator^=(const __bitset& __v) _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     void flip() _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long to_ulong() const;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long long to_ullong() const;
 
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bool all() const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bool any() const _NOEXCEPT;
 
     _LIBCPP_INLINE_VISIBILITY
@@ -528,7 +531,7 @@ __bitset<1, _Size>::__bitset(unsigned long long __v) _NOEXCEPT
 
 template <size_t _Size>
 inline
-void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 void
 __bitset<1, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
 {
     __first_ &= __v.__first_;
@@ -536,7 +539,7 @@ __bitset<1, _Size>::operator&=(const __bitset& __v) _NOEXCEPT
 
 template <size_t _Size>
 inline
-void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 void
 __bitset<1, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
 {
     __first_ |= __v.__first_;
@@ -544,7 +547,7 @@ __bitset<1, _Size>::operator|=(const __bitset& __v) _NOEXCEPT
 
 template <size_t _Size>
 inline
-void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 void
 __bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
 {
     __first_ ^= __v.__first_;
@@ -552,7 +555,7 @@ __bitset<1, _Size>::operator^=(const __bitset& __v) _NOEXCEPT
 
 template <size_t _Size>
 inline
-void
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 void
 __bitset<1, _Size>::flip() _NOEXCEPT
 {
     __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
@@ -562,7 +565,7 @@ __bitset<1, _Size>::flip() _NOEXCEPT
 
 template <size_t _Size>
 inline
-unsigned long
+_LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long
 __bitset<1, _Size>::to_ulong() const
 {
     return __first_;
@@ -570,7 +573,7 @@ __bitset<1, _Size>::to_ulong() const
 
 template <size_t _Size>
 inline
-unsigned long long
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long long
 __bitset<1, _Size>::to_ullong() const
 {
     return __first_;
@@ -578,7 +581,7 @@ __bitset<1, _Size>::to_ullong() const
 
 template <size_t _Size>
 inline
-bool
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 bool
 __bitset<1, _Size>::all() const _NOEXCEPT
 {
     __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
@@ -587,7 +590,7 @@ __bitset<1, _Size>::all() const _NOEXCEPT
 
 template <size_t _Size>
 inline
-bool
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 bool
 __bitset<1, _Size>::any() const _NOEXCEPT
 {
     __storage_type __m = ~__storage_type(0) >> (__bits_per_word - _Size);
@@ -631,26 +634,26 @@ protected:
     _LIBCPP_INLINE_VISIBILITY
     explicit _LIBCPP_CONSTEXPR __bitset(unsigned long long) _NOEXCEPT;
 
-    _LIBCPP_INLINE_VISIBILITY reference __make_ref(size_t) _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 reference __make_ref(size_t) _NOEXCEPT
         {return reference(nullptr, 1);}
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR const_reference __make_ref(size_t) const _NOEXCEPT
         {return const_reference(nullptr, 1);}
-    _LIBCPP_INLINE_VISIBILITY iterator __make_iter(size_t) _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 iterator __make_iter(size_t) _NOEXCEPT
         {return iterator(nullptr, 0);}
-    _LIBCPP_INLINE_VISIBILITY const_iterator __make_iter(size_t) const _NOEXCEPT
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 const_iterator __make_iter(size_t) const _NOEXCEPT
         {return const_iterator(nullptr, 0);}
 
-    _LIBCPP_INLINE_VISIBILITY void operator&=(const __bitset&) _NOEXCEPT {}
-    _LIBCPP_INLINE_VISIBILITY void operator|=(const __bitset&) _NOEXCEPT {}
-    _LIBCPP_INLINE_VISIBILITY void operator^=(const __bitset&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 void operator&=(const __bitset&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 void operator|=(const __bitset&) _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 void operator^=(const __bitset&) _NOEXCEPT {}
 
-    _LIBCPP_INLINE_VISIBILITY void flip() _NOEXCEPT {}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 void flip() _NOEXCEPT {}
 
-    _LIBCPP_INLINE_VISIBILITY unsigned long to_ulong() const {return 0;}
-    _LIBCPP_INLINE_VISIBILITY unsigned long long to_ullong() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long to_ulong() const {return 0;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 unsigned long long to_ullong() const {return 0;}
 
-    _LIBCPP_INLINE_VISIBILITY bool all() const _NOEXCEPT {return true;}
-    _LIBCPP_INLINE_VISIBILITY bool any() const _NOEXCEPT {return false;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 bool all() const _NOEXCEPT {return true;}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 bool any() const _NOEXCEPT {return false;}
 
     _LIBCPP_INLINE_VISIBILITY size_t __hash_code() const _NOEXCEPT {return 0;}
 };
@@ -687,10 +690,12 @@ public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
         bitset(unsigned long long __v) _NOEXCEPT : base(__v) {}
     template<class _CharT, class = __enable_if_t<_IsCharLikeType<_CharT>::value> >
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
         explicit bitset(const _CharT* __str,
                         typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,
                         _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
     template<class _CharT, class _Traits, class _Allocator>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
         explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
                         typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos = 0,
                         typename basic_string<_CharT,_Traits,_Allocator>::size_type __n =
@@ -698,24 +703,29 @@ public:
                         _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
 
     // 23.3.5.2 bitset operations:
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& operator&=(const bitset& __rhs) _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& operator|=(const bitset& __rhs) _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& operator^=(const bitset& __rhs) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& operator<<=(size_t __pos) _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& operator>>=(size_t __pos) _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& set() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& set(size_t __pos, bool __val = true);
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& reset() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& reset(size_t __pos);
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset  operator~() const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& flip() _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset& flip(size_t __pos);
 
     // element access:
@@ -724,41 +734,43 @@ public:
 #else
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference operator[](size_t __p) const {return base::__make_ref(__p);}
 #endif
-    _LIBCPP_HIDE_FROM_ABI                         reference operator[](size_t __p)       {return base::__make_ref(__p);}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20 reference operator[](size_t __p)       {return base::__make_ref(__p);}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long to_ulong() const;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     unsigned long long to_ullong() const;
     template <class _CharT, class _Traits, class _Allocator>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
         basic_string<_CharT, _Traits, _Allocator> to_string(_CharT __zero = _CharT('0'),
                                                             _CharT __one = _CharT('1')) const;
     template <class _CharT, class _Traits>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
         basic_string<_CharT, _Traits, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),
                                                                     _CharT __one = _CharT('1')) const;
     template <class _CharT>
-        _LIBCPP_INLINE_VISIBILITY
+        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
         basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> > to_string(_CharT __zero = _CharT('0'),
                                                                                 _CharT __one = _CharT('1')) const;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     basic_string<char, char_traits<char>, allocator<char> > to_string(char __zero = '0',
                                                                       char __one = '1') const;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     size_t count() const _NOEXCEPT;
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR size_t size() const _NOEXCEPT {return _Size;}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bool operator==(const bitset& __rhs) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bool operator!=(const bitset& __rhs) const _NOEXCEPT;
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
     bool test(size_t __pos) const;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bool all() const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bool any() const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY bool none() const _NOEXCEPT {return !any();}
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20 bool none() const _NOEXCEPT {return !any();}
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset operator<<(size_t __pos) const _NOEXCEPT;
-    _LIBCPP_INLINE_VISIBILITY
+    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
     bitset operator>>(size_t __pos) const _NOEXCEPT;
 
 private:
@@ -771,6 +783,7 @@ private:
 
 template <size_t _Size>
 template<class _CharT, class>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>::bitset(const _CharT* __str,
                       typename basic_string<_CharT>::size_type __n,
                       _CharT __zero, _CharT __one)
@@ -792,6 +805,7 @@ bitset<_Size>::bitset(const _CharT* __str,
 
 template <size_t _Size>
 template<class _CharT, class _Traits, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
        typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos,
        typename basic_string<_CharT,_Traits,_Allocator>::size_type __n,
@@ -817,6 +831,7 @@ bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::operator&=(const bitset& __rhs) _NOEXCEPT
 {
@@ -826,6 +841,7 @@ bitset<_Size>::operator&=(const bitset& __rhs) _NOEXCEPT
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::operator|=(const bitset& __rhs) _NOEXCEPT
 {
@@ -835,6 +851,7 @@ bitset<_Size>::operator|=(const bitset& __rhs) _NOEXCEPT
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::operator^=(const bitset& __rhs) _NOEXCEPT
 {
@@ -843,6 +860,7 @@ bitset<_Size>::operator^=(const bitset& __rhs) _NOEXCEPT
 }
 
 template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::operator<<=(size_t __pos) _NOEXCEPT
 {
@@ -853,6 +871,7 @@ bitset<_Size>::operator<<=(size_t __pos) _NOEXCEPT
 }
 
 template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::operator>>=(size_t __pos) _NOEXCEPT
 {
@@ -864,6 +883,7 @@ bitset<_Size>::operator>>=(size_t __pos) _NOEXCEPT
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::set() _NOEXCEPT
 {
@@ -872,6 +892,7 @@ bitset<_Size>::set() _NOEXCEPT
 }
 
 template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::set(size_t __pos, bool __val)
 {
@@ -884,6 +905,7 @@ bitset<_Size>::set(size_t __pos, bool __val)
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::reset() _NOEXCEPT
 {
@@ -892,6 +914,7 @@ bitset<_Size>::reset() _NOEXCEPT
 }
 
 template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::reset(size_t __pos)
 {
@@ -904,6 +927,7 @@ bitset<_Size>::reset(size_t __pos)
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>
 bitset<_Size>::operator~() const _NOEXCEPT
 {
@@ -914,6 +938,7 @@ bitset<_Size>::operator~() const _NOEXCEPT
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::flip() _NOEXCEPT
 {
@@ -922,6 +947,7 @@ bitset<_Size>::flip() _NOEXCEPT
 }
 
 template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>&
 bitset<_Size>::flip(size_t __pos)
 {
@@ -935,6 +961,7 @@ bitset<_Size>::flip(size_t __pos)
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 unsigned long
 bitset<_Size>::to_ulong() const
 {
@@ -943,6 +970,7 @@ bitset<_Size>::to_ulong() const
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 unsigned long long
 bitset<_Size>::to_ullong() const
 {
@@ -951,6 +979,7 @@ bitset<_Size>::to_ullong() const
 
 template <size_t _Size>
 template <class _CharT, class _Traits, class _Allocator>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 basic_string<_CharT, _Traits, _Allocator>
 bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
 {
@@ -966,6 +995,7 @@ bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
 template <size_t _Size>
 template <class _CharT, class _Traits>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 basic_string<_CharT, _Traits, allocator<_CharT> >
 bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
 {
@@ -975,6 +1005,7 @@ bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
 template <size_t _Size>
 template <class _CharT>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 basic_string<_CharT, char_traits<_CharT>, allocator<_CharT> >
 bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
 {
@@ -983,6 +1014,7 @@ bitset<_Size>::to_string(_CharT __zero, _CharT __one) const
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 basic_string<char, char_traits<char>, allocator<char> >
 bitset<_Size>::to_string(char __zero, char __one) const
 {
@@ -991,6 +1023,7 @@ bitset<_Size>::to_string(char __zero, char __one) const
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 size_t
 bitset<_Size>::count() const _NOEXCEPT
 {
@@ -999,6 +1032,7 @@ bitset<_Size>::count() const _NOEXCEPT
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bool
 bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT
 {
@@ -1007,6 +1041,7 @@ bitset<_Size>::operator==(const bitset& __rhs) const _NOEXCEPT
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bool
 bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT
 {
@@ -1014,6 +1049,7 @@ bitset<_Size>::operator!=(const bitset& __rhs) const _NOEXCEPT
 }
 
 template <size_t _Size>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bool
 bitset<_Size>::test(size_t __pos) const
 {
@@ -1025,6 +1061,7 @@ bitset<_Size>::test(size_t __pos) const
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bool
 bitset<_Size>::all() const _NOEXCEPT
 {
@@ -1033,6 +1070,7 @@ bitset<_Size>::all() const _NOEXCEPT
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bool
 bitset<_Size>::any() const _NOEXCEPT
 {
@@ -1041,6 +1079,7 @@ bitset<_Size>::any() const _NOEXCEPT
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>
 bitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT
 {
@@ -1051,6 +1090,7 @@ bitset<_Size>::operator<<(size_t __pos) const _NOEXCEPT
 
 template <size_t _Size>
 inline
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>
 bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT
 {
@@ -1060,7 +1100,7 @@ bitset<_Size>::operator>>(size_t __pos) const _NOEXCEPT
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>
 operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
 {
@@ -1070,7 +1110,7 @@ operator&(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>
 operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
 {
@@ -1080,7 +1120,7 @@ operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
 }
 
 template <size_t _Size>
-inline _LIBCPP_INLINE_VISIBILITY
+inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX20
 bitset<_Size>
 operator^(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
 {

diff  --git a/libcxx/include/version b/libcxx/include/version
index 8ffb1747eb276..60eac7b0600ba 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -56,6 +56,7 @@ __cpp_lib_clamp                                         201603L <algorithm>
 __cpp_lib_complex_udls                                  201309L <complex>
 __cpp_lib_concepts                                      202002L <concepts>
 __cpp_lib_constexpr_algorithms                          201806L <algorithm>
+__cpp_lib_constexpr_bitset                              202207L <bitset>
 __cpp_lib_constexpr_cmath                               202202L <cmath> <cstdlib>
 __cpp_lib_constexpr_complex                             201711L <complex>
 __cpp_lib_constexpr_dynamic_alloc                       201907L <memory>
@@ -382,6 +383,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_associative_heterogeneous_erasure    202110L
 // # define __cpp_lib_bind_back                            202202L
 # define __cpp_lib_byteswap                             202110L
+# define __cpp_lib_constexpr_bitset                     202207L
 // # define __cpp_lib_constexpr_cmath                      202202L
 // # define __cpp_lib_constexpr_typeinfo                   202106L
 // # define __cpp_lib_invoke_r                             202106L

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/bitset.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/bitset.version.compile.pass.cpp
new file mode 100644
index 0000000000000..8179d3b7028f6
--- /dev/null
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/bitset.version.compile.pass.cpp
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+//
+// clang-format off
+
+// <bitset>
+
+// Test the feature test macros defined by <bitset>
+
+/*  Constant                      Value
+    __cpp_lib_constexpr_bitset    202207L [C++2b]
+*/
+
+#include <bitset>
+#include "test_macros.h"
+
+#if TEST_STD_VER < 14
+
+# ifdef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 14
+
+# ifdef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 17
+
+# ifdef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER == 20
+
+# ifdef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should not be defined before c++2b"
+# endif
+
+#elif TEST_STD_VER > 20
+
+# ifndef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_bitset != 202207L
+#   error "__cpp_lib_constexpr_bitset should have the value 202207L in c++2b"
+# endif
+
+#endif // TEST_STD_VER > 20
+

diff  --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index d9a340e52ef9a..edade7874eca1 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -52,6 +52,7 @@
     __cpp_lib_complex_udls                         201309L [C++14]
     __cpp_lib_concepts                             202002L [C++20]
     __cpp_lib_constexpr_algorithms                 201806L [C++20]
+    __cpp_lib_constexpr_bitset                     202207L [C++2b]
     __cpp_lib_constexpr_cmath                      202202L [C++2b]
     __cpp_lib_constexpr_complex                    201711L [C++20]
     __cpp_lib_constexpr_dynamic_alloc              201907L [C++20]
@@ -324,6 +325,10 @@
 #   error "__cpp_lib_constexpr_algorithms should not be defined before c++20"
 # endif
 
+# ifdef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_constexpr_cmath
 #   error "__cpp_lib_constexpr_cmath should not be defined before c++2b"
 # endif
@@ -952,6 +957,10 @@
 #   error "__cpp_lib_constexpr_algorithms should not be defined before c++20"
 # endif
 
+# ifdef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_constexpr_cmath
 #   error "__cpp_lib_constexpr_cmath should not be defined before c++2b"
 # endif
@@ -1676,6 +1685,10 @@
 #   error "__cpp_lib_constexpr_algorithms should not be defined before c++20"
 # endif
 
+# ifdef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_constexpr_cmath
 #   error "__cpp_lib_constexpr_cmath should not be defined before c++2b"
 # endif
@@ -2646,6 +2659,10 @@
 #   error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++20"
 # endif
 
+# ifdef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should not be defined before c++2b"
+# endif
+
 # ifdef __cpp_lib_constexpr_cmath
 #   error "__cpp_lib_constexpr_cmath should not be defined before c++2b"
 # endif
@@ -3865,6 +3882,13 @@
 #   error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++2b"
 # endif
 
+# ifndef __cpp_lib_constexpr_bitset
+#   error "__cpp_lib_constexpr_bitset should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_bitset != 202207L
+#   error "__cpp_lib_constexpr_bitset should have the value 202207L in c++2b"
+# endif
+
 # if !defined(_LIBCPP_VERSION)
 #   ifndef __cpp_lib_constexpr_cmath
 #     error "__cpp_lib_constexpr_cmath should be defined in c++2b"

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp
index 4d0c962019895..3ccc5a2a3a484 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.cons/char_ptr_ctor.pass.cpp
@@ -9,7 +9,7 @@
 // template <class charT>
 //     explicit bitset(const charT* str,
 //                     typename basic_string<charT>::size_type n = basic_string<charT>::npos,
-//                     charT zero = charT('0'), charT one = charT('1'));
+//                     charT zero = charT('0'), charT one = charT('1')); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -21,19 +21,19 @@
 TEST_MSVC_DIAGNOSTIC_IGNORED(6294) // Ill-defined for-loop:  initial condition does not satisfy test.  Loop body not executed.
 
 template <std::size_t N>
-void test_char_pointer_ctor()
+TEST_CONSTEXPR_CXX23 void test_char_pointer_ctor()
 {
-    {
 #ifndef TEST_HAS_NO_EXCEPTIONS
-        try {
-            std::bitset<N> v("xxx1010101010xxxx");
-            assert(false);
-        }
-        catch (std::invalid_argument&) {}
-#endif
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    try {
+      std::bitset<N> v("xxx1010101010xxxx");
+      assert(false);
     }
+    catch (std::invalid_argument&) {}
+  }
+#endif
 
-    {
+  {
     const char str[] = "1010101010";
     std::bitset<N> v(str);
     std::size_t M = std::min<std::size_t>(v.size(), 10);
@@ -41,20 +41,29 @@ void test_char_pointer_ctor()
         assert(v[i] == (str[M - 1 - i] == '1'));
     for (std::size_t i = 10; i < v.size(); ++i)
         assert(v[i] == false);
-    }
+  }
+}
+
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_char_pointer_ctor<0>();
+  test_char_pointer_ctor<1>();
+  test_char_pointer_ctor<31>();
+  test_char_pointer_ctor<32>();
+  test_char_pointer_ctor<33>();
+  test_char_pointer_ctor<63>();
+  test_char_pointer_ctor<64>();
+  test_char_pointer_ctor<65>();
+  test_char_pointer_ctor<1000>();
+
+  return true;
 }
 
 int main(int, char**)
 {
-    test_char_pointer_ctor<0>();
-    test_char_pointer_ctor<1>();
-    test_char_pointer_ctor<31>();
-    test_char_pointer_ctor<32>();
-    test_char_pointer_ctor<33>();
-    test_char_pointer_ctor<63>();
-    test_char_pointer_ctor<64>();
-    test_char_pointer_ctor<65>();
-    test_char_pointer_ctor<1000>();
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp
index a59427bdd061e..490fc7555bb19 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.cons/default.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test default ctor
+// default ctor
 
 #include <bitset>
 #include <cassert>
@@ -14,7 +14,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_default_ctor()
+TEST_CONSTEXPR_CXX23 void test_default_ctor()
 {
     {
         TEST_CONSTEXPR std::bitset<N> v1;
@@ -30,18 +30,26 @@ void test_default_ctor()
 #endif
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_default_ctor<0>();
+  test_default_ctor<1>();
+  test_default_ctor<31>();
+  test_default_ctor<32>();
+  test_default_ctor<33>();
+  test_default_ctor<63>();
+  test_default_ctor<64>();
+  test_default_ctor<65>();
+  test_default_ctor<1000>();
+
+  return true;
+}
 
 int main(int, char**)
 {
-    test_default_ctor<0>();
-    test_default_ctor<1>();
-    test_default_ctor<31>();
-    test_default_ctor<32>();
-    test_default_ctor<33>();
-    test_default_ctor<63>();
-    test_default_ctor<64>();
-    test_default_ctor<65>();
-    test_default_ctor<1000>();
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp
index 2c657b561c8fc..327765b71a06c 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset(string, pos, n, zero, one);
+// bitset(string, pos, n, zero, one); // constexpr since C++23
 
 #include <bitset>
 #include <algorithm> // for 'min' and 'max'
@@ -17,64 +17,60 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_string_ctor() {
+TEST_CONSTEXPR_CXX23 void test_string_ctor() {
 #ifndef TEST_HAS_NO_EXCEPTIONS
-    {
-        try {
-            std::string s("xxx1010101010xxxx");
-            std::bitset<N> v(s, s.size()+1, 10);
-            assert(false);
-        }
-        catch (std::out_of_range&)
-        {
-        }
-    }
-    {
-        try {
-            std::string s("xxx1010101010xxxx");
-            std::bitset<N> v(s, 2, 10);
-            assert(false);
-        }
-        catch (std::invalid_argument&)
-        {
-        }
+  if (!TEST_IS_CONSTANT_EVALUATED) {
+    try {
+        std::string s("xxx1010101010xxxx");
+        std::bitset<N> v(s, s.size()+1, 10);
+        assert(false);
     }
+    catch (std::out_of_range&)
     {
-        try {
-            std::string s("xxxbababababaxxxx");
-            std::bitset<N> v(s, 2, 10, 'a', 'b');
-            assert(false);
-        }
-        catch (std::invalid_argument&)
-        {
-        }
     }
-#endif // TEST_HAS_NO_EXCEPTIONS
-    {
+    try {
         std::string s("xxx1010101010xxxx");
-        std::bitset<N> v(s, 3, 10);
-        std::size_t M = std::min<std::size_t>(v.size(), 10);
-        for (std::size_t i = 0; i < M; ++i)
-            assert(v[i] == (s[3 + M - 1 - i] == '1'));
-        for (std::size_t i = 10; i < v.size(); ++i)
-            assert(v[i] == false);
+        std::bitset<N> v(s, 2, 10);
+        assert(false);
     }
+    catch (std::invalid_argument&)
     {
+    }
+    try {
         std::string s("xxxbababababaxxxx");
-        std::bitset<N> v(s, 3, 10, 'a', 'b');
-        std::size_t M = std::min<std::size_t>(v.size(), 10);
-        for (std::size_t i = 0; i < M; ++i)
-            assert(v[i] == (s[3 + M - 1 - i] == 'b'));
-        for (std::size_t i = 10; i < v.size(); ++i)
-            assert(v[i] == false);
+        std::bitset<N> v(s, 2, 10, 'a', 'b');
+        assert(false);
     }
+    catch (std::invalid_argument&)
+    {
+    }
+  }
+#endif // TEST_HAS_NO_EXCEPTIONS
+  {
+    std::string s("xxx1010101010xxxx");
+    std::bitset<N> v(s, 3, 10);
+    std::size_t M = std::min<std::size_t>(v.size(), 10);
+    for (std::size_t i = 0; i < M; ++i)
+        assert(v[i] == (s[3 + M - 1 - i] == '1'));
+    for (std::size_t i = 10; i < v.size(); ++i)
+        assert(v[i] == false);
+  }
+  {
+    std::string s("xxxbababababaxxxx");
+    std::bitset<N> v(s, 3, 10, 'a', 'b');
+    std::size_t M = std::min<std::size_t>(v.size(), 10);
+    for (std::size_t i = 0; i < M; ++i)
+        assert(v[i] == (s[3 + M - 1 - i] == 'b'));
+    for (std::size_t i = 10; i < v.size(); ++i)
+        assert(v[i] == false);
+  }
 }
 
 struct Nonsense {
     virtual ~Nonsense() {}
 };
 
-void test_for_non_eager_instantiation() {
+TEST_CONSTEXPR_CXX23 void test_for_non_eager_instantiation() {
     // Ensure we don't accidentally instantiate `std::basic_string<Nonsense>`
     // since it may not be well formed and can cause an error in the
     // non-immediate context.
@@ -82,17 +78,26 @@ void test_for_non_eager_instantiation() {
     static_assert(!std::is_constructible<std::bitset<3>, Nonsense*, size_t, Nonsense&, Nonsense&>::value, "");
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_string_ctor<0>();
+  test_string_ctor<1>();
+  test_string_ctor<31>();
+  test_string_ctor<32>();
+  test_string_ctor<33>();
+  test_string_ctor<63>();
+  test_string_ctor<64>();
+  test_string_ctor<65>();
+  test_string_ctor<1000>();
+  test_for_non_eager_instantiation();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_string_ctor<0>();
-    test_string_ctor<1>();
-    test_string_ctor<31>();
-    test_string_ctor<32>();
-    test_string_ctor<33>();
-    test_string_ctor<63>();
-    test_string_ctor<64>();
-    test_string_ctor<65>();
-    test_string_ctor<1000>();
-    test_for_non_eager_instantiation();
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
 
-    return 0;
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
index b4de74b00422b..c3c30490d90a2 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.cons/ull_ctor.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset(unsigned long long val);
+// bitset(unsigned long long val); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -18,7 +18,7 @@
 TEST_MSVC_DIAGNOSTIC_IGNORED(6294) // Ill-defined for-loop:  initial condition does not satisfy test.  Loop body not executed.
 
 template <std::size_t N>
-void test_val_ctor()
+TEST_CONSTEXPR_CXX23 void test_val_ctor()
 {
     {
         TEST_CONSTEXPR std::bitset<N> v(0xAAAAAAAAAAAAAAAAULL);
@@ -37,17 +37,26 @@ void test_val_ctor()
 #endif
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_val_ctor<0>();
+  test_val_ctor<1>();
+  test_val_ctor<31>();
+  test_val_ctor<32>();
+  test_val_ctor<33>();
+  test_val_ctor<63>();
+  test_val_ctor<64>();
+  test_val_ctor<65>();
+  test_val_ctor<1000>();
+
+  return true;
+}
+
 int main(int, char**)
 {
-    test_val_ctor<0>();
-    test_val_ctor<1>();
-    test_val_ctor<31>();
-    test_val_ctor<32>();
-    test_val_ctor<33>();
-    test_val_ctor<63>();
-    test_val_ctor<64>();
-    test_val_ctor<65>();
-    test_val_ctor<1000>();
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/all.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/all.pass.cpp
index b1f57b1375753..8b27ffc7795e0 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/all.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/all.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bool all() const;
+// bool all() const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -15,7 +15,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_all() {
+TEST_CONSTEXPR_CXX23 void test_all() {
     std::bitset<N> v;
     v.reset();
     assert(v.all() == (N == 0));
@@ -27,16 +27,25 @@ void test_all() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_all<0>();
+  test_all<1>();
+  test_all<31>();
+  test_all<32>();
+  test_all<33>();
+  test_all<63>();
+  test_all<64>();
+  test_all<65>();
+  test_all<1000>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_all<0>();
-    test_all<1>();
-    test_all<31>();
-    test_all<32>();
-    test_all<33>();
-    test_all<63>();
-    test_all<64>();
-    test_all<65>();
-    test_all<1000>();
-
-    return 0;
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/any.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/any.pass.cpp
index 966a53b7d9b2b..f53a527c1fea3 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/any.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/any.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bool any() const;
+// bool any() const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -15,7 +15,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_any() {
+TEST_CONSTEXPR_CXX23 void test_any() {
     std::bitset<N> v;
     v.reset();
     assert(v.any() == false);
@@ -30,16 +30,25 @@ void test_any() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_any<0>();
+  test_any<1>();
+  test_any<31>();
+  test_any<32>();
+  test_any<33>();
+  test_any<63>();
+  test_any<64>();
+  test_any<65>();
+  test_any<1000>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_any<0>();
-    test_any<1>();
-    test_any<31>();
-    test_any<32>();
-    test_any<33>();
-    test_any<63>();
-    test_any<64>();
-    test_any<65>();
-    test_any<1000>();
-
-    return 0;
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/count.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/count.pass.cpp
index 81311bb68a358..4a21f452fa467 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/count.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/count.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test size_t count() const;
+// size_t count() const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_count() {
+TEST_CONSTEXPR_CXX23 void test_count() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         const std::bitset<N> v = cases[c];
@@ -30,16 +30,25 @@ void test_count() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_count<0>();
+  test_count<1>();
+  test_count<31>();
+  test_count<32>();
+  test_count<33>();
+  test_count<63>();
+  test_count<64>();
+  test_count<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_count<0>();
-    test_count<1>();
-    test_count<31>();
-    test_count<32>();
-    test_count<33>();
-    test_count<63>();
-    test_count<64>();
-    test_count<65>();
-    test_count<1000>();
-
-    return 0;
+  test();
+  test_count<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp
index 841030ccdf749..79fa505e63cd3 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/flip_all.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& flip();
+// bitset<N>& flip(); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_flip_all() {
+TEST_CONSTEXPR_CXX23 void test_flip_all() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         std::bitset<N> v1 = cases[c];
@@ -28,16 +28,25 @@ void test_flip_all() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_flip_all<0>();
+  test_flip_all<1>();
+  test_flip_all<31>();
+  test_flip_all<32>();
+  test_flip_all<33>();
+  test_flip_all<63>();
+  test_flip_all<64>();
+  test_flip_all<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_flip_all<0>();
-    test_flip_all<1>();
-    test_flip_all<31>();
-    test_flip_all<32>();
-    test_flip_all<33>();
-    test_flip_all<63>();
-    test_flip_all<64>();
-    test_flip_all<65>();
-    test_flip_all<1000>();
-
-    return 0;
+  test();
+  test_flip_all<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.out_of_range.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.out_of_range.pass.cpp
index f6165b7b38d2f..1e49fbc245372 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.out_of_range.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.out_of_range.pass.cpp
@@ -8,7 +8,7 @@
 
 // UNSUPPORTED: no-exceptions
 
-// test bitset<N>& flip(size_t pos);
+// bitset<N>& flip(size_t pos); // constexpr since C++23
 
 // Make sure we throw std::out_of_range when calling flip() on an OOB index.
 

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
index 3e0942a2fd7e5..adb8d05b5e7f5 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/flip_one.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& flip(size_t pos);
+// bitset<N>& flip(size_t pos); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_flip_one() {
+TEST_CONSTEXPR_CXX23 void test_flip_one() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         std::bitset<N> v = cases[c];
@@ -34,16 +34,25 @@ void test_flip_one() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_flip_one<0>();
+  test_flip_one<1>();
+  test_flip_one<31>();
+  test_flip_one<32>();
+  test_flip_one<33>();
+  test_flip_one<63>();
+  test_flip_one<64>();
+  test_flip_one<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_flip_one<0>();
-    test_flip_one<1>();
-    test_flip_one<31>();
-    test_flip_one<32>();
-    test_flip_one<33>();
-    test_flip_one<63>();
-    test_flip_one<64>();
-    test_flip_one<65>();
-    test_flip_one<1000>();
-
-    return 0;
+  test();
+  test_flip_one<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp
index db2c464df2f96..8d3aeca7da3c6 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/index.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>::reference operator[](size_t pos);
+// bitset<N>::reference operator[](size_t pos); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_index() {
+TEST_CONSTEXPR_CXX23 void test_index() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         std::bitset<N> v1 = cases[c];
@@ -46,22 +46,31 @@ void test_index() {
     }
 }
 
-int main(int, char**) {
-    test_index<0>();
-    test_index<1>();
-    test_index<31>();
-    test_index<32>();
-    test_index<33>();
-    test_index<63>();
-    test_index<64>();
-    test_index<65>();
-    test_index<1000>();
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_index<0>();
+  test_index<1>();
+  test_index<31>();
+  test_index<32>();
+  test_index<33>();
+  test_index<63>();
+  test_index<64>();
+  test_index<65>();
+
+  std::bitset<1> set;
+  set[0] = false;
+  auto b = set[0];
+  set[0] = true;
+  assert(b);
 
-    std::bitset<1> set;
-    set[0] = false;
-    auto b = set[0];
-    set[0] = true;
-    assert(b);
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  test_index<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
 
-    return 0;
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp
index 4c0830b4125c2..77eb9056bc6d9 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/index_const.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test constexpr bool operator[](size_t pos) const;
+// constexpr bool operator[](size_t pos) const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_index_const() {
+TEST_CONSTEXPR_CXX23 void test_index_const() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         std::bitset<N> const v = cases[c];
@@ -32,16 +32,15 @@ void test_index_const() {
 #endif
 }
 
-int main(int, char**) {
-    test_index_const<0>();
-    test_index_const<1>();
-    test_index_const<31>();
-    test_index_const<32>();
-    test_index_const<33>();
-    test_index_const<63>();
-    test_index_const<64>();
-    test_index_const<65>();
-    test_index_const<1000>();
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_index_const<0>();
+  test_index_const<1>();
+  test_index_const<31>();
+  test_index_const<32>();
+  test_index_const<33>();
+  test_index_const<63>();
+  test_index_const<64>();
+  test_index_const<65>();
 
   std::bitset<1> set_;
   set_[0] = false;
@@ -54,5 +53,15 @@ int main(int, char**) {
   assert(b);
 #endif
 
-    return 0;
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  test_index_const<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp
index 4d5f9a0a8521f..64c2a2c185ffb 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N> operator<<(size_t pos) const;
+// bitset<N> operator<<(size_t pos) const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_left_shift() {
+TEST_CONSTEXPR_CXX23 void test_left_shift() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         for (std::size_t s = 0; s <= N+1; ++s) {
@@ -28,16 +28,25 @@ void test_left_shift() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_left_shift<0>();
+  test_left_shift<1>();
+  test_left_shift<31>();
+  test_left_shift<32>();
+  test_left_shift<33>();
+  test_left_shift<63>();
+  test_left_shift<64>();
+  test_left_shift<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_left_shift<0>();
-    test_left_shift<1>();
-    test_left_shift<31>();
-    test_left_shift<32>();
-    test_left_shift<33>();
-    test_left_shift<63>();
-    test_left_shift<64>();
-    test_left_shift<65>();
-    test_left_shift<1000>();
-
-    return 0;
+  test();
+  test_left_shift<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp
index d8802e9dfaf5f..521a4ff13abba 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/left_shift_eq.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& operator<<=(size_t pos);
+// bitset<N>& operator<<=(size_t pos); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_left_shift() {
+TEST_CONSTEXPR_CXX23 bool test_left_shift() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         for (std::size_t s = 0; s <= N+1; ++s) {
@@ -31,18 +31,29 @@ void test_left_shift() {
                     assert(v1[i] == v2[i-s]);
         }
     }
+    return true;
 }
 
 int main(int, char**) {
-    test_left_shift<0>();
-    test_left_shift<1>();
-    test_left_shift<31>();
-    test_left_shift<32>();
-    test_left_shift<33>();
-    test_left_shift<63>();
-    test_left_shift<64>();
-    test_left_shift<65>();
-    test_left_shift<1000>();
+  test_left_shift<0>();
+  test_left_shift<1>();
+  test_left_shift<31>();
+  test_left_shift<32>();
+  test_left_shift<33>();
+  test_left_shift<63>();
+  test_left_shift<64>();
+  test_left_shift<65>();
+  test_left_shift<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test_left_shift<0>());
+  static_assert(test_left_shift<1>());
+  static_assert(test_left_shift<31>());
+  static_assert(test_left_shift<32>());
+  static_assert(test_left_shift<33>());
+  static_assert(test_left_shift<63>());
+  static_assert(test_left_shift<64>());
+  static_assert(test_left_shift<65>());
+#endif
 
-    return 0;
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/none.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/none.pass.cpp
index 9143fc42f3c47..4dbe3a4c6f78f 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/none.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/none.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bool none() const;
+// bool none() const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -15,7 +15,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_none() {
+TEST_CONSTEXPR_CXX23 void test_none() {
     std::bitset<N> v;
     v.reset();
     assert(v.none() == true);
@@ -30,16 +30,25 @@ void test_none() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_none<0>();
+  test_none<1>();
+  test_none<31>();
+  test_none<32>();
+  test_none<33>();
+  test_none<63>();
+  test_none<64>();
+  test_none<65>();
+  test_none<1000>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_none<0>();
-    test_none<1>();
-    test_none<31>();
-    test_none<32>();
-    test_none<33>();
-    test_none<63>();
-    test_none<64>();
-    test_none<65>();
-    test_none<1000>();
-
-    return 0;
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp
index 7e9410aa96c50..ddfcf763958a8 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/not_all.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N> operator~() const;
+// bitset<N> operator~() const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_not_all() {
+TEST_CONSTEXPR_CXX23 void test_not_all() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         std::bitset<N> v1 = cases[c];
@@ -27,16 +27,25 @@ void test_not_all() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_not_all<0>();
+  test_not_all<1>();
+  test_not_all<31>();
+  test_not_all<32>();
+  test_not_all<33>();
+  test_not_all<63>();
+  test_not_all<64>();
+  test_not_all<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_not_all<0>();
-    test_not_all<1>();
-    test_not_all<31>();
-    test_not_all<32>();
-    test_not_all<33>();
-    test_not_all<63>();
-    test_not_all<64>();
-    test_not_all<65>();
-    test_not_all<1000>();
-
-    return 0;
+  test();
+  test_not_all<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp
index f341f1f752077..e8ab264f4bab6 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/op_and_eq.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& operator&=(const bitset<N>& rhs);
+// bitset<N>& operator&=(const bitset<N>& rhs); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_op_and_eq() {
+TEST_CONSTEXPR_CXX23 void test_op_and_eq() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c1 = 0; c1 != cases.size(); ++c1) {
         for (std::size_t c2 = 0; c2 != cases.size(); ++c2) {
@@ -31,16 +31,25 @@ void test_op_and_eq() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_op_and_eq<0>();
+  test_op_and_eq<1>();
+  test_op_and_eq<31>();
+  test_op_and_eq<32>();
+  test_op_and_eq<33>();
+  test_op_and_eq<63>();
+  test_op_and_eq<64>();
+  test_op_and_eq<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_op_and_eq<0>();
-    test_op_and_eq<1>();
-    test_op_and_eq<31>();
-    test_op_and_eq<32>();
-    test_op_and_eq<33>();
-    test_op_and_eq<63>();
-    test_op_and_eq<64>();
-    test_op_and_eq<65>();
-    test_op_and_eq<1000>();
-
-    return 0;
+  test();
+  test_op_and_eq<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp
index d0b424aaca4df..98b602de90a09 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/op_eq_eq.pass.cpp
@@ -8,8 +8,8 @@
 
 // test:
 
-// bool operator==(const bitset<N>& rhs) const;
-// bool operator!=(const bitset<N>& rhs) const;
+// bool operator==(const bitset<N>& rhs) const; // constexpr since C++23
+// bool operator!=(const bitset<N>& rhs) const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -20,7 +20,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_equality() {
+TEST_CONSTEXPR_CXX23 void test_equality() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         std::bitset<N> const v1 = cases[c];
@@ -33,16 +33,25 @@ void test_equality() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_equality<0>();
+  test_equality<1>();
+  test_equality<31>();
+  test_equality<32>();
+  test_equality<33>();
+  test_equality<63>();
+  test_equality<64>();
+  test_equality<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_equality<0>();
-    test_equality<1>();
-    test_equality<31>();
-    test_equality<32>();
-    test_equality<33>();
-    test_equality<63>();
-    test_equality<64>();
-    test_equality<65>();
-    test_equality<1000>();
-
-    return 0;
+  test();
+  test_equality<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp
index be8f9d8c9f463..0d0d62432e01d 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/op_or_eq.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& operator|=(const bitset<N>& rhs);
+// bitset<N>& operator|=(const bitset<N>& rhs); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_op_or_eq() {
+TEST_CONSTEXPR_CXX23 void test_op_or_eq() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c1 = 0; c1 != cases.size(); ++c1) {
         for (std::size_t c2 = 0; c2 != cases.size(); ++c2) {
@@ -31,16 +31,25 @@ void test_op_or_eq() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_op_or_eq<0>();
+  test_op_or_eq<1>();
+  test_op_or_eq<31>();
+  test_op_or_eq<32>();
+  test_op_or_eq<33>();
+  test_op_or_eq<63>();
+  test_op_or_eq<64>();
+  test_op_or_eq<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_op_or_eq<0>();
-    test_op_or_eq<1>();
-    test_op_or_eq<31>();
-    test_op_or_eq<32>();
-    test_op_or_eq<33>();
-    test_op_or_eq<63>();
-    test_op_or_eq<64>();
-    test_op_or_eq<65>();
-    test_op_or_eq<1000>();
-
-    return 0;
+  test();
+  test_op_or_eq<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp
index d54d9d5583c74..af4e4a84a62fa 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/op_xor_eq.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& operator^=(const bitset<N>& rhs);
+// bitset<N>& operator^=(const bitset<N>& rhs); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_op_xor_eq() {
+TEST_CONSTEXPR_CXX23 bool test_op_xor_eq() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c1 = 0; c1 != cases.size(); ++c1) {
         for (std::size_t c2 = 0; c2 != cases.size(); ++c2) {
@@ -29,18 +29,29 @@ void test_op_xor_eq() {
                 assert(v1[i] == (v3[i] != v2[i]));
         }
     }
+    return true;
 }
 
 int main(int, char**) {
-    test_op_xor_eq<0>();
-    test_op_xor_eq<1>();
-    test_op_xor_eq<31>();
-    test_op_xor_eq<32>();
-    test_op_xor_eq<33>();
-    test_op_xor_eq<63>();
-    test_op_xor_eq<64>();
-    test_op_xor_eq<65>();
-    test_op_xor_eq<1000>();
+  test_op_xor_eq<0>();
+  test_op_xor_eq<1>();
+  test_op_xor_eq<31>();
+  test_op_xor_eq<32>();
+  test_op_xor_eq<33>();
+  test_op_xor_eq<63>();
+  test_op_xor_eq<64>();
+  test_op_xor_eq<65>();
+  test_op_xor_eq<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test_op_xor_eq<0>());
+  static_assert(test_op_xor_eq<1>());
+  static_assert(test_op_xor_eq<31>());
+  static_assert(test_op_xor_eq<32>());
+  static_assert(test_op_xor_eq<33>());
+  static_assert(test_op_xor_eq<63>());
+  static_assert(test_op_xor_eq<64>());
+  static_assert(test_op_xor_eq<65>());
+#endif
 
-    return 0;
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp
index 8ac6067dbf467..9f77cca456abb 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/reset_all.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& reset();
+// bitset<N>& reset(); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -15,7 +15,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_reset_all() {
+TEST_CONSTEXPR_CXX23 void test_reset_all() {
     std::bitset<N> v;
     v.set();
     v.reset();
@@ -23,16 +23,25 @@ void test_reset_all() {
         assert(!v[i]);
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_reset_all<0>();
+  test_reset_all<1>();
+  test_reset_all<31>();
+  test_reset_all<32>();
+  test_reset_all<33>();
+  test_reset_all<63>();
+  test_reset_all<64>();
+  test_reset_all<65>();
+  test_reset_all<1000>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_reset_all<0>();
-    test_reset_all<1>();
-    test_reset_all<31>();
-    test_reset_all<32>();
-    test_reset_all<33>();
-    test_reset_all<63>();
-    test_reset_all<64>();
-    test_reset_all<65>();
-    test_reset_all<1000>();
-
-    return 0;
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.out_of_range.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.out_of_range.pass.cpp
index 0613b05839a56..4dc854a0b5852 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.out_of_range.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.out_of_range.pass.cpp
@@ -8,7 +8,7 @@
 
 // UNSUPPORTED: no-exceptions
 
-// test bitset<N>& reset(size_t pos);
+// bitset<N>& reset(size_t pos); // constexpr since C++23
 
 // Make sure we throw std::out_of_range when calling reset() on an OOB index.
 

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
index cdf52f72c4f22..0517e5af4e5fa 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/reset_one.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& reset(size_t pos);
+// bitset<N>& reset(size_t pos); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -19,7 +19,7 @@
 TEST_MSVC_DIAGNOSTIC_IGNORED(6294) // Ill-defined for-loop:  initial condition does not satisfy test.  Loop body not executed.
 
 template <std::size_t N>
-void test_reset_one() {
+TEST_CONSTEXPR_CXX23 void test_reset_one() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         for (std::size_t i = 0; i != N; ++i) {
@@ -30,16 +30,25 @@ void test_reset_one() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_reset_one<0>();
+  test_reset_one<1>();
+  test_reset_one<31>();
+  test_reset_one<32>();
+  test_reset_one<33>();
+  test_reset_one<63>();
+  test_reset_one<64>();
+  test_reset_one<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_reset_one<0>();
-    test_reset_one<1>();
-    test_reset_one<31>();
-    test_reset_one<32>();
-    test_reset_one<33>();
-    test_reset_one<63>();
-    test_reset_one<64>();
-    test_reset_one<65>();
-    test_reset_one<1000>();
-
-    return 0;
+  test();
+  test_reset_one<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp
index 46eb17d1fa8dd..ec023dcdfd3c6 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/right_shift.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N> operator>>(size_t pos) const;
+// bitset<N> operator>>(size_t pos) const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_right_shift() {
+TEST_CONSTEXPR_CXX23 bool test_right_shift() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         for (std::size_t s = 0; s <= N+1; ++s) {
@@ -26,18 +26,29 @@ void test_right_shift() {
             assert((v1 >>= s) == (v2 >> s));
         }
     }
+    return true;
 }
 
 int main(int, char**) {
-    test_right_shift<0>();
-    test_right_shift<1>();
-    test_right_shift<31>();
-    test_right_shift<32>();
-    test_right_shift<33>();
-    test_right_shift<63>();
-    test_right_shift<64>();
-    test_right_shift<65>();
-    test_right_shift<1000>();
+  test_right_shift<0>();
+  test_right_shift<1>();
+  test_right_shift<31>();
+  test_right_shift<32>();
+  test_right_shift<33>();
+  test_right_shift<63>();
+  test_right_shift<64>();
+  test_right_shift<65>();
+  test_right_shift<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test_right_shift<0>());
+  static_assert(test_right_shift<1>());
+  static_assert(test_right_shift<31>());
+  static_assert(test_right_shift<32>());
+  static_assert(test_right_shift<33>());
+  static_assert(test_right_shift<63>());
+  static_assert(test_right_shift<64>());
+  static_assert(test_right_shift<65>());
+#endif
 
-    return 0;
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp
index a32f602d0c03b..bf182523880d1 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/right_shift_eq.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& operator<<=(size_t pos);
+// bitset<N>& operator<<=(size_t pos); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_right_shift() {
+TEST_CONSTEXPR_CXX23 bool test_right_shift() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         for (std::size_t s = 0; s <= N+1; ++s) {
@@ -31,18 +31,29 @@ void test_right_shift() {
                     assert(v1[i] == 0);
         }
     }
+    return true;
 }
 
 int main(int, char**) {
-    test_right_shift<0>();
-    test_right_shift<1>();
-    test_right_shift<31>();
-    test_right_shift<32>();
-    test_right_shift<33>();
-    test_right_shift<63>();
-    test_right_shift<64>();
-    test_right_shift<65>();
-    test_right_shift<1000>();
+  test_right_shift<0>();
+  test_right_shift<1>();
+  test_right_shift<31>();
+  test_right_shift<32>();
+  test_right_shift<33>();
+  test_right_shift<63>();
+  test_right_shift<64>();
+  test_right_shift<65>();
+  test_right_shift<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test_right_shift<0>());
+  static_assert(test_right_shift<1>());
+  static_assert(test_right_shift<31>());
+  static_assert(test_right_shift<32>());
+  static_assert(test_right_shift<33>());
+  static_assert(test_right_shift<63>());
+  static_assert(test_right_shift<64>());
+  static_assert(test_right_shift<65>());
+#endif
 
-    return 0;
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp
index a37e4474c2e87..632454186ae49 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/set_all.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& set();
+// bitset<N>& set(); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -15,23 +15,32 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_set_all() {
+TEST_CONSTEXPR_CXX23 void test_set_all() {
     std::bitset<N> v;
     v.set();
     for (std::size_t i = 0; i < v.size(); ++i)
         assert(v[i]);
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_set_all<0>();
+  test_set_all<1>();
+  test_set_all<31>();
+  test_set_all<32>();
+  test_set_all<33>();
+  test_set_all<63>();
+  test_set_all<64>();
+  test_set_all<65>();
+  test_set_all<1000>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_set_all<0>();
-    test_set_all<1>();
-    test_set_all<31>();
-    test_set_all<32>();
-    test_set_all<33>();
-    test_set_all<63>();
-    test_set_all<64>();
-    test_set_all<65>();
-    test_set_all<1000>();
-
-    return 0;
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/set_one.out_of_range.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/set_one.out_of_range.pass.cpp
index 2d93e3e5e9f4b..2a7eb11cef88e 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/set_one.out_of_range.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/set_one.out_of_range.pass.cpp
@@ -8,7 +8,7 @@
 
 // UNSUPPORTED: no-exceptions
 
-// test bitset<N>& set(size_t pos, bool val = true);
+// bitset<N>& set(size_t pos, bool val = true); // constexpr since C++23
 
 // Make sure we throw std::out_of_range when calling set() on an OOB index.
 

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
index 7d95622187247..e5b494dbff8fd 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/set_one.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N>& set(size_t pos, bool val = true);
+// bitset<N>& set(size_t pos, bool val = true); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_set_one() {
+TEST_CONSTEXPR_CXX23 void test_set_one() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         std::bitset<N> v = cases[c];
@@ -31,16 +31,25 @@ void test_set_one() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_set_one<0>();
+  test_set_one<1>();
+  test_set_one<31>();
+  test_set_one<32>();
+  test_set_one<33>();
+  test_set_one<63>();
+  test_set_one<64>();
+  test_set_one<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_set_one<0>();
-    test_set_one<1>();
-    test_set_one<31>();
-    test_set_one<32>();
-    test_set_one<33>();
-    test_set_one<63>();
-    test_set_one<64>();
-    test_set_one<65>();
-    test_set_one<1000>();
-
-    return 0;
+  test();
+  test_set_one<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/size.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/size.pass.cpp
index 2aafae0da9720..0237fa31acb92 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/size.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/size.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test size_t count() const;
+// size_t count() const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -14,21 +14,30 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_size() {
+TEST_CONSTEXPR_CXX23 void test_size() {
     const std::bitset<N> v;
     assert(v.size() == N);
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_size<0>();
+  test_size<1>();
+  test_size<31>();
+  test_size<32>();
+  test_size<33>();
+  test_size<63>();
+  test_size<64>();
+  test_size<65>();
+  test_size<1000>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_size<0>();
-    test_size<1>();
-    test_size<31>();
-    test_size<32>();
-    test_size<33>();
-    test_size<63>();
-    test_size<64>();
-    test_size<65>();
-    test_size<1000>();
-
-    return 0;
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/test.out_of_range.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/test.out_of_range.pass.cpp
index 7c05d2abfec91..37009c67ac3d2 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/test.out_of_range.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/test.out_of_range.pass.cpp
@@ -8,7 +8,7 @@
 
 // UNSUPPORTED: no-exceptions
 
-// test constexpr bool test(size_t pos) const;
+// constexpr bool test(size_t pos) const;
 
 // Make sure we throw std::out_of_range when calling test() on an OOB index.
 

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/test.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
index ea5aa996a490b..92e6496096aa1 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/test.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test constexpr bool test(size_t pos) const;
+// bool test(size_t pos) const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_test() {
+TEST_CONSTEXPR_CXX23 void test_test() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         std::bitset<N> const v = cases[c];
@@ -29,16 +29,25 @@ void test_test() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_test<0>();
+  test_test<1>();
+  test_test<31>();
+  test_test<32>();
+  test_test<33>();
+  test_test<63>();
+  test_test<64>();
+  test_test<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_test<0>();
-    test_test<1>();
-    test_test<31>();
-    test_test<32>();
-    test_test<33>();
-    test_test<63>();
-    test_test<64>();
-    test_test<65>();
-    test_test<1000>();
-
-    return 0;
+  test();
+  test_test<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp
index 2ad9c2d787933..78c58f678e796 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/to_string.pass.cpp
@@ -10,15 +10,15 @@
 
 // template <class charT, class traits, class Allocator>
 // basic_string<charT, traits, Allocator>
-// to_string(charT zero = charT('0'), charT one = charT('1')) const;
+// to_string(charT zero = charT('0'), charT one = charT('1')) const; // constexpr since C++23
 //
 // template <class charT, class traits>
-// basic_string<charT, traits, allocator<charT> > to_string() const;
+// basic_string<charT, traits, allocator<charT> > to_string() const; // constexpr since C++23
 //
 // template <class charT>
-// basic_string<charT, char_traits<charT>, allocator<charT> > to_string() const;
+// basic_string<charT, char_traits<charT>, allocator<charT> > to_string() const; // constexpr since C++23
 //
-// basic_string<char, char_traits<char>, allocator<char> > to_string() const;
+// basic_string<char, char_traits<char>, allocator<char> > to_string() const; // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -31,7 +31,7 @@
 #include "test_macros.h"
 
 template <class CharT, std::size_t N>
-void check_equal(std::basic_string<CharT> const& s, std::bitset<N> const& b, CharT zero, CharT one) {
+TEST_CONSTEXPR_CXX23 void check_equal(std::basic_string<CharT> const& s, std::bitset<N> const& b, CharT zero, CharT one) {
     assert(s.size() == b.size());
     for (std::size_t i = 0; i < b.size(); ++i) {
         if (b[i]) {
@@ -43,7 +43,7 @@ void check_equal(std::basic_string<CharT> const& s, std::bitset<N> const& b, Cha
 }
 
 template <std::size_t N>
-void test_to_string() {
+TEST_CONSTEXPR_CXX23 bool test_to_string() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c = 0; c != cases.size(); ++c) {
         std::bitset<N> const v = cases[c];
@@ -106,18 +106,29 @@ void test_to_string() {
             check_equal(s, v, 'x', 'y');
         }
     }
+    return true;
 }
 
 int main(int, char**) {
-    test_to_string<0>();
-    test_to_string<1>();
-    test_to_string<31>();
-    test_to_string<32>();
-    test_to_string<33>();
-    test_to_string<63>();
-    test_to_string<64>();
-    test_to_string<65>();
-    test_to_string<1000>();
+  test_to_string<0>();
+  test_to_string<1>();
+  test_to_string<31>();
+  test_to_string<32>();
+  test_to_string<33>();
+  test_to_string<63>();
+  test_to_string<64>();
+  test_to_string<65>();
+  test_to_string<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test_to_string<0>());
+  static_assert(test_to_string<1>());
+  static_assert(test_to_string<31>());
+  static_assert(test_to_string<32>());
+  static_assert(test_to_string<33>());
+  static_assert(test_to_string<63>());
+  static_assert(test_to_string<64>());
+  static_assert(test_to_string<65>());
+#endif
 
-    return 0;
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/to_ullong.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/to_ullong.pass.cpp
index 683b6629e7bbf..cbc8da96be1b1 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/to_ullong.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/to_ullong.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test unsigned long long to_ullong() const;
+// unsigned long long to_ullong() const; // constexpr since C++23
 
 #include <bitset>
 #include <algorithm>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_to_ullong() {
+TEST_CONSTEXPR_CXX23 void test_to_ullong() {
     const std::size_t M = sizeof(unsigned long long) * CHAR_BIT < N ? sizeof(unsigned long long) * CHAR_BIT : N;
     const bool is_M_zero = std::integral_constant<bool, M == 0>::value; // avoid compiler warnings
     const std::size_t X = is_M_zero ? sizeof(unsigned long long) * CHAR_BIT - 1 : sizeof(unsigned long long) * CHAR_BIT - M;
@@ -32,9 +32,8 @@ void test_to_ullong() {
         std::min(max, max-1),
         max
     };
-    for (std::size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
-        unsigned long long j = tests[i];
-        std::bitset<N> v(j);
+    for (unsigned long long j : tests) {
+         std::bitset<N> v(j);
         assert(j == v.to_ullong());
     }
     { // test values bigger than can fit into the bitset
@@ -46,16 +45,25 @@ void test_to_ullong() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_to_ullong<0>();
+  test_to_ullong<1>();
+  test_to_ullong<31>();
+  test_to_ullong<32>();
+  test_to_ullong<33>();
+  test_to_ullong<63>();
+  test_to_ullong<64>();
+  test_to_ullong<65>();
+  test_to_ullong<1000>();
+
+  return true;
+}
+
 int main(int, char**) {
-//     test_to_ullong<0>();
-    test_to_ullong<1>();
-    test_to_ullong<31>();
-    test_to_ullong<32>();
-    test_to_ullong<33>();
-    test_to_ullong<63>();
-    test_to_ullong<64>();
-    test_to_ullong<65>();
-    test_to_ullong<1000>();
-
-    return 0;
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.members/to_ulong.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.members/to_ulong.pass.cpp
index eec2cb39c8bf1..4aa90ce119639 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.members/to_ulong.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.members/to_ulong.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test unsigned long to_ulong() const;
+// unsigned long to_ulong() const; // constexpr since C++23
 
 #include <bitset>
 #include <algorithm>
@@ -18,7 +18,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_to_ulong() {
+TEST_CONSTEXPR_CXX23 void test_to_ulong() {
     const std::size_t M = sizeof(unsigned long) * CHAR_BIT < N ? sizeof(unsigned long) * CHAR_BIT : N;
     const bool is_M_zero = std::integral_constant<bool, M == 0>::value; // avoid compiler warnings
     const std::size_t X = is_M_zero ? sizeof(unsigned long) * CHAR_BIT - 1 : sizeof(unsigned long) * CHAR_BIT - M;
@@ -33,9 +33,8 @@ void test_to_ulong() {
         std::min(max, max-1),
         max
     };
-    for (std::size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); ++i) {
-        std::size_t j = tests[i];
-        std::bitset<N> v(j);
+    for (unsigned long j : tests) {
+         std::bitset<N> v(j);
         assert(j == v.to_ulong());
     }
 
@@ -48,16 +47,25 @@ void test_to_ulong() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_to_ulong<0>();
+  test_to_ulong<1>();
+  test_to_ulong<31>();
+  test_to_ulong<32>();
+  test_to_ulong<33>();
+  test_to_ulong<63>();
+  test_to_ulong<64>();
+  test_to_ulong<65>();
+  test_to_ulong<1000>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_to_ulong<0>();
-    test_to_ulong<1>();
-    test_to_ulong<31>();
-    test_to_ulong<32>();
-    test_to_ulong<33>();
-    test_to_ulong<63>();
-    test_to_ulong<64>();
-    test_to_ulong<65>();
-    test_to_ulong<1000>();
-
-    return 0;
+  test();
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp
index a0885f91d3b1c..792f1fa453031 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.operators/op_and.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs);
+// bitset<N> operator&(const bitset<N>& lhs, const bitset<N>& rhs); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_op_and() {
+TEST_CONSTEXPR_CXX23 void test_op_and() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c1 = 0; c1 != cases.size(); ++c1) {
         for (std::size_t c2 = 0; c2 != cases.size(); ++c2) {
@@ -29,16 +29,25 @@ void test_op_and() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_op_and<0>();
+  test_op_and<1>();
+  test_op_and<31>();
+  test_op_and<32>();
+  test_op_and<33>();
+  test_op_and<63>();
+  test_op_and<64>();
+  test_op_and<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_op_and<0>();
-    test_op_and<1>();
-    test_op_and<31>();
-    test_op_and<32>();
-    test_op_and<33>();
-    test_op_and<63>();
-    test_op_and<64>();
-    test_op_and<65>();
-    test_op_and<1000>();
-
-    return 0;
+  test();
+  test_op_and<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp
index 78e68bf1b51a0..c3ea175561c25 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.operators/op_not.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs);
+// bitset<N> operator^(const bitset<N>& lhs, const bitset<N>& rhs); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_op_not() {
+TEST_CONSTEXPR_CXX23 void test_op_not() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c1 = 0; c1 != cases.size(); ++c1) {
         for (std::size_t c2 = 0; c2 != cases.size(); ++c2) {
@@ -29,16 +29,25 @@ void test_op_not() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_op_not<0>();
+  test_op_not<1>();
+  test_op_not<31>();
+  test_op_not<32>();
+  test_op_not<33>();
+  test_op_not<63>();
+  test_op_not<64>();
+  test_op_not<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_op_not<0>();
-    test_op_not<1>();
-    test_op_not<31>();
-    test_op_not<32>();
-    test_op_not<33>();
-    test_op_not<63>();
-    test_op_not<64>();
-    test_op_not<65>();
-    test_op_not<1000>();
-
-    return 0;
+  test();
+  test_op_not<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp b/libcxx/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp
index febaa7f01dcdf..bf2bfac00b0d8 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp
+++ b/libcxx/test/std/utilities/template.bitset/bitset.operators/op_or.pass.cpp
@@ -6,7 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-// test bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs);
+// bitset<N> operator|(const bitset<N>& lhs, const bitset<N>& rhs); // constexpr since C++23
 
 #include <bitset>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include "test_macros.h"
 
 template <std::size_t N>
-void test_op_or() {
+TEST_CONSTEXPR_CXX23 void test_op_or() {
     std::vector<std::bitset<N> > const cases = get_test_cases<N>();
     for (std::size_t c1 = 0; c1 != cases.size(); ++c1) {
         for (std::size_t c2 = 0; c2 != cases.size(); ++c2) {
@@ -29,16 +29,25 @@ void test_op_or() {
     }
 }
 
+TEST_CONSTEXPR_CXX23 bool test() {
+  test_op_or<0>();
+  test_op_or<1>();
+  test_op_or<31>();
+  test_op_or<32>();
+  test_op_or<33>();
+  test_op_or<63>();
+  test_op_or<64>();
+  test_op_or<65>();
+
+  return true;
+}
+
 int main(int, char**) {
-    test_op_or<0>();
-    test_op_or<1>();
-    test_op_or<31>();
-    test_op_or<32>();
-    test_op_or<33>();
-    test_op_or<63>();
-    test_op_or<64>();
-    test_op_or<65>();
-    test_op_or<1000>();
-
-    return 0;
+  test();
+  test_op_or<1000>(); // not in constexpr because of constexpr evaluation step limits
+#if TEST_STD_VER > 20
+  static_assert(test());
+#endif
+
+  return 0;
 }

diff  --git a/libcxx/test/std/utilities/template.bitset/bitset_test_cases.h b/libcxx/test/std/utilities/template.bitset/bitset_test_cases.h
index 26c2cd48b8152..3172d6f6e8b02 100644
--- a/libcxx/test/std/utilities/template.bitset/bitset_test_cases.h
+++ b/libcxx/test/std/utilities/template.bitset/bitset_test_cases.h
@@ -12,18 +12,20 @@
 #include <string>
 #include <vector>
 
+#include "test_macros.h"
+
 template <int N>
-std::vector<std::bitset<N> > get_test_cases();
+TEST_CONSTEXPR_CXX23 std::vector<std::bitset<N> > get_test_cases();
 
 template <>
-inline std::vector<std::bitset<0> > get_test_cases<0>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<0> > get_test_cases<0>() {
     std::vector<std::bitset<0> > cases;
     cases.push_back(std::bitset<0>());
     return cases;
 }
 
 template <>
-inline std::vector<std::bitset<1> > get_test_cases<1>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<1> > get_test_cases<1>() {
     std::vector<std::bitset<1> > cases;
     cases.push_back(std::bitset<1>("0"));
     cases.push_back(std::bitset<1>("1"));
@@ -31,7 +33,7 @@ inline std::vector<std::bitset<1> > get_test_cases<1>() {
 }
 
 template <>
-inline std::vector<std::bitset<2> > get_test_cases<2>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<2> > get_test_cases<2>() {
     std::vector<std::bitset<2> > cases;
     cases.push_back(std::bitset<2>("00"));
     cases.push_back(std::bitset<2>("01"));
@@ -41,7 +43,7 @@ inline std::vector<std::bitset<2> > get_test_cases<2>() {
 }
 
 template <>
-inline std::vector<std::bitset<31> > get_test_cases<31>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<31> > get_test_cases<31>() {
     std::vector<std::bitset<31> > cases;
     cases.push_back(std::bitset<31>("0000000000000000000000000000000"));
     cases.push_back(std::bitset<31>("0000000000000000000000000000001"));
@@ -59,7 +61,7 @@ inline std::vector<std::bitset<31> > get_test_cases<31>() {
 }
 
 template <>
-inline std::vector<std::bitset<32> > get_test_cases<32>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<32> > get_test_cases<32>() {
     std::vector<std::bitset<32> > cases;
     cases.push_back(std::bitset<32>("00000000000000000000000000000000"));
     cases.push_back(std::bitset<32>("00000000000000000000000000000001"));
@@ -77,7 +79,7 @@ inline std::vector<std::bitset<32> > get_test_cases<32>() {
 }
 
 template <>
-inline std::vector<std::bitset<33> > get_test_cases<33>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<33> > get_test_cases<33>() {
     std::vector<std::bitset<33> > cases;
     cases.push_back(std::bitset<33>("000000000000000000000000000000000"));
     cases.push_back(std::bitset<33>("000000000000000000000000000000001"));
@@ -95,7 +97,7 @@ inline std::vector<std::bitset<33> > get_test_cases<33>() {
 }
 
 template <>
-inline std::vector<std::bitset<63> > get_test_cases<63>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<63> > get_test_cases<63>() {
     std::vector<std::bitset<63> > cases;
     cases.push_back(std::bitset<63>("000000000000000000000000000000000000000000000000000000000000000"));
     cases.push_back(std::bitset<63>("000000000000000000000000000000000000000000000000000000000000001"));
@@ -113,7 +115,7 @@ inline std::vector<std::bitset<63> > get_test_cases<63>() {
 }
 
 template <>
-inline std::vector<std::bitset<64> > get_test_cases<64>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<64> > get_test_cases<64>() {
     std::vector<std::bitset<64> > cases;
     cases.push_back(std::bitset<64>("0000000000000000000000000000000000000000000000000000000000000000"));
     cases.push_back(std::bitset<64>("0000000000000000000000000000000000000000000000000000000000000001"));
@@ -131,7 +133,7 @@ inline std::vector<std::bitset<64> > get_test_cases<64>() {
 }
 
 template <>
-inline std::vector<std::bitset<65> > get_test_cases<65>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<65> > get_test_cases<65>() {
     std::vector<std::bitset<65> > cases;
     cases.push_back(std::bitset<65>("00000000000000000000000000000000000000000000000000000000000000000"));
     cases.push_back(std::bitset<65>("00000000000000000000000000000000000000000000000000000000000000001"));
@@ -148,7 +150,7 @@ inline std::vector<std::bitset<65> > get_test_cases<65>() {
     return cases;
 }
 
-inline std::string str_repeat(std::string s, unsigned int n) {
+TEST_CONSTEXPR_CXX23 inline std::string str_repeat(std::string s, unsigned int n) {
     std::string res = s;
     for (; n != 0; --n)
         res += s;
@@ -156,7 +158,7 @@ inline std::string str_repeat(std::string s, unsigned int n) {
 }
 
 template <>
-inline std::vector<std::bitset<1000> > get_test_cases<1000>() {
+TEST_CONSTEXPR_CXX23 inline std::vector<std::bitset<1000> > get_test_cases<1000>() {
     std::vector<std::bitset<1000> > cases;
     cases.push_back(std::bitset<1000>(std::string(1000, '0')));
     cases.push_back(std::bitset<1000>(std::string(999, '0') + std::string(1, '1')));

diff  --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index 6bea8f12f3d01..cb27f8b33b3b2 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -166,6 +166,12 @@
 # define TEST_CONSTEXPR_CXX20
 #endif
 
+#if TEST_STD_VER > 20
+#  define TEST_CONSTEXPR_CXX23 constexpr
+#else
+#  define TEST_CONSTEXPR_CXX23
+#endif
+
 #define TEST_ALIGNAS_TYPE(...) TEST_ALIGNAS(TEST_ALIGNOF(__VA_ARGS__))
 
 #if !TEST_HAS_FEATURE(cxx_rtti) && !defined(__cpp_rtti) \

diff  --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index b6078c002f446..5edffd7c11e15 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -214,6 +214,10 @@ def add_version_header(tc):
     "name": "__cpp_lib_constexpr_algorithms",
     "values": { "c++20": 201806 },
     "headers": ["algorithm"],
+  }, {
+    "name": "__cpp_lib_constexpr_bitset",
+    "values": { "c++2b": 202207 },
+    "headers": ["bitset"],
   }, {
     "name": "__cpp_lib_constexpr_cmath",
     "values": { "c++2b": 202202 },


        


More information about the libcxx-commits mailing list