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