xref: /llvm-project/libcxx/include/__cxx03/experimental/memory (revision ce7771902dc50d900de639d499a60486b83f70e0)
1e78f53d1SNikolas Klauser// -*- C++ -*-
2e78f53d1SNikolas Klauser//===----------------------------------------------------------------------===//
3e78f53d1SNikolas Klauser//
4e78f53d1SNikolas Klauser// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5e78f53d1SNikolas Klauser// See https://llvm.org/LICENSE.txt for license information.
6e78f53d1SNikolas Klauser// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7e78f53d1SNikolas Klauser//
8e78f53d1SNikolas Klauser//===----------------------------------------------------------------------===//
9e78f53d1SNikolas Klauser
10*ce777190SNikolas Klauser#ifndef _LIBCPP___CXX03_EXPERIMENTAL_MEMORY
11*ce777190SNikolas Klauser#define _LIBCPP___CXX03_EXPERIMENTAL_MEMORY
12e78f53d1SNikolas Klauser
13e78f53d1SNikolas Klauser/*
14e78f53d1SNikolas Klauser    experimental/memory synopsis
15e78f53d1SNikolas Klauser
16e78f53d1SNikolas Klausernamespace std::experimental::inline fundamentals_v2  {
17e78f53d1SNikolas Klauser
18e78f53d1SNikolas Klausertemplate <class W> class observer_ptr {
19e78f53d1SNikolas Klauserpublic:
20e78f53d1SNikolas Klauser    using element_type = W;
21e78f53d1SNikolas Klauser    using pointer = add_pointer_t<W>; // exposition-only
22e78f53d1SNikolas Klauser    using reference = add_lvalue_reference_t<W>; // exposition-only
23e78f53d1SNikolas Klauser
24e78f53d1SNikolas Klauser    // default ctor
25e78f53d1SNikolas Klauser    constexpr observer_ptr() noexcept;
26e78f53d1SNikolas Klauser
27e78f53d1SNikolas Klauser    // pointer-accepting ctors
28e78f53d1SNikolas Klauser    constexpr observer_ptr(nullptr_t) noexcept;
29e78f53d1SNikolas Klauser    constexpr explicit observer_ptr(pointer) noexcept;
30e78f53d1SNikolas Klauser
31e78f53d1SNikolas Klauser    // copying ctors (in addition to compiler-generated copy ctor)
32e78f53d1SNikolas Klauser    template <class W2> constexpr observer_ptr(observer_ptr<W2>) noexcept;
33e78f53d1SNikolas Klauser
34e78f53d1SNikolas Klauser    // observers
35e78f53d1SNikolas Klauser    constexpr pointer get() const noexcept;
36e78f53d1SNikolas Klauser    constexpr reference operator*() const;
37e78f53d1SNikolas Klauser    constexpr pointer operator->() const noexcept;
38e78f53d1SNikolas Klauser    constexpr explicit operator bool() const noexcept;
39e78f53d1SNikolas Klauser
40e78f53d1SNikolas Klauser    // conversions
41e78f53d1SNikolas Klauser    constexpr explicit operator pointer() const noexcept;
42e78f53d1SNikolas Klauser
43e78f53d1SNikolas Klauser    // modifiers
44e78f53d1SNikolas Klauser    constexpr pointer release() noexcept;
45e78f53d1SNikolas Klauser    constexpr void reset(pointer = nullptr) noexcept;
46e78f53d1SNikolas Klauser    constexpr void swap(observer_ptr&) noexcept;
47e78f53d1SNikolas Klauser};
48e78f53d1SNikolas Klauser
49e78f53d1SNikolas Klauser}
50e78f53d1SNikolas Klauser*/
51e78f53d1SNikolas Klauser
5273fbae83SNikolas Klauser#include <__cxx03/__functional/hash.h>
5373fbae83SNikolas Klauser#include <__cxx03/__functional/operations.h>
5473fbae83SNikolas Klauser#include <__cxx03/__type_traits/add_lvalue_reference.h>
5573fbae83SNikolas Klauser#include <__cxx03/__type_traits/add_pointer.h>
5673fbae83SNikolas Klauser#include <__cxx03/__type_traits/common_type.h>
5773fbae83SNikolas Klauser#include <__cxx03/__type_traits/enable_if.h>
5873fbae83SNikolas Klauser#include <__cxx03/__type_traits/is_convertible.h>
5973fbae83SNikolas Klauser#include <__cxx03/cstddef>
6073fbae83SNikolas Klauser#include <__cxx03/experimental/__config>
61e78f53d1SNikolas Klauser
62e78f53d1SNikolas Klauser#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
63e78f53d1SNikolas Klauser#  pragma GCC system_header
64e78f53d1SNikolas Klauser#endif
65e78f53d1SNikolas Klauser
66e78f53d1SNikolas Klauser#ifdef _LIBCPP_ENABLE_EXPERIMENTAL
67e78f53d1SNikolas Klauser
68e78f53d1SNikolas Klauser_LIBCPP_BEGIN_NAMESPACE_LFTS_V2
69e78f53d1SNikolas Klauser
70e78f53d1SNikolas Klauser#  if _LIBCPP_STD_VER >= 17
71e78f53d1SNikolas Klauser
72e78f53d1SNikolas Klausertemplate <class _Wp>
73e78f53d1SNikolas Klauserclass observer_ptr {
74e78f53d1SNikolas Klauserpublic:
75e78f53d1SNikolas Klauser  using element_type = _Wp;
76e78f53d1SNikolas Klauser
77e78f53d1SNikolas Klauser  // constructors
78e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr() noexcept : __ptr_(nullptr) {}
79e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(nullptr_t) noexcept : __ptr_(nullptr) {}
80e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr explicit observer_ptr(element_type* __p) noexcept : __ptr_(__p) {}
81e78f53d1SNikolas Klauser
82e78f53d1SNikolas Klauser  template <class _W2, __enable_if_t<is_convertible<_W2*, _Wp*>::value, int> = 0>
83e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(observer_ptr<_W2> __other) noexcept : __ptr_(__other.get()) {}
84e78f53d1SNikolas Klauser
85e78f53d1SNikolas Klauser  // observers
86e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr element_type* get() const noexcept { return __ptr_; }
87e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr add_lvalue_reference_t<_Wp> operator*() const { return *__ptr_; }
88e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr element_type* operator->() const noexcept { return __ptr_; }
89e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __ptr_ != nullptr; }
90e78f53d1SNikolas Klauser
91e78f53d1SNikolas Klauser  // conversions
92e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr explicit operator element_type*() const noexcept { return __ptr_; }
93e78f53d1SNikolas Klauser
94e78f53d1SNikolas Klauser  // modifiers
95e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr void reset(element_type* __p = nullptr) noexcept { __ptr_ = __p; }
96e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr& __other) noexcept {
97e78f53d1SNikolas Klauser    observer_ptr __tmp = __other;
98e78f53d1SNikolas Klauser    __other            = *this;
99e78f53d1SNikolas Klauser    *this              = __tmp;
100e78f53d1SNikolas Klauser  }
101e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI constexpr element_type* release() noexcept {
102e78f53d1SNikolas Klauser    observer_ptr __p;
103e78f53d1SNikolas Klauser    __p.swap(*this);
104e78f53d1SNikolas Klauser    return __p.get();
105e78f53d1SNikolas Klauser  }
106e78f53d1SNikolas Klauser
107e78f53d1SNikolas Klauserprivate:
108e78f53d1SNikolas Klauser  element_type* __ptr_;
109e78f53d1SNikolas Klauser};
110e78f53d1SNikolas Klauser
111e78f53d1SNikolas Klauser// specializations
112e78f53d1SNikolas Klauser
113e78f53d1SNikolas Klausertemplate <class _Wp>
114e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr<_Wp>& __a, observer_ptr<_Wp>& __b) noexcept {
115e78f53d1SNikolas Klauser  __a.swap(__b);
116e78f53d1SNikolas Klauser}
117e78f53d1SNikolas Klauser
118e78f53d1SNikolas Klausertemplate <class _Wp>
119e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI observer_ptr<_Wp> make_observer(_Wp* __ptr) noexcept {
120e78f53d1SNikolas Klauser  return observer_ptr<_Wp>{__ptr};
121e78f53d1SNikolas Klauser}
122e78f53d1SNikolas Klauser
123e78f53d1SNikolas Klausertemplate <class _W1, class _W2>
124e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
125e78f53d1SNikolas Klauser  return __a.get() == __b.get();
126e78f53d1SNikolas Klauser}
127e78f53d1SNikolas Klauser
128e78f53d1SNikolas Klausertemplate <class _W1, class _W2>
129e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
130e78f53d1SNikolas Klauser  return !(__a == __b);
131e78f53d1SNikolas Klauser}
132e78f53d1SNikolas Klauser
133e78f53d1SNikolas Klausertemplate <class _Wp>
134e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_Wp> __p, nullptr_t) {
135e78f53d1SNikolas Klauser  return !__p;
136e78f53d1SNikolas Klauser}
137e78f53d1SNikolas Klauser
138e78f53d1SNikolas Klausertemplate <class _Wp>
139e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, observer_ptr<_Wp> __p) {
140e78f53d1SNikolas Klauser  return !__p;
141e78f53d1SNikolas Klauser}
142e78f53d1SNikolas Klauser
143e78f53d1SNikolas Klausertemplate <class _Wp>
144e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_Wp> __p, nullptr_t) {
145e78f53d1SNikolas Klauser  return (bool)__p;
146e78f53d1SNikolas Klauser}
147e78f53d1SNikolas Klauser
148e78f53d1SNikolas Klausertemplate <class _Wp>
149e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, observer_ptr<_Wp> __p) {
150e78f53d1SNikolas Klauser  return (bool)__p;
151e78f53d1SNikolas Klauser}
152e78f53d1SNikolas Klauser
153e78f53d1SNikolas Klausertemplate <class _W1, class _W2>
154e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator<(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
155e78f53d1SNikolas Klauser  return std::less<typename std::common_type<_W1*, _W2*>::type>()(__a.get(), __b.get());
156e78f53d1SNikolas Klauser}
157e78f53d1SNikolas Klauser
158e78f53d1SNikolas Klausertemplate <class _W1, class _W2>
159e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator>(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
160e78f53d1SNikolas Klauser  return __b < __a;
161e78f53d1SNikolas Klauser}
162e78f53d1SNikolas Klauser
163e78f53d1SNikolas Klausertemplate <class _W1, class _W2>
164e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator<=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
165e78f53d1SNikolas Klauser  return !(__a > __b);
166e78f53d1SNikolas Klauser}
167e78f53d1SNikolas Klauser
168e78f53d1SNikolas Klausertemplate <class _W1, class _W2>
169e78f53d1SNikolas Klauser_LIBCPP_HIDE_FROM_ABI bool operator>=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) {
170e78f53d1SNikolas Klauser  return !(__a < __b);
171e78f53d1SNikolas Klauser}
172e78f53d1SNikolas Klauser
173e78f53d1SNikolas Klauser#  endif // _LIBCPP_STD_VER >= 17
174e78f53d1SNikolas Klauser
175e78f53d1SNikolas Klauser_LIBCPP_END_NAMESPACE_LFTS_V2
176e78f53d1SNikolas Klauser
177e78f53d1SNikolas Klauser_LIBCPP_BEGIN_NAMESPACE_STD
178e78f53d1SNikolas Klauser
179e78f53d1SNikolas Klauser// hash
180e78f53d1SNikolas Klauser
181e78f53d1SNikolas Klauser#  if _LIBCPP_STD_VER >= 17
182e78f53d1SNikolas Klausertemplate <class _Tp>
183e78f53d1SNikolas Klauserstruct hash<experimental::observer_ptr<_Tp>> {
184e78f53d1SNikolas Klauser  _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::observer_ptr<_Tp>& __ptr) const noexcept {
185e78f53d1SNikolas Klauser    return hash<_Tp*>()(__ptr.get());
186e78f53d1SNikolas Klauser  }
187e78f53d1SNikolas Klauser};
188e78f53d1SNikolas Klauser#  endif // _LIBCPP_STD_VER >= 17
189e78f53d1SNikolas Klauser
190e78f53d1SNikolas Klauser_LIBCPP_END_NAMESPACE_STD
191e78f53d1SNikolas Klauser
192e78f53d1SNikolas Klauser#endif // _LIBCPP_ENABLE_EXPERIMENTAL
193e78f53d1SNikolas Klauser
194e78f53d1SNikolas Klauser#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
19573fbae83SNikolas Klauser#  include <__cxx03/limits>
196e78f53d1SNikolas Klauser#endif
197e78f53d1SNikolas Klauser
198*ce777190SNikolas Klauser#endif /* _LIBCPP___CXX03_EXPERIMENTAL_MEMORY */
199