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++03, c++11, c++14, c++17 12 13 // template <class T> constexpr T* to_address(T* p) noexcept; 14 // template <class Ptr> constexpr 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 constexpr explicit P1(int* p) 26 : p_(p) { } 27 28 constexpr 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 constexpr explicit P2(int* p) 41 : p_(p) { } 42 43 constexpr P1 operator->() const noexcept 44 { return p_; } 45 46 private: 47 P1 p_; 48 }; 49 50 class P3 51 { 52 public: 53 constexpr explicit P3(int* p) 54 : p_(p) { } 55 56 constexpr 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 constexpr int* to_address(const ::P3& p) noexcept 69 { return p.get(); } 70 }; 71 } 72 73 class P4 74 { 75 public: 76 constexpr explicit P4(int* p) 77 : p_(p) { } 78 79 constexpr int* operator->() const noexcept 80 { return nullptr; } 81 82 constexpr 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 constexpr 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 constexpr bool test() { 103 int i = 0; 104 ASSERT_NOEXCEPT(std::to_address(&i)); 105 assert(std::to_address(&i) == &i); 106 P1 p1(&i); 107 ASSERT_NOEXCEPT(std::to_address(p1)); 108 assert(std::to_address(p1) == &i); 109 P2 p2(&i); 110 ASSERT_NOEXCEPT(std::to_address(p2)); 111 assert(std::to_address(p2) == &i); 112 P3 p3(&i); 113 ASSERT_NOEXCEPT(std::to_address(p3)); 114 assert(std::to_address(p3) == &i); 115 P4 p4(&i); 116 ASSERT_NOEXCEPT(std::to_address(p4)); 117 assert(std::to_address(p4) == &i); 118 119 return true; 120 } 121 122 int main(int, char**) { 123 test(); 124 static_assert(test()); 125 return 0; 126 } 127