1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // <memory> 10 11 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 12 13 // template <class T> constexpr T* to_address(T* p) noexcept; 14 // template <class Ptr> auto to_address(const Ptr& p) noexcept; 15 16 #include <memory> 17 #include <cassert> 18 #include "test_macros.h" 19 20 class P1 21 { 22 public: 23 using element_type = int; 24 25 explicit P1(int* p) 26 : p_(p) { } 27 28 int* operator->() const noexcept 29 { return p_; } 30 31 private: 32 int* p_; 33 }; 34 35 class P2 36 { 37 public: 38 using element_type = int; 39 40 explicit P2(int* p) 41 : p_(p) { } 42 43 P1 operator->() const noexcept 44 { return p_; } 45 46 private: 47 P1 p_; 48 }; 49 50 class P3 51 { 52 public: 53 explicit P3(int* p) 54 : p_(p) { } 55 56 int* get() const noexcept 57 { return p_; } 58 59 private: 60 int* p_; 61 }; 62 63 namespace std 64 { 65 template<> 66 struct pointer_traits<::P3> 67 { 68 static int* to_address(const ::P3& p) noexcept 69 { return p.get(); } 70 }; 71 } 72 73 class P4 74 { 75 public: 76 explicit P4(int* p) 77 : p_(p) { } 78 79 int* operator->() const noexcept 80 { return nullptr; } 81 82 int* get() const noexcept 83 { return p_; } 84 85 private: 86 int* p_; 87 }; 88 89 namespace std 90 { 91 template<> 92 struct pointer_traits<::P4> 93 { 94 static int* to_address(const ::P4& p) noexcept 95 { return p.get(); } 96 }; 97 } 98 99 int n = 0; 100 static_assert(std::to_address(&n) == &n); 101 102 int main(int, char**) 103 { 104 int i = 0; 105 ASSERT_NOEXCEPT(std::to_address(&i)); 106 assert(std::to_address(&i) == &i); 107 P1 p1(&i); 108 ASSERT_NOEXCEPT(std::to_address(p1)); 109 assert(std::to_address(p1) == &i); 110 P2 p2(&i); 111 ASSERT_NOEXCEPT(std::to_address(p2)); 112 assert(std::to_address(p2) == &i); 113 P3 p3(&i); 114 ASSERT_NOEXCEPT(std::to_address(p3)); 115 assert(std::to_address(p3) == &i); 116 P4 p4(&i); 117 ASSERT_NOEXCEPT(std::to_address(p4)); 118 assert(std::to_address(p4) == &i); 119 120 return 0; 121 } 122