libstdc++
experimental/memory
Go to the documentation of this file.
1 // <experimental/memory> -*- C++ -*-
2 
3 // Copyright (C) 2015-2022 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 #pragma GCC system_header
38 
39 #if __cplusplus >= 201402L
40 
41 #include <memory>
42 #include <type_traits>
43 #include <experimental/bits/shared_ptr.h>
44 #include <bits/functional_hash.h>
45 
46 namespace std _GLIBCXX_VISIBILITY(default)
47 {
48 _GLIBCXX_BEGIN_NAMESPACE_VERSION
49 
50 namespace experimental
51 {
52 inline 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 
235 template <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