[PATCH] D35470: [libcxx] Implement std::to_address for C++20
glenjofe updated this revision to Diff 123520. glenjofe added a comment. Now implements P0653R2 which was accepted in Albuquerque. https://reviews.llvm.org/D35470 Files: include/memory test/std/utilities/memory/pointer.conversion/to_address.pass.cpp Index: test/std/utilities/memory/pointer.conversion/to_address.pass.cpp === --- test/std/utilities/memory/pointer.conversion/to_address.pass.cpp +++ test/std/utilities/memory/pointer.conversion/to_address.pass.cpp @@ -0,0 +1,111 @@ +//===--===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template constexpr T* to_address(T* p) noexcept; +// template auto to_address(const Ptr& p) noexcept; + +#include +#include + +class P1 +{ +public: +using element_type = int; + +explicit P1(int* p) +: p_(p) { } + +int* operator->() const noexcept +{ return p_; } + +private: +int* p_; +}; + +class P2 +{ +public: +using element_type = int; + +explicit P2(int* p) +: p_(p) { } + +P1 operator->() const noexcept +{ return p_; } + +private: +P1 p_; +}; + +class P3 +{ +public: +explicit P3(int* p) +: p_(p) { } + +int* get() const noexcept +{ return p_; } + +private: +int* p_; +}; + +namespace std +{ +template<> +struct pointer_traits<::P3> +{ +static int* to_address(const ::P3& p) noexcept +{ return p.get(); } +}; +} + +class P4 +{ +public: +explicit P4(int* p) +: p_(p) { } + +int* operator->() const noexcept +{ return nullptr; } + +int* get() const noexcept +{ return p_; } + +private: +int* p_; +}; + +namespace std +{ +template<> +struct pointer_traits<::P4> +{ +static int* to_address(const ::P4& p) noexcept { return p.get(); } +}; +} + +int main() +{ +int i = 0; +int* p = &i; +assert(std::to_address(p) == &i); +P1 p1(&i); +assert(std::to_address(p1) == &i); +P2 p2(&i); +assert(std::to_address(p2) == &i); +P3 p3(&i); +assert(std::to_address(p3) == &i); +P4 p4(&i); +assert(std::to_address(p4) == &i); +} Index: include/memory === --- include/memory +++ include/memory @@ -46,6 +46,9 @@ static pointer pointer_to() noexcept; }; +template constexpr T* to_address(T* p) noexcept; // C++20 +template auto to_address(const Ptr& p) noexcept; // C++20 + template struct allocator_traits { @@ -1090,20 +1093,56 @@ }; template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp* __to_raw_pointer(_Tp* __p) _NOEXCEPT { return __p; } +#if _LIBCPP_STD_VER <= 17 template inline _LIBCPP_INLINE_VISIBILITY typename pointer_traits<_Pointer>::element_type* __to_raw_pointer(_Pointer __p) _NOEXCEPT { return _VSTD::__to_raw_pointer(__p.operator->()); } +#else +template +inline _LIBCPP_INLINE_VISIBILITY +auto +__to_raw_pointer(const _Pointer& __p) _NOEXCEPT +-> decltype(pointer_traits<_Pointer>::to_address(__p)) +{ +return pointer_traits<_Pointer>::to_address(__p); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +__to_raw_pointer(const _Pointer& __p, _None...) _NOEXCEPT +{ +return _VSTD::__to_raw_pointer(__p.operator->()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY constexpr +_Tp* +to_address(_Tp* __p) _NOEXCEPT +{ +static_assert(!is_function_v<_Tp>, "_Tp is a function type"); +return __p; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +to_address(const _Pointer& __p) _NOEXCEPT +{ +return _VSTD::__to_raw_pointer(__p); +} +#endif template struct __has_size_type : false_type {}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35470: [libcxx] Implement std::to_address for C++20
glenjofe updated this revision to Diff 123531. glenjofe marked 2 inline comments as done. glenjofe added a comment. Address Eric's review comments. https://reviews.llvm.org/D35470 Files: include/memory test/std/utilities/memory/pointer.conversion/to_address.pass.cpp Index: test/std/utilities/memory/pointer.conversion/to_address.pass.cpp === --- test/std/utilities/memory/pointer.conversion/to_address.pass.cpp +++ test/std/utilities/memory/pointer.conversion/to_address.pass.cpp @@ -0,0 +1,120 @@ +//===--===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +// + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template constexpr T* to_address(T* p) noexcept; +// template auto to_address(const Ptr& p) noexcept; + +#include +#include +#include "test_macros.h" + +class P1 +{ +public: +using element_type = int; + +explicit P1(int* p) +: p_(p) { } + +int* operator->() const noexcept +{ return p_; } + +private: +int* p_; +}; + +class P2 +{ +public: +using element_type = int; + +explicit P2(int* p) +: p_(p) { } + +P1 operator->() const noexcept +{ return p_; } + +private: +P1 p_; +}; + +class P3 +{ +public: +explicit P3(int* p) +: p_(p) { } + +int* get() const noexcept +{ return p_; } + +private: +int* p_; +}; + +namespace std +{ +template<> +struct pointer_traits<::P3> +{ +static int* to_address(const ::P3& p) noexcept +{ return p.get(); } +}; +} + +class P4 +{ +public: +explicit P4(int* p) +: p_(p) { } + +int* operator->() const noexcept +{ return nullptr; } + +int* get() const noexcept +{ return p_; } + +private: +int* p_; +}; + +namespace std +{ +template<> +struct pointer_traits<::P4> +{ +static int* to_address(const ::P4& p) noexcept +{ return p.get(); } +}; +} + +int n = 0; +static_assert(std::to_address(&n) == &n); + +int main() +{ +int i = 0; +ASSERT_NOEXCEPT(std::to_address(&i)); +assert(std::to_address(&i) == &i); +P1 p1(&i); +ASSERT_NOEXCEPT(std::to_address(p1)); +assert(std::to_address(p1) == &i); +P2 p2(&i); +ASSERT_NOEXCEPT(std::to_address(p2)); +assert(std::to_address(p2) == &i); +P3 p3(&i); +ASSERT_NOEXCEPT(std::to_address(p3)); +assert(std::to_address(p3) == &i); +P4 p4(&i); +ASSERT_NOEXCEPT(std::to_address(p4)); +assert(std::to_address(p4) == &i); +} Index: include/memory === --- include/memory +++ include/memory @@ -46,6 +46,9 @@ static pointer pointer_to() noexcept; }; +template constexpr T* to_address(T* p) noexcept; // C++20 +template auto to_address(const Ptr& p) noexcept; // C++20 + template struct allocator_traits { @@ -1090,20 +1093,56 @@ }; template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR _Tp* __to_raw_pointer(_Tp* __p) _NOEXCEPT { return __p; } +#if _LIBCPP_STD_VER <= 17 template inline _LIBCPP_INLINE_VISIBILITY typename pointer_traits<_Pointer>::element_type* __to_raw_pointer(_Pointer __p) _NOEXCEPT { return _VSTD::__to_raw_pointer(__p.operator->()); } +#else +template +inline _LIBCPP_INLINE_VISIBILITY +auto +__to_raw_pointer(const _Pointer& __p) _NOEXCEPT +-> decltype(pointer_traits<_Pointer>::to_address(__p)) +{ +return pointer_traits<_Pointer>::to_address(__p); +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +__to_raw_pointer(const _Pointer& __p, _None...) _NOEXCEPT +{ +return _VSTD::__to_raw_pointer(__p.operator->()); +} + +template +inline _LIBCPP_INLINE_VISIBILITY constexpr +_Tp* +to_address(_Tp* __p) _NOEXCEPT +{ +static_assert(!is_function_v<_Tp>, "_Tp is a function type"); +return __p; +} + +template +inline _LIBCPP_INLINE_VISIBILITY +auto +to_address(const _Pointer& __p) _NOEXCEPT +{ +return _VSTD::__to_raw_pointer(__p); +} +#endif template struct __has_size_type : false_type {}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35470: [libcxx] Implement std::to_address for C++20
glenjofe added inline comments. Comment at: test/std/utilities/memory/pointer.conversion/to_address.pass.cpp:119 +ASSERT_NOEXCEPT(std::to_address(p4)); +assert(std::to_address(p4) == &i); +} EricWF wrote: > Shouldn't one of these tests hit a non-noexcept function? Both overloads of to_address are unconditionally noexcept. https://reviews.llvm.org/D35470 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35470: [libcxx] Implement std::to_address for C++20
glenjofe added a comment. Thanks Eric. Can you commit on my behalf? https://reviews.llvm.org/D35470 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35470: [libcxx] Implement pointer_traits::to_address as in P0653R0
glenjofe created this revision. glenjofe created this object with edit policy "No One". A tiny patch that implements P0653R0 (or D0653R1 which revises the former with only a small editorial change after LEWG review). Repository: rL LLVM https://reviews.llvm.org/D35470 Files: include/memory test/std/utilities/memory/pointer.traits/pointer.traits.functions/to_address.pass.cpp test/std/utilities/memory/pointer.traits/to_address.pass.cpp Index: test/std/utilities/memory/pointer.traits/to_address.pass.cpp === --- test/std/utilities/memory/pointer.traits/to_address.pass.cpp +++ test/std/utilities/memory/pointer.traits/to_address.pass.cpp @@ -0,0 +1,23 @@ +//===--===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +// + +// element_type* pointer_traits::to_address(pointer p) noexcept; + +#include +#include + +int main() +{ +int i = 0; +assert(std::pointer_traits::to_address(&i) == &i); +assert(std::pointer_traits::to_address(&i) == &i); +assert(std::pointer_traits::to_address(&i) == &i); +} Index: test/std/utilities/memory/pointer.traits/pointer.traits.functions/to_address.pass.cpp === --- test/std/utilities/memory/pointer.traits/pointer.traits.functions/to_address.pass.cpp +++ test/std/utilities/memory/pointer.traits/pointer.traits.functions/to_address.pass.cpp @@ -0,0 +1,40 @@ +//===--===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +// + +// element_type* pointer_traits::to_address(pointer p) noexcept; + +#include +#include + +struct P1 +{ + typedef int element_type; + int* value; + explicit P1(int* ptr) noexcept : value(ptr) { } + int* operator->() const noexcept { return value; } +}; + +struct P2 +{ + typedef P1::element_type element_type; + P1 value; + explicit P2(P1 ptr) noexcept : value(ptr) { } + P1 operator->() const noexcept { return value; } +}; + +int main() +{ +int i = 0; +P1 p1(&i); +assert(std::pointer_traits::to_address(p1) == &i); +P2 p2(p1); +assert(std::pointer_traits::to_address(p2) == &i); +} Index: include/memory === --- include/memory +++ include/memory @@ -32,6 +32,7 @@ template using rebind = ; static pointer pointer_to(); +static element_type* to_address(pointer p) noexcept; }; template @@ -44,6 +45,7 @@ template using rebind = U*; static pointer pointer_to() noexcept; +static element_type* to_address(pointer p) noexcept; }; template @@ -950,11 +952,20 @@ private: struct __nat {}; + +template +_LIBCPP_INLINE_VISIBILITY +static element_type* __to_address(_Tp __p) _NOEXCEPT +{return pointer_traits<_Tp>::to_address(__p);} public: _LIBCPP_INLINE_VISIBILITY static pointer pointer_to(typename conditional::value, __nat, element_type>::type& __r) {return pointer::pointer_to(__r);} + +_LIBCPP_INLINE_VISIBILITY +static element_type* to_address(pointer __p) _NOEXCEPT +{return __to_address(__p.operator->());} }; template @@ -977,6 +988,9 @@ static pointer pointer_to(typename conditional::value, __nat, element_type>::type& __r) _NOEXCEPT {return _VSTD::addressof(__r);} + +_LIBCPP_INLINE_VISIBILITY +static element_type* to_address(pointer __p) _NOEXCEPT {return __p;} }; template @@ -1089,20 +1103,12 @@ #endif }; -template -inline _LIBCPP_INLINE_VISIBILITY -_Tp* -__to_raw_pointer(_Tp* __p) _NOEXCEPT -{ -return __p; -} - template inline _LIBCPP_INLINE_VISIBILITY typename pointer_traits<_Pointer>::element_type* __to_raw_pointer(_Pointer __p) _NOEXCEPT { -return _VSTD::__to_raw_pointer(__p.operator->()); +return pointer_traits<_Pointer>::to_address(__p); } template ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D35470: [libcxx] Implement pointer_traits::to_address as in P0653R0
glenjofe updated this revision to Diff 106965. glenjofe removed rL LLVM as the repository for this revision. glenjofe added a comment. Include full context in the diff. https://reviews.llvm.org/D35470 Files: include/memory test/std/utilities/memory/pointer.traits/pointer.traits.functions/to_address.pass.cpp test/std/utilities/memory/pointer.traits/to_address.pass.cpp Index: test/std/utilities/memory/pointer.traits/to_address.pass.cpp === --- test/std/utilities/memory/pointer.traits/to_address.pass.cpp +++ test/std/utilities/memory/pointer.traits/to_address.pass.cpp @@ -0,0 +1,23 @@ +//===--===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +// + +// element_type* pointer_traits::to_address(pointer p) noexcept; + +#include +#include + +int main() +{ +int i = 0; +assert(std::pointer_traits::to_address(&i) == &i); +assert(std::pointer_traits::to_address(&i) == &i); +assert(std::pointer_traits::to_address(&i) == &i); +} Index: test/std/utilities/memory/pointer.traits/pointer.traits.functions/to_address.pass.cpp === --- test/std/utilities/memory/pointer.traits/pointer.traits.functions/to_address.pass.cpp +++ test/std/utilities/memory/pointer.traits/pointer.traits.functions/to_address.pass.cpp @@ -0,0 +1,40 @@ +//===--===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===--===// + +// + +// element_type* pointer_traits::to_address(pointer p) noexcept; + +#include +#include + +struct P1 +{ + typedef int element_type; + int* value; + explicit P1(int* ptr) noexcept : value(ptr) { } + int* operator->() const noexcept { return value; } +}; + +struct P2 +{ + typedef P1::element_type element_type; + P1 value; + explicit P2(P1 ptr) noexcept : value(ptr) { } + P1 operator->() const noexcept { return value; } +}; + +int main() +{ +int i = 0; +P1 p1(&i); +assert(std::pointer_traits::to_address(p1) == &i); +P2 p2(p1); +assert(std::pointer_traits::to_address(p2) == &i); +} Index: include/memory === --- include/memory +++ include/memory @@ -32,6 +32,7 @@ template using rebind = ; static pointer pointer_to(); +static element_type* to_address(pointer p) noexcept; }; template @@ -44,6 +45,7 @@ template using rebind = U*; static pointer pointer_to() noexcept; +static element_type* to_address(pointer p) noexcept; }; template @@ -950,11 +952,20 @@ private: struct __nat {}; + +template +_LIBCPP_INLINE_VISIBILITY +static element_type* __to_address(_Tp __p) _NOEXCEPT +{return pointer_traits<_Tp>::to_address(__p);} public: _LIBCPP_INLINE_VISIBILITY static pointer pointer_to(typename conditional::value, __nat, element_type>::type& __r) {return pointer::pointer_to(__r);} + +_LIBCPP_INLINE_VISIBILITY +static element_type* to_address(pointer __p) _NOEXCEPT +{return __to_address(__p.operator->());} }; template @@ -977,6 +988,9 @@ static pointer pointer_to(typename conditional::value, __nat, element_type>::type& __r) _NOEXCEPT {return _VSTD::addressof(__r);} + +_LIBCPP_INLINE_VISIBILITY +static element_type* to_address(pointer __p) _NOEXCEPT {return __p;} }; template @@ -1089,20 +1103,12 @@ #endif }; -template -inline _LIBCPP_INLINE_VISIBILITY -_Tp* -__to_raw_pointer(_Tp* __p) _NOEXCEPT -{ -return __p; -} - template inline _LIBCPP_INLINE_VISIBILITY typename pointer_traits<_Pointer>::element_type* __to_raw_pointer(_Pointer __p) _NOEXCEPT { -return _VSTD::__to_raw_pointer(__p.operator->()); +return pointer_traits<_Pointer>::to_address(__p); } template ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits