------------------------------------------------- -----------------
``__cpp_lib_constexpr_memory`` ``202202L``
------------------------------------------------- -----------------
- ``__cpp_lib_constexpr_typeinfo`` *unimplemented*
+ ``__cpp_lib_constexpr_typeinfo`` ``202106L``
------------------------------------------------- -----------------
``__cpp_lib_expected`` ``202202L``
------------------------------------------------- -----------------
Implemented Papers
------------------
+- P1328R1 - `constexpr type_info::operator==()`
+
Improvements and New Features
-----------------------------
"`P0401R6 <https://wg21.link/P0401R6>`__","LWG","Providing size feedback in the Allocator interface","June 2021","|Complete|","15.0"
"`P0448R4 <https://wg21.link/P0448R4>`__","LWG","A strstream replacement using span<charT> as buffer","June 2021","",""
"`P1132R8 <https://wg21.link/P1132R8>`__","LWG","out_ptr - a scalable output pointer abstraction","June 2021","",""
-"`P1328R1 <https://wg21.link/P1328R1>`__","LWG","Making std::type_info::operator== constexpr","June 2021","",""
+"`P1328R1 <https://wg21.link/P1328R1>`__","LWG","Making std::type_info::operator== constexpr","June 2021","|Complete|","17.0"
"`P1425R4 <https://wg21.link/P1425R4>`__","LWG","Iterators pair constructors for stack and queue","June 2021","|Complete|","14.0","|ranges|"
"`P1518R2 <https://wg21.link/P1518R2>`__","LWG","Stop overconstraining allocators in container deduction guides","June 2021","|Complete|","13.0"
"`P1659R3 <https://wg21.link/P1659R3>`__","LWG","starts_with and ends_with","June 2021","","","|ranges|"
public:
virtual ~type_info();
- bool operator==(const type_info& rhs) const noexcept;
+ bool operator==(const type_info& rhs) const noexcept; // constexpr since C++23
bool operator!=(const type_info& rhs) const noexcept; // removed in C++20
bool before(const type_info& rhs) const noexcept;
#include <__assert> // all public C++ headers provide the assertion handler
#include <__availability>
#include <__config>
+#include <__type_traits/is_constant_evaluated.h>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
size_t hash_code() const _NOEXCEPT;
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator==(const type_info& __arg) const _NOEXCEPT {
+ // When evaluated in a constant expression, both type infos simply can't come
+ // from different translation units, so it is sufficient to compare their addresses.
+ if (__libcpp_is_constant_evaluated()) {
+ return this == &__arg;
+ }
return __compare(__arg) == 0;
}
return __impl::__hash(__type_name);
}
- _LIBCPP_INLINE_VISIBILITY
+ _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
bool operator==(const type_info& __arg) const _NOEXCEPT
{
+ // When evaluated in a constant expression, both type infos simply can't come
+ // from different translation units, so it is sufficient to compare their addresses.
+ if (__libcpp_is_constant_evaluated()) {
+ return this == &__arg;
+ }
return __impl::__eq(__type_name, __arg.__type_name);
}
// # define __cpp_lib_constexpr_cmath 202202L
# undef __cpp_lib_constexpr_memory
# define __cpp_lib_constexpr_memory 202202L
-// # define __cpp_lib_constexpr_typeinfo 202106L
+# define __cpp_lib_constexpr_typeinfo 202106L
# define __cpp_lib_expected 202202L
# define __cpp_lib_forward_like 202207L
// # define __cpp_lib_invoke_r 202106L
#elif TEST_STD_VER > 20
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_constexpr_typeinfo
-# error "__cpp_lib_constexpr_typeinfo should be defined in c++2b"
-# endif
-# if __cpp_lib_constexpr_typeinfo != 202106L
-# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++2b"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_constexpr_typeinfo
-# error "__cpp_lib_constexpr_typeinfo should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_constexpr_typeinfo
+# error "__cpp_lib_constexpr_typeinfo should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_typeinfo != 202106L
+# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++2b"
# endif
#endif // TEST_STD_VER > 20
# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++2b"
# endif
-# if !defined(_LIBCPP_VERSION)
-# ifndef __cpp_lib_constexpr_typeinfo
-# error "__cpp_lib_constexpr_typeinfo should be defined in c++2b"
-# endif
-# if __cpp_lib_constexpr_typeinfo != 202106L
-# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++2b"
-# endif
-# else // _LIBCPP_VERSION
-# ifdef __cpp_lib_constexpr_typeinfo
-# error "__cpp_lib_constexpr_typeinfo should not be defined because it is unimplemented in libc++!"
-# endif
+# ifndef __cpp_lib_constexpr_typeinfo
+# error "__cpp_lib_constexpr_typeinfo should be defined in c++2b"
+# endif
+# if __cpp_lib_constexpr_typeinfo != 202106L
+# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++2b"
# endif
# ifndef __cpp_lib_constexpr_utility
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// class type_info
+//
+// bool operator==(const type_info& rhs) const noexcept; // constexpr since C++23
+
+// UNSUPPORTED: no-rtti
+
+// When we build for Windows on top of the VC runtime, `typeinfo::operator==` may not
+// be `constexpr` (depending on the version of the VC runtime). So this test can fail.
+// UNSUPPORTED: target={{.+}}-windows-msvc && !libcpp-no-vcruntime
+
+#include <typeinfo>
+#include <cassert>
+
+#include "test_macros.h"
+
+struct Base {
+ virtual void func() {}
+};
+struct Derived : Base {
+ virtual void func() {}
+};
+
+TEST_CONSTEXPR_CXX23 bool test() {
+ // Test when storing typeid() in a const ref
+ {
+ std::type_info const& t1 = typeid(int);
+ std::type_info const& t2 = typeid(long);
+ assert(t1 == t1);
+ assert(t2 == t2);
+ assert(t1 != t2);
+ }
+
+ // Test when using `typeid()` directly
+ {
+ struct Foo { };
+ struct Bar { };
+ assert(typeid(Foo) == typeid(Foo));
+ assert(typeid(Foo) != typeid(Bar));
+ }
+
+ // Test when using typeid(object) instead of typeid(type)
+ {
+ int x = 0, y = 0;
+ long z = 0;
+ assert(typeid(x) == typeid(y));
+ assert(typeid(x) != typeid(z));
+ }
+
+ // Check with derived/base types
+ {
+ Derived derived;
+ Base const& as_base = derived;
+ assert(typeid(as_base) == typeid(Derived));
+ }
+
+ // Check noexcept-ness
+ {
+ std::type_info const& t1 = typeid(int); (void)t1;
+ std::type_info const& t2 = typeid(long); (void)t2;
+ ASSERT_NOEXCEPT(t1 == t2);
+ }
+ return true;
+}
+
+int main(int, char**) {
+ test();
+#if TEST_STD_VER >= 23
+ static_assert(test());
+#endif
+ return 0;
+}
"name": "__cpp_lib_constexpr_typeinfo",
"values": { "c++2b": 202106 },
"headers": ["typeinfo"],
- "unimplemented": True,
}, {
"name": "__cpp_lib_constexpr_utility",
"values": { "c++20": 201811 },