1// <experimental/memory> -*- C++ -*- 2 3// Copyright (C) 2015-2018 Free Software Foundation, Inc. 4// 5// This file is part of the GNU ISO C++ Library. This library is free 6// software; you can redistribute it and/or modify it under the 7// terms of the GNU General Public License as published by the 8// Free Software Foundation; either version 3, or (at your option) 9// any later version. 10 11// This library is distributed in the hope that it will be useful, 12// but WITHOUT ANY WARRANTY; without even the implied warranty of 13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14// GNU General Public License for more details. 15 16// Under Section 7 of GPL version 3, you are granted additional 17// permissions described in the GCC Runtime Library Exception, version 18// 3.1, as published by the Free Software Foundation. 19 20// You should have received a copy of the GNU General Public License and 21// a copy of the GCC Runtime Library Exception along with this program; 22// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23// <http://www.gnu.org/licenses/>. 24 25/** @file experimental/memory 26 * This is a TS C++ Library header. 27 */ 28 29// 30// N4336 Working Draft, C++ Extensions for Library Fundamentals, Version 2 31// 32 33#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY 34#define _GLIBCXX_EXPERIMENTAL_MEMORY 1 35 36#pragma GCC system_header 37 38#if __cplusplus >= 201402L 39 40#include <memory> 41#include <type_traits> 42#include <utility> 43#include <experimental/bits/shared_ptr.h> 44#include <bits/functional_hash.h> 45 46namespace std _GLIBCXX_VISIBILITY(default) 47{ 48_GLIBCXX_BEGIN_NAMESPACE_VERSION 49 50namespace experimental 51{ 52inline namespace fundamentals_v2 53{ 54#define __cpp_lib_experimental_observer_ptr 201411 55 56 template <typename _Tp> 57 class observer_ptr 58 { 59 public: 60 // publish our template parameter and variations thereof 61 using element_type = _Tp; 62 using __pointer = add_pointer_t<_Tp>; // exposition-only 63 using __reference = add_lvalue_reference_t<_Tp>; // exposition-only 64 65 // 3.2.2, observer_ptr constructors 66 // default c’tor 67 constexpr observer_ptr() noexcept 68 : __t() 69 { } 70 71 // pointer-accepting c’tors 72 constexpr observer_ptr(nullptr_t) noexcept 73 : __t() 74 { } 75 76 constexpr explicit observer_ptr(__pointer __p) noexcept 77 : __t(__p) 78 { } 79 80 // copying c’tors (in addition to compiler-generated copy c’tor) 81 template <typename _Up, 82 typename = typename enable_if< 83 is_convertible<typename add_pointer<_Up>::type, __pointer 84 >::value 85 >::type> 86 constexpr observer_ptr(observer_ptr<_Up> __p) noexcept 87 : __t(__p.get()) 88 { 89 } 90 91 // 3.2.3, observer_ptr observers 92 constexpr __pointer 93 get() const noexcept 94 { 95 return __t; 96 } 97 98 constexpr __reference 99 operator*() const 100 { 101 return *get(); 102 } 103 104 constexpr __pointer 105 operator->() const noexcept 106 { 107 return get(); 108 } 109 110 constexpr explicit operator bool() const noexcept 111 { 112 return get() != nullptr; 113 } 114 115 // 3.2.4, observer_ptr conversions 116 constexpr explicit operator __pointer() const noexcept 117 { 118 return get(); 119 } 120 121 // 3.2.5, observer_ptr modifiers 122 constexpr __pointer 123 release() noexcept 124 { 125 __pointer __tmp = get(); 126 reset(); 127 return __tmp; 128 } 129 130 constexpr void 131 reset(__pointer __p = nullptr) noexcept 132 { 133 __t = __p; 134 } 135 136 constexpr void 137 swap(observer_ptr& __p) noexcept 138 { 139 std::swap(__t, __p.__t); 140 } 141 142 private: 143 __pointer __t; 144 }; // observer_ptr<> 145 146 template<typename _Tp> 147 void 148 swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept 149 { 150 __p1.swap(__p2); 151 } 152 153 template<typename _Tp> 154 observer_ptr<_Tp> 155 make_observer(_Tp* __p) noexcept 156 { 157 return observer_ptr<_Tp>(__p); 158 } 159 160 template<typename _Tp, typename _Up> 161 bool 162 operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 163 { 164 return __p1.get() == __p2.get(); 165 } 166 167 template<typename _Tp, typename _Up> 168 bool 169 operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 170 { 171 return !(__p1 == __p2); 172 } 173 174 template<typename _Tp> 175 bool 176 operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept 177 { 178 return !__p; 179 } 180 181 template<typename _Tp> 182 bool 183 operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept 184 { 185 return !__p; 186 } 187 188 template<typename _Tp> 189 bool 190 operator!=(observer_ptr<_Tp> __p, nullptr_t) noexcept 191 { 192 return bool(__p); 193 } 194 195 template<typename _Tp> 196 bool 197 operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept 198 { 199 return bool(__p); 200 } 201 202 template<typename _Tp, typename _Up> 203 bool 204 operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 205 { 206 return std::less<typename common_type<typename add_pointer<_Tp>::type, 207 typename add_pointer<_Up>::type 208 >::type 209 >{}(__p1.get(), __p2.get()); 210 } 211 212 template<typename _Tp, typename _Up> 213 bool 214 operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 215 { 216 return __p2 < __p1; 217 } 218 219 template<typename _Tp, typename _Up> 220 bool 221 operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 222 { 223 return !(__p2 < __p1); 224 } 225 226 template<typename _Tp, typename _Up> 227 bool 228 operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) 229 { 230 return !(__p1 < __p2); 231 } 232} // namespace fundamentals_v2 233} // namespace experimental 234 235template <typename _Tp> 236 struct hash<experimental::observer_ptr<_Tp>> 237 { 238 using result_type = size_t; 239 using argument_type = experimental::observer_ptr<_Tp>; 240 241 size_t 242 operator()(const experimental::observer_ptr<_Tp>& __t) const 243 noexcept(noexcept(hash<typename add_pointer<_Tp>::type> {}(__t.get()))) 244 { 245 return hash<typename add_pointer<_Tp>::type> {}(__t.get()); 246 } 247 }; 248 249 250_GLIBCXX_END_NAMESPACE_VERSION 251} // namespace std 252 253#endif // __cplusplus <= 201103L 254 255#endif // _GLIBCXX_EXPERIMENTAL_MEMORY 256