Author: ericwf Date: Wed Nov 22 11:49:21 2017 New Revision: 318865 URL: http://llvm.org/viewvc/llvm-project?rev=318865&view=rev Log: [libcxx] Implement std::to_address for C++20
Summary: Now implements P0653R2 - Utility to convert to raw pointer. Reviewers: mclow.lists, EricWF Reviewed By: EricWF Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D35470 Added: libcxx/trunk/test/std/utilities/memory/pointer.conversion/ libcxx/trunk/test/std/utilities/memory/pointer.conversion/to_address.pass.cpp Modified: libcxx/trunk/include/memory Modified: libcxx/trunk/include/memory URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=318865&r1=318864&r2=318865&view=diff ============================================================================== --- libcxx/trunk/include/memory (original) +++ libcxx/trunk/include/memory Wed Nov 22 11:49:21 2017 @@ -46,6 +46,9 @@ struct pointer_traits<T*> static pointer pointer_to(<details>) noexcept; }; +template <class T> constexpr T* to_address(T* p) noexcept; // C++20 +template <class Ptr> auto to_address(const Ptr& p) noexcept; // C++20 + template <class Alloc> struct allocator_traits { @@ -1090,13 +1093,14 @@ struct __const_void_pointer<_Ptr, _Alloc }; template <class _Tp> -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 <class _Pointer> inline _LIBCPP_INLINE_VISIBILITY typename pointer_traits<_Pointer>::element_type* @@ -1104,6 +1108,41 @@ __to_raw_pointer(_Pointer __p) _NOEXCEPT { return _VSTD::__to_raw_pointer(__p.operator->()); } +#else +template <class _Pointer> +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 <class _Pointer, class... _None> +inline _LIBCPP_INLINE_VISIBILITY +auto +__to_raw_pointer(const _Pointer& __p, _None...) _NOEXCEPT +{ + return _VSTD::__to_raw_pointer(__p.operator->()); +} + +template <class _Tp> +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 <class _Pointer> +inline _LIBCPP_INLINE_VISIBILITY +auto +to_address(const _Pointer& __p) _NOEXCEPT +{ + return _VSTD::__to_raw_pointer(__p); +} +#endif template <class _Tp, class = void> struct __has_size_type : false_type {}; Added: libcxx/trunk/test/std/utilities/memory/pointer.conversion/to_address.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/pointer.conversion/to_address.pass.cpp?rev=318865&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/memory/pointer.conversion/to_address.pass.cpp (added) +++ libcxx/trunk/test/std/utilities/memory/pointer.conversion/to_address.pass.cpp Wed Nov 22 11:49:21 2017 @@ -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. +// +//===----------------------------------------------------------------------===// + +// <memory> + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 + +// template <class T> constexpr T* to_address(T* p) noexcept; +// template <class Ptr> auto to_address(const Ptr& p) noexcept; + +#include <memory> +#include <cassert> +#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); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits