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 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: 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); +}