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