66//
77// ===----------------------------------------------------------------------===//
88
9- // UNSUPPORTED: c++03
9+ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23
10+ // UNSUPPORTED: clang-18, clang-19, gcc-14, apple-clang-16
1011
1112// <type_traits>
1213
1819
1920#include " test_macros.h"
2021
21- #ifndef __cpp_lib_is_within_lifetime
22-
23- // Check that it doesn't exist if the feature test macro isn't defined (via ADL)
24- template <class T >
25- constexpr decltype (static_cast <void >(is_within_lifetime(std::declval<T>())), bool{}) is_within_lifetime_exists(int ) {
26- return true ;
27- }
28- template <class T >
29- constexpr bool is_within_lifetime_exists (long ) {
30- return false ;
31- }
32-
33- static_assert (!is_within_lifetime_exists<const std::integral_constant<bool , false >*>(0 ), " " );
34-
35- #elif TEST_STD_VER < 26
36- # error __cpp_lib_is_within_lifetime defined before C++26
37- #else // defined(__cpp_lib_is_within_lifetime) && TEST_STD_VER >= 26
38-
3922ASSERT_SAME_TYPE (decltype (std::is_within_lifetime(std::declval<int *>())), bool);
4023ASSERT_SAME_TYPE (decltype (std::is_within_lifetime(std::declval<const int *>())), bool);
4124ASSERT_SAME_TYPE (decltype (std::is_within_lifetime(std::declval<void *>())), bool);
@@ -58,53 +41,101 @@ static_assert(is_within_lifetime_exists<const void*>);
5841static_assert (!is_within_lifetime_exists<int >); // Not a pointer
5942static_assert (!is_within_lifetime_exists<decltype (nullptr )>); // Not a pointer
6043static_assert (!is_within_lifetime_exists<void () const >); // Not a pointer
61- static_assert (!is_within_lifetime_exists<int S::*>); // Doesn't accept pointer-to-member
62- static_assert (!is_within_lifetime_exists<void (S::*)()>);
63- static_assert (!is_within_lifetime_exists<void (*)()>); // Doesn't match `const T*`
64-
65- constexpr int i = 0 ;
66- static_assert (std::is_within_lifetime(&i));
67- static_assert (std::is_within_lifetime(const_cast <int *>(&i)));
68- static_assert (std::is_within_lifetime(static_cast <const void *>(&i)));
69- static_assert (std::is_within_lifetime(static_cast <void *>(const_cast <int *>(&i))));
70- static_assert (std::is_within_lifetime<const int >(&i));
71- static_assert (std::is_within_lifetime<int >(const_cast <int *>(&i)));
72- static_assert (std::is_within_lifetime<const void >(static_cast <const void *>(&i)));
73- static_assert (std::is_within_lifetime<void >(static_cast <void *>(const_cast <int *>(&i))));
74-
75- constexpr union {
76- int active;
77- int inactive;
78- } u{.active = 1 };
79- static_assert (std::is_within_lifetime(&u.active) && !std::is_within_lifetime(&u.inactive));
44+ static_assert (!is_within_lifetime_exists<int S::*>); // Doesn't accept pointer-to-data-member
45+ static_assert (!is_within_lifetime_exists<void (S::*)()>); // Doesn't accept pointer-to-member-function
46+ static_assert (!is_within_lifetime_exists<void (*)()>); // Doesn't match `const T*`
8047
8148consteval bool f () {
82- union {
83- int active;
84- int inactive;
85- };
86- if (std::is_within_lifetime (&active) || std::is_within_lifetime (&inactive))
87- return false ;
88- active = 1 ;
89- if (!std::is_within_lifetime (&active) || std::is_within_lifetime (&inactive))
90- return false ;
91- inactive = 1 ;
92- if (std::is_within_lifetime (&active) || !std::is_within_lifetime (&inactive))
93- return false ;
94- int j;
95- S s;
96- return std::is_within_lifetime (&j) && std::is_within_lifetime (&s);
49+ // Test that it works with global variables whose lifetime is in a
50+ // different constant expression
51+ {
52+ static constexpr int i = 0 ;
53+ static_assert (std::is_within_lifetime (&i));
54+ // (Even when cast to a different type)
55+ static_assert (std::is_within_lifetime (const_cast <int *>(&i)));
56+ static_assert (std::is_within_lifetime (static_cast <const void *>(&i)));
57+ static_assert (std::is_within_lifetime (static_cast <void *>(const_cast <int *>(&i))));
58+ static_assert (std::is_within_lifetime<const int >(&i));
59+ static_assert (std::is_within_lifetime<int >(const_cast <int *>(&i)));
60+ static_assert (std::is_within_lifetime<const void >(static_cast <const void *>(&i)));
61+ static_assert (std::is_within_lifetime<void >(static_cast <void *>(const_cast <int *>(&i))));
62+ }
63+
64+ {
65+ static constexpr union {
66+ int member1;
67+ int member2;
68+ } u{.member2 = 1 };
69+ static_assert (!std::is_within_lifetime (&u.member1 ) && std::is_within_lifetime (&u.member2 ));
70+ }
71+
72+ // Test that it works for varibles inside the same constant expression
73+ {
74+ int i = 0 ;
75+ assert (std::is_within_lifetime (&i));
76+ // (Even when cast to a different type)
77+ assert (std::is_within_lifetime (const_cast <int *>(&i)));
78+ assert (std::is_within_lifetime (static_cast <const void *>(&i)));
79+ assert (std::is_within_lifetime (static_cast <void *>(const_cast <int *>(&i))));
80+ assert (std::is_within_lifetime<const int >(&i));
81+ assert (std::is_within_lifetime<int >(const_cast <int *>(&i)));
82+ assert (std::is_within_lifetime<const void >(static_cast <const void *>(&i)));
83+ assert (std::is_within_lifetime<void >(static_cast <void *>(const_cast <int *>(&i))));
84+ }
85+ // Anonymous union
86+ {
87+ union {
88+ int member1;
89+ int member2;
90+ };
91+ assert (!std::is_within_lifetime (&member1) && !std::is_within_lifetime (&member2));
92+ member1 = 1 ;
93+ assert (std::is_within_lifetime (&member1) && !std::is_within_lifetime (&member2));
94+ member2 = 1 ;
95+ assert (!std::is_within_lifetime (&member1) && std::is_within_lifetime (&member2));
96+ }
97+ // Variant members
98+ {
99+ struct X {
100+ union {
101+ int member1;
102+ int member2;
103+ };
104+ } x;
105+ assert (!std::is_within_lifetime (&x.member1 ) && !std::is_within_lifetime (&x.member2 ));
106+ x.member1 = 1 ;
107+ assert (std::is_within_lifetime (&x.member1 ) && !std::is_within_lifetime (&x.member2 ));
108+ x.member2 = 1 ;
109+ assert (!std::is_within_lifetime (&x.member1 ) && std::is_within_lifetime (&x.member2 ));
110+ }
111+ // Unions
112+ {
113+ union X {
114+ int member1;
115+ int member2;
116+ } x;
117+ assert (!std::is_within_lifetime (&x.member1 ) && !std::is_within_lifetime (&x.member2 ));
118+ x.member1 = 1 ;
119+ assert (std::is_within_lifetime (&x.member1 ) && !std::is_within_lifetime (&x.member2 ));
120+ x.member2 = 1 ;
121+ assert (!std::is_within_lifetime (&x.member1 ) && std::is_within_lifetime (&x.member2 ));
122+ }
123+ {
124+ S s; // uninitialised
125+ assert (std::is_within_lifetime (&s));
126+ }
127+
128+ return true ;
97129}
98130static_assert (f());
99131
100- # ifndef TEST_COMPILER_MSVC
101- // MSVC doesn't support consteval propagation :(
132+ // Check that it is a consteval (and consteval-propagating) function
133+ // (i.e., taking the address of below will fail because it will be an immediate function)
102134template <typename T>
103135constexpr void does_escalate (T p) {
104136 std::is_within_lifetime (p);
105137}
106-
107- template <typename T, void (T) = does_escalate<T>>
138+ template <typename T, void (*)(T) = &does_escalate<T>>
108139constexpr bool check_escalated (int ) {
109140 return false ;
110141}
@@ -114,6 +145,3 @@ constexpr bool check_escalated(long) {
114145}
115146static_assert (check_escalated<int *>(0 ), " " );
116147static_assert (check_escalated<void *>(0 ), " " );
117- # endif // defined(TEST_COMPILER_MSVC)
118-
119- #endif // defined(__cpp_lib_is_within_lifetime) && TEST_STD_VER >= 26
0 commit comments