1 /*
2 Copyright 2017-2018 Glen Joseph Fernandes
3 (glenjofe@gmail.com)
4 
5 Distributed under the Boost Software License, Version 1.0.
6 (http://www.boost.org/LICENSE_1_0.txt)
7 */
8 #include <boost/core/pointer_traits.hpp>
9 #include <boost/core/lightweight_test.hpp>
10 
11 template<class T>
12 class P1 {
13 public:
P1(T * p)14     explicit P1(T* p)
15         : p_(p) { }
operator ->() const16     T* operator->() const BOOST_NOEXCEPT {
17         return p_;
18     }
19 private:
20     T* p_;
21 };
22 
23 template<class T>
24 class P2 {
25 public:
P2(T * p)26     explicit P2(T* p)
27         : p_(p) { }
operator ->() const28     P1<T> operator->() const BOOST_NOEXCEPT {
29         return p_;
30     }
31 private:
32     P1<T> p_;
33 };
34 
35 #if !defined(BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION)
36 template<class T>
37 class P3 {
38 public:
P3(T * p)39     explicit P3(T* p)
40         : p_(p) { }
get() const41     T* get() const BOOST_NOEXCEPT {
42         return p_;
43     }
44 private:
45     T* p_;
46 };
47 
48 namespace boost {
49 template<class T>
50 struct pointer_traits<P3<T> > {
to_addressboost::pointer_traits51     static T* to_address(const P3<T>& p) BOOST_NOEXCEPT {
52         return p.get();
53     }
54 };
55 } /* boost */
56 
57 template<class T>
58 class P4 {
59 public:
P4(T * p)60     explicit P4(T* p)
61         : p_(p) { }
operator ->() const62     T* operator->() const BOOST_NOEXCEPT {
63         return 0;
64     }
get() const65     T* get() const BOOST_NOEXCEPT {
66         return p_;
67     }
68 private:
69     int* p_;
70 };
71 
72 namespace boost {
73 template<class T>
74 struct pointer_traits<P4<T> > {
to_addressboost::pointer_traits75     static T* to_address(const P4<T>& p) BOOST_NOEXCEPT {
76         return p.get();
77     }
78 };
79 } /* boost */
80 
81 #if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
82 template<class T>
83 class P5 {
84 public:
P5(T * p)85     explicit P5(T* p)
86         : p_(p) { }
get() const87     T* get() const BOOST_NOEXCEPT {
88         return p_;
89     }
90 private:
91     T* p_;
92 };
93 
94 namespace std {
95 template<class T>
96 struct pointer_traits<P5<T> > {
to_addressstd::pointer_traits97     static T* to_address(const P5<T>& p) BOOST_NOEXCEPT {
98         return p.get();
99     }
100 };
101 } /* std */
102 
103 template<class T>
104 class P6 {
105 public:
P6(T * p)106     explicit P6(T* p)
107         : p_(p) { }
get() const108     T* get() const BOOST_NOEXCEPT {
109         return p_;
110     }
111 private:
112     T* p_;
113 };
114 
115 namespace boost {
116 template<class T>
117 struct pointer_traits<P6<T> > {
to_addressboost::pointer_traits118     static T* to_address(const P6<T>& p) BOOST_NOEXCEPT {
119         return p.get();
120     }
121 };
122 } /* boost */
123 
124 namespace std {
125 template<class T>
126 struct pointer_traits<P6<T> > {
to_addressstd::pointer_traits127     static T* to_address(const P6<T>& p) BOOST_NOEXCEPT {
128         return 0;
129     }
130 };
131 } /* std */
132 #endif
133 #endif
134 
main()135 int main()
136 {
137     int i = 0;
138     BOOST_TEST(boost::to_address(&i) == &i);
139     int* p = &i;
140     BOOST_TEST(boost::to_address(p) == &i);
141     P1<int> p1(&i);
142     BOOST_TEST(boost::to_address(p1) == &i);
143     P2<int> p2(&i);
144     BOOST_TEST(boost::to_address(p2) == &i);
145 #if !defined(BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION)
146     P3<int> p3(&i);
147     BOOST_TEST(boost::to_address(p3) == &i);
148     P4<int> p4(&i);
149     BOOST_TEST(boost::to_address(p4) == &i);
150 #if !defined(BOOST_NO_CXX11_POINTER_TRAITS)
151     P5<int> p5(&i);
152     BOOST_TEST(boost::to_address(p5) == &i);
153     P6<int> p6(&i);
154     BOOST_TEST(boost::to_address(p6) == &i);
155 #endif
156 #endif
157     return boost::report_errors();
158 }
159