I've just created LWG 4295 proposing this change, and am implementing it via this patch.
libstdc++-v3/ChangeLog: * include/experimental/memory (swap, make_observer_ptr): Add constexpr. (operator==, operator!=, operator<, operator>, operator<=) (operator>=): Likewise. * testsuite/experimental/memory/observer_ptr/make_observer.cc: Checks for constant evaluation. * testsuite/experimental/memory/observer_ptr/relops/relops.cc: Likewise. * testsuite/experimental/memory/observer_ptr/swap/swap.cc: Likewise. --- Tested x86_64-linux. libstdc++-v3/include/experimental/memory | 22 +++++++-------- .../memory/observer_ptr/make_observer.cc | 11 ++++++-- .../memory/observer_ptr/relops/relops.cc | 28 +++++++++++-------- .../memory/observer_ptr/swap/swap.cc | 20 ++++++++----- 4 files changed, 50 insertions(+), 31 deletions(-) diff --git a/libstdc++-v3/include/experimental/memory b/libstdc++-v3/include/experimental/memory index 131e5acc03d9..1b01462e1b26 100644 --- a/libstdc++-v3/include/experimental/memory +++ b/libstdc++-v3/include/experimental/memory @@ -148,42 +148,42 @@ inline namespace fundamentals_v2 }; // observer_ptr<> template<typename _Tp> - void + constexpr void swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept { __p1.swap(__p2); } template<typename _Tp> - observer_ptr<_Tp> + constexpr observer_ptr<_Tp> make_observer(_Tp* __p) noexcept { return observer_ptr<_Tp>(__p); } template<typename _Tp, typename _Up> - bool + constexpr bool operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return __p1.get() == __p2.get(); } template<typename _Tp, typename _Up> - bool + constexpr bool operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return !(__p1 == __p2); } template<typename _Tp> - bool + constexpr bool operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept { return !__p; } template<typename _Tp> - bool + constexpr bool operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept { return !__p; @@ -197,14 +197,14 @@ inline namespace fundamentals_v2 } template<typename _Tp> - bool + constexpr bool operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept { return bool(__p); } template<typename _Tp, typename _Up> - bool + constexpr bool operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return std::less<typename common_type<typename add_pointer<_Tp>::type, @@ -214,21 +214,21 @@ inline namespace fundamentals_v2 } template<typename _Tp, typename _Up> - bool + constexpr bool operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return __p2 < __p1; } template<typename _Tp, typename _Up> - bool + constexpr bool operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return !(__p2 < __p1); } template<typename _Tp, typename _Up> - bool + constexpr bool operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) { return !(__p1 < __p2); diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc index 048735ff63ae..1de9cf095092 100644 --- a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc @@ -20,12 +20,19 @@ #include <experimental/memory> #include <testsuite_hooks.h> -int main() +constexpr bool test() { const int i = 42; auto o = std::experimental::make_observer(&i); static_assert( std::is_same<decltype(o), - std::experimental::observer_ptr<const int>>(), "" ); + std::experimental::observer_ptr<const int>>(), "" ); VERIFY( o && *o == 42 ); VERIFY( o.get() == &i ); + return true; +} + +int main() +{ + test(); + static_assert( test(), "LWG 4295 - make_observer should be constexpr" ); } diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc index 3e23e0b452be..d03dd5dcbd80 100644 --- a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc @@ -22,13 +22,13 @@ using std::experimental::observer_ptr; -void test01() +constexpr void test01() { observer_ptr<int> a, b; VERIFY(a == b); } -void test02() +constexpr void test02() { int x[2]{}; observer_ptr<int> a{&x[0]}; @@ -40,7 +40,7 @@ void test02() VERIFY(b > a); } -void test03() +constexpr void test03() { int x{}; observer_ptr<int> a{&x}; @@ -48,9 +48,10 @@ void test03() VERIFY(a == b); } -void test04() +int x[2]{}; + +constexpr void test04() { - static constexpr int x[2]{}; constexpr observer_ptr<const int> a{&x[0]}; constexpr observer_ptr<const int> b{&x[1]}; VERIFY(a != b); @@ -60,20 +61,25 @@ void test04() VERIFY(b > a); } -void test05() +constexpr void test05() { - static constexpr int x{}; - constexpr observer_ptr<const int> a{&x}; - constexpr observer_ptr<const int> b{&x}; + constexpr observer_ptr<const int> a{&x[0]}; + constexpr observer_ptr<const int> b{&x[0]}; VERIFY(a == b); } - -int main() +constexpr bool all_tests() { test01(); test02(); test03(); test04(); test05(); + return true; +} + +int main() +{ + all_tests(); + static_assert( all_tests(), "LWG 4295 - relops should be constexpr" ); } diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc index 9e7678863512..84b8844af34d 100644 --- a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc @@ -25,7 +25,7 @@ using std::experimental::observer_ptr; struct B {}; struct D : B {}; -void test01() +constexpr void test01() { observer_ptr<int> a, b; VERIFY(a == b); @@ -33,7 +33,7 @@ void test01() VERIFY(a == b); } -void test02() +constexpr void test02() { int x{}; observer_ptr<int> a; @@ -45,7 +45,7 @@ void test02() VERIFY(!b); } -void test03() +constexpr void test03() { int x[2]{1,2}; observer_ptr<int> a{&x[0]}; @@ -57,10 +57,16 @@ void test03() VERIFY(*b == 1); } - int main() { - test01(); - test02(); - test03(); + auto tests = [] { + test01(); + test02(); + test03(); + return true; + }; + tests(); +#if __cpp_lib_constexpr_algorithms >= 201806L // >= C++20 + static_assert( tests(), "LWG 4295 - swap should be constexpr" ); +#endif } -- 2.50.1