[libcxx-commits] [libcxx] 16a1c85 - [libc++] Implement P1328R1 constexpr std::type_info::operator==
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 7 17:03:59 PST 2023
Author: Louis Dionne
Date: 2023-02-07T17:03:45-08:00
New Revision: 16a1c851713a5825daed8ea4a887078a63488562
URL: https://github.com/llvm/llvm-project/commit/16a1c851713a5825daed8ea4a887078a63488562
DIFF: https://github.com/llvm/llvm-project/commit/16a1c851713a5825daed8ea4a887078a63488562.diff
LOG: [libc++] Implement P1328R1 constexpr std::type_info::operator==
Differential Revision: https://reviews.llvm.org/D143447
Added:
libcxx/test/std/language.support/support.rtti/type.info/type_info.equal.pass.cpp
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/docs/ReleaseNotes.rst
libcxx/docs/Status/Cxx2bPapers.csv
libcxx/include/typeinfo
libcxx/include/version
libcxx/test/std/language.support/support.limits/support.limits.general/typeinfo.version.compile.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
libcxx/utils/generate_feature_test_macro_components.py
Removed:
################################################################################
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index b46fc8c0c4baa..df4dfc4a9a12a 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -316,7 +316,7 @@ Status
------------------------------------------------- -----------------
``__cpp_lib_constexpr_memory`` ``202202L``
------------------------------------------------- -----------------
- ``__cpp_lib_constexpr_typeinfo`` *unimplemented*
+ ``__cpp_lib_constexpr_typeinfo`` ``202106L``
------------------------------------------------- -----------------
``__cpp_lib_expected`` ``202202L``
------------------------------------------------- -----------------
diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 8a04afb1a1459..20b2b09cdaf60 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -38,6 +38,8 @@ What's New in Libc++ 17.0.0?
Implemented Papers
------------------
+- P1328R1 - `constexpr type_info::operator==()`
+
Improvements and New Features
-----------------------------
diff --git a/libcxx/docs/Status/Cxx2bPapers.csv b/libcxx/docs/Status/Cxx2bPapers.csv
index e3f39d4250547..626f6cd9bb107 100644
--- a/libcxx/docs/Status/Cxx2bPapers.csv
+++ b/libcxx/docs/Status/Cxx2bPapers.csv
@@ -14,7 +14,7 @@
"`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|"
diff --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo
index 443103939849a..5627da16cbc0c 100644
--- a/libcxx/include/typeinfo
+++ b/libcxx/include/typeinfo
@@ -21,7 +21,7 @@ class type_info
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;
@@ -59,6 +59,7 @@ public:
#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>
@@ -104,8 +105,13 @@ public:
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
diff erent translation units, so it is sufficient to compare their addresses.
+ if (__libcpp_is_constant_evaluated()) {
+ return this == &__arg;
+ }
return __compare(__arg) == 0;
}
@@ -330,9 +336,14 @@ public:
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
diff erent 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);
}
diff --git a/libcxx/include/version b/libcxx/include/version
index 9705229a1c522..44a081a688303 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -392,7 +392,7 @@ __cpp_lib_void_t 201411L <type_traits>
// # 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
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/typeinfo.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/typeinfo.version.compile.pass.cpp
index 75abf3e8fc9c0..3cb2502d0af69 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/typeinfo.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/typeinfo.version.compile.pass.cpp
@@ -48,17 +48,11 @@
#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
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 9c1816bbce518..b02679d734ae7 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
@@ -3988,17 +3988,11 @@
# 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
diff --git a/libcxx/test/std/language.support/support.rtti/type.info/type_info.equal.pass.cpp b/libcxx/test/std/language.support/support.rtti/type.info/type_info.equal.pass.cpp
new file mode 100644
index 0000000000000..3f5dd96261923
--- /dev/null
+++ b/libcxx/test/std/language.support/support.rtti/type.info/type_info.equal.pass.cpp
@@ -0,0 +1,79 @@
+//===----------------------------------------------------------------------===//
+//
+// 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;
+}
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 69cb94272de87..4cf52fb88bbf1 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -267,7 +267,6 @@ def add_version_header(tc):
"name": "__cpp_lib_constexpr_typeinfo",
"values": { "c++2b": 202106 },
"headers": ["typeinfo"],
- "unimplemented": True,
}, {
"name": "__cpp_lib_constexpr_utility",
"values": { "c++20": 201811 },
More information about the libcxx-commits
mailing list