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()135int 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