libstdc++
experimental/memory
Go to the documentation of this file.
1// <experimental/memory> -*- C++ -*-
2
3// Copyright (C) 2015-2025 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 * @ingroup libfund-ts
28 */
29
30//
31// N4336 Working Draft, C++ Extensions for Library Fundamentals, Version 2
32//
33
34#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY
35#define _GLIBCXX_EXPERIMENTAL_MEMORY 1
36
37#ifdef _GLIBCXX_SYSHDR
38#pragma GCC system_header
39#endif
40
41#include <bits/requires_hosted.h> // experimental is currently omitted
42
43#if __cplusplus >= 201402L
44
45#include <memory>
46#include <type_traits>
47#include <experimental/bits/shared_ptr.h>
48#include <bits/functional_hash.h>
49
50namespace std _GLIBCXX_VISIBILITY(default)
51{
52_GLIBCXX_BEGIN_NAMESPACE_VERSION
53
54namespace experimental
55{
56inline namespace fundamentals_v2
57{
58#define __cpp_lib_experimental_observer_ptr 201411
59
60 template <typename _Tp>
61 class observer_ptr
62 {
63 public:
64 // publish our template parameter and variations thereof
65 using element_type = _Tp;
66 using __pointer = add_pointer_t<_Tp>; // exposition-only
67 using __reference = add_lvalue_reference_t<_Tp>; // exposition-only
68
69 // 3.2.2, observer_ptr constructors
70 // default c'tor
71 constexpr observer_ptr() noexcept
72 : __t()
73 { }
74
75 // pointer-accepting c'tors
76 constexpr observer_ptr(nullptr_t) noexcept
77 : __t()
78 { }
79
80 constexpr explicit observer_ptr(__pointer __p) noexcept
81 : __t(__p)
82 { }
83
84 // copying c'tors (in addition to compiler-generated copy c'tor)
85 template <typename _Up,
86 typename = typename enable_if<
87 is_convertible<typename add_pointer<_Up>::type, __pointer
88 >::value
89 >::type>
90 constexpr observer_ptr(observer_ptr<_Up> __p) noexcept
91 : __t(__p.get())
92 {
93 }
94
95 // 3.2.3, observer_ptr observers
96 constexpr __pointer
97 get() const noexcept
98 {
99 return __t;
100 }
101
102 constexpr __reference
103 operator*() const
104 {
105 return *get();
106 }
107
108 constexpr __pointer
109 operator->() const noexcept
110 {
111 return get();
112 }
113
114 constexpr explicit operator bool() const noexcept
115 {
116 return get() != nullptr;
117 }
118
119 // 3.2.4, observer_ptr conversions
120 constexpr explicit operator __pointer() const noexcept
121 {
122 return get();
123 }
124
125 // 3.2.5, observer_ptr modifiers
126 constexpr __pointer
127 release() noexcept
128 {
129 __pointer __tmp = get();
130 reset();
131 return __tmp;
132 }
133
134 constexpr void
135 reset(__pointer __p = nullptr) noexcept
136 {
137 __t = __p;
138 }
139
140 constexpr void
141 swap(observer_ptr& __p) noexcept
142 {
143 std::swap(__t, __p.__t);
144 }
145
146 private:
147 __pointer __t;
148 }; // observer_ptr<>
149
150 template<typename _Tp>
151 constexpr void
152 swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept
153 {
154 __p1.swap(__p2);
155 }
156
157 template<typename _Tp>
158 constexpr observer_ptr<_Tp>
159 make_observer(_Tp* __p) noexcept
160 {
161 return observer_ptr<_Tp>(__p);
162 }
163
164 template<typename _Tp, typename _Up>
165 constexpr bool
166 operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
167 {
168 return __p1.get() == __p2.get();
169 }
170
171 template<typename _Tp, typename _Up>
172 constexpr bool
173 operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
174 {
175 return !(__p1 == __p2);
176 }
177
178 template<typename _Tp>
179 constexpr bool
180 operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept
181 {
182 return !__p;
183 }
184
185 template<typename _Tp>
186 constexpr bool
187 operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept
188 {
189 return !__p;
190 }
191
192 template<typename _Tp>
193 bool
194 operator!=(observer_ptr<_Tp> __p, nullptr_t) noexcept
195 {
196 return bool(__p);
197 }
198
199 template<typename _Tp>
200 constexpr bool
201 operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept
202 {
203 return bool(__p);
204 }
205
206 template<typename _Tp, typename _Up>
207 constexpr bool
208 operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
209 {
210 return std::less<typename common_type<typename add_pointer<_Tp>::type,
211 typename add_pointer<_Up>::type
212 >::type
213 >{}(__p1.get(), __p2.get());
214 }
215
216 template<typename _Tp, typename _Up>
217 constexpr bool
218 operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
219 {
220 return __p2 < __p1;
221 }
222
223 template<typename _Tp, typename _Up>
224 constexpr bool
225 operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
226 {
227 return !(__p2 < __p1);
228 }
229
230 template<typename _Tp, typename _Up>
231 constexpr bool
232 operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
233 {
234 return !(__p1 < __p2);
235 }
236} // namespace fundamentals_v2
237} // namespace experimental
238
239template <typename _Tp>
240 struct hash<experimental::observer_ptr<_Tp>>
241 {
242 using result_type = size_t;
243 using argument_type = experimental::observer_ptr<_Tp>;
244
245 size_t
246 operator()(const experimental::observer_ptr<_Tp>& __t) const
247 noexcept(noexcept(hash<typename add_pointer<_Tp>::type> {}(__t.get())))
248 {
249 return hash<typename add_pointer<_Tp>::type> {}(__t.get());
250 }
251 };
252
253
254_GLIBCXX_END_NAMESPACE_VERSION
255} // namespace std
256
257#endif // __cplusplus <= 201103L
258
259#endif // _GLIBCXX_EXPERIMENTAL_MEMORY