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