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