diff --git a/libcxx/include/__iterator/wrap_iter.h b/libcxx/include/__iterator/wrap_iter.h --- a/libcxx/include/__iterator/wrap_iter.h +++ b/libcxx/include/__iterator/wrap_iter.h @@ -13,7 +13,7 @@ #include <__config> #include <__debug> #include <__iterator/iterator_traits.h> -#include <__memory/pointer_traits.h> // __to_address +#include <__memory/pointer_traits.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -283,12 +283,18 @@ struct __is_cpp17_contiguous_iterator<__wrap_iter<_It> > : true_type {}; #endif -template -_LIBCPP_CONSTEXPR -decltype(_VSTD::__to_address(declval<_Iter>())) -__to_address(__wrap_iter<_Iter> __w) _NOEXCEPT { - return _VSTD::__to_address(__w.base()); -} +template +struct _LIBCPP_TEMPLATE_VIS pointer_traits<__wrap_iter<_It> > +{ + typedef __wrap_iter<_It> pointer; + typedef typename pointer_traits<_It>::element_type element_type; + typedef typename pointer_traits<_It>::difference_type difference_type; + + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + static element_type *to_address(pointer __w) _NOEXCEPT { + return _VSTD::__to_address(__w.base()); + } +}; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/std/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp b/libcxx/test/std/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp --- a/libcxx/test/std/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp +++ b/libcxx/test/std/utilities/memory/pointer.conversion/to_address_std_iterators.pass.cpp @@ -10,10 +10,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17 -// TODO: We should enable this test in Debug mode once we fix __wrap_iter -// to be a proper contiguous_iterator. -// UNSUPPORTED: LIBCXX-DEBUG-FIXME - // template constexpr T* to_address(T* p) noexcept; // template constexpr auto to_address(const Ptr& p) noexcept; diff --git a/libcxx/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp b/libcxx/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp --- a/libcxx/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp +++ b/libcxx/test/std/utilities/memory/pointer.traits/pointer_to.pass.cpp @@ -17,29 +17,40 @@ #include #include +#include +#include +#include + #include "test_macros.h" -#if TEST_STD_VER > 17 -constexpr -#endif -bool check() { +TEST_CONSTEXPR_CXX20 bool test() +{ { int i = 0; - static_assert((std::is_same::pointer_to(i))>::value), ""); - int* a = std::pointer_traits::pointer_to(i); - assert(a == &i); + static_assert(std::is_same::pointer_to(i)), int*>::value, ""); + assert(std::pointer_traits::pointer_to(i) == &i); } { - (std::pointer_traits::element_type)0; + int i = 0; + static_assert(std::is_same::pointer_to(i)), const int*>::value, ""); + assert(std::pointer_traits::pointer_to(i) == &i); } return true; } -int main(int, char**) { - check(); +int main(int, char**) +{ + test(); #if TEST_STD_VER > 17 - static_assert(check(), ""); + static_assert(test()); #endif - return 0; + { + // Check that pointer_traits is still well-formed, even though it has no pointer_to. + static_assert(std::is_same::element_type, void>::value, ""); + static_assert(std::is_same::element_type, const void>::value, ""); + static_assert(std::is_same::element_type, volatile void>::value, ""); + } + + return 0; }