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