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