libstdc++
|
00001 // <experimental/memory> -*- C++ -*- 00002 00003 // Copyright (C) 2015-2019 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file experimental/memory 00026 * This is a TS C++ Library header. 00027 */ 00028 00029 // 00030 // N4336 Working Draft, C++ Extensions for Library Fundamentals, Version 2 00031 // 00032 00033 #ifndef _GLIBCXX_EXPERIMENTAL_MEMORY 00034 #define _GLIBCXX_EXPERIMENTAL_MEMORY 1 00035 00036 #pragma GCC system_header 00037 00038 #if __cplusplus >= 201402L 00039 00040 #include <memory> 00041 #include <type_traits> 00042 #include <utility> 00043 #include <experimental/bits/shared_ptr.h> 00044 #include <bits/functional_hash.h> 00045 00046 namespace std _GLIBCXX_VISIBILITY(default) 00047 { 00048 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00049 00050 namespace experimental 00051 { 00052 inline namespace fundamentals_v2 00053 { 00054 #define __cpp_lib_experimental_observer_ptr 201411 00055 00056 template <typename _Tp> 00057 class observer_ptr 00058 { 00059 public: 00060 // publish our template parameter and variations thereof 00061 using element_type = _Tp; 00062 using __pointer = add_pointer_t<_Tp>; // exposition-only 00063 using __reference = add_lvalue_reference_t<_Tp>; // exposition-only 00064 00065 // 3.2.2, observer_ptr constructors 00066 // default c'tor 00067 constexpr observer_ptr() noexcept 00068 : __t() 00069 { } 00070 00071 // pointer-accepting c'tors 00072 constexpr observer_ptr(nullptr_t) noexcept 00073 : __t() 00074 { } 00075 00076 constexpr explicit observer_ptr(__pointer __p) noexcept 00077 : __t(__p) 00078 { } 00079 00080 // copying c'tors (in addition to compiler-generated copy c'tor) 00081 template <typename _Up, 00082 typename = typename enable_if< 00083 is_convertible<typename add_pointer<_Up>::type, __pointer 00084 >::value 00085 >::type> 00086 constexpr observer_ptr(observer_ptr<_Up> __p) noexcept 00087 : __t(__p.get()) 00088 { 00089 } 00090 00091 // 3.2.3, observer_ptr observers 00092 constexpr __pointer 00093 get() const noexcept 00094 { 00095 return __t; 00096 } 00097 00098 constexpr __reference 00099 operator*() const 00100 { 00101 return *get(); 00102 } 00103 00104 constexpr __pointer 00105 operator->() const noexcept 00106 { 00107 return get(); 00108 } 00109 00110 constexpr explicit operator bool() const noexcept 00111 { 00112 return get() != nullptr; 00113 } 00114 00115 // 3.2.4, observer_ptr conversions 00116 constexpr explicit operator __pointer() const noexcept 00117 { 00118 return get(); 00119 } 00120 00121 // 3.2.5, observer_ptr modifiers 00122 constexpr __pointer 00123 release() noexcept 00124 { 00125 __pointer __tmp = get(); 00126 reset(); 00127 return __tmp; 00128 } 00129 00130 constexpr void 00131 reset(__pointer __p = nullptr) noexcept 00132 { 00133 __t = __p; 00134 } 00135 00136 constexpr void 00137 swap(observer_ptr& __p) noexcept 00138 { 00139 std::swap(__t, __p.__t); 00140 } 00141 00142 private: 00143 __pointer __t; 00144 }; // observer_ptr<> 00145 00146 template<typename _Tp> 00147 void 00148 swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept 00149 { 00150 __p1.swap(__p2); 00151 } 00152 00153 template<typename _Tp> 00154 observer_ptr<_Tp> 00155 make_observer(_Tp* __p) noexcept 00156 { 00157 return observer_ptr<_Tp>(__p); 00158 } 00159 00160 template<typename _Tp, typename _Up> 00161 bool 00162 operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 00163 { 00164 return __p1.get() == __p2.get(); 00165 } 00166 00167 template<typename _Tp, typename _Up> 00168 bool 00169 operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 00170 { 00171 return !(__p1 == __p2); 00172 } 00173 00174 template<typename _Tp> 00175 bool 00176 operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept 00177 { 00178 return !__p; 00179 } 00180 00181 template<typename _Tp> 00182 bool 00183 operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept 00184 { 00185 return !__p; 00186 } 00187 00188 template<typename _Tp> 00189 bool 00190 operator!=(observer_ptr<_Tp> __p, nullptr_t) noexcept 00191 { 00192 return bool(__p); 00193 } 00194 00195 template<typename _Tp> 00196 bool 00197 operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept 00198 { 00199 return bool(__p); 00200 } 00201 00202 template<typename _Tp, typename _Up> 00203 bool 00204 operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 00205 { 00206 return std::less<typename common_type<typename add_pointer<_Tp>::type, 00207 typename add_pointer<_Up>::type 00208 >::type 00209 >{}(__p1.get(), __p2.get()); 00210 } 00211 00212 template<typename _Tp, typename _Up> 00213 bool 00214 operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 00215 { 00216 return __p2 < __p1; 00217 } 00218 00219 template<typename _Tp, typename _Up> 00220 bool 00221 operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 00222 { 00223 return !(__p2 < __p1); 00224 } 00225 00226 template<typename _Tp, typename _Up> 00227 bool 00228 operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 00229 { 00230 return !(__p1 < __p2); 00231 } 00232 } // namespace fundamentals_v2 00233 } // namespace experimental 00234 00235 template <typename _Tp> 00236 struct hash<experimental::observer_ptr<_Tp>> 00237 { 00238 using result_type = size_t; 00239 using argument_type = experimental::observer_ptr<_Tp>; 00240 00241 size_t 00242 operator()(const experimental::observer_ptr<_Tp>& __t) const 00243 noexcept(noexcept(hash<typename add_pointer<_Tp>::type> {}(__t.get()))) 00244 { 00245 return hash<typename add_pointer<_Tp>::type> {}(__t.get()); 00246 } 00247 }; 00248 00249 00250 _GLIBCXX_END_NAMESPACE_VERSION 00251 } // namespace std 00252 00253 #endif // __cplusplus <= 201103L 00254 00255 #endif // _GLIBCXX_EXPERIMENTAL_MEMORY