15f757f3fSDimitry Andric// -*- C++ -*- 25f757f3fSDimitry Andric//===----------------------------------------------------------------------===// 35f757f3fSDimitry Andric// 45f757f3fSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 55f757f3fSDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 65f757f3fSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 75f757f3fSDimitry Andric// 85f757f3fSDimitry Andric//===----------------------------------------------------------------------===// 95f757f3fSDimitry Andric 105f757f3fSDimitry Andric#ifndef _LIBCPP_EXPERIMENTAL_MEMORY 115f757f3fSDimitry Andric#define _LIBCPP_EXPERIMENTAL_MEMORY 125f757f3fSDimitry Andric 135f757f3fSDimitry Andric/* 145f757f3fSDimitry Andric experimental/memory synopsis 155f757f3fSDimitry Andric 165f757f3fSDimitry Andricnamespace std::experimental::inline fundamentals_v2 { 175f757f3fSDimitry Andric 185f757f3fSDimitry Andrictemplate <class W> class observer_ptr { 195f757f3fSDimitry Andricpublic: 205f757f3fSDimitry Andric using element_type = W; 215f757f3fSDimitry Andric using pointer = add_pointer_t<W>; // exposition-only 225f757f3fSDimitry Andric using reference = add_lvalue_reference_t<W>; // exposition-only 235f757f3fSDimitry Andric 245f757f3fSDimitry Andric // default ctor 255f757f3fSDimitry Andric constexpr observer_ptr() noexcept; 265f757f3fSDimitry Andric 275f757f3fSDimitry Andric // pointer-accepting ctors 285f757f3fSDimitry Andric constexpr observer_ptr(nullptr_t) noexcept; 295f757f3fSDimitry Andric constexpr explicit observer_ptr(pointer) noexcept; 305f757f3fSDimitry Andric 315f757f3fSDimitry Andric // copying ctors (in addition to compiler-generated copy ctor) 325f757f3fSDimitry Andric template <class W2> constexpr observer_ptr(observer_ptr<W2>) noexcept; 335f757f3fSDimitry Andric 345f757f3fSDimitry Andric // observers 355f757f3fSDimitry Andric constexpr pointer get() const noexcept; 365f757f3fSDimitry Andric constexpr reference operator*() const; 375f757f3fSDimitry Andric constexpr pointer operator->() const noexcept; 385f757f3fSDimitry Andric constexpr explicit operator bool() const noexcept; 395f757f3fSDimitry Andric 405f757f3fSDimitry Andric // conversions 415f757f3fSDimitry Andric constexpr explicit operator pointer() const noexcept; 425f757f3fSDimitry Andric 435f757f3fSDimitry Andric // modifiers 445f757f3fSDimitry Andric constexpr pointer release() noexcept; 455f757f3fSDimitry Andric constexpr void reset(pointer = nullptr) noexcept; 465f757f3fSDimitry Andric constexpr void swap(observer_ptr&) noexcept; 475f757f3fSDimitry Andric}; 485f757f3fSDimitry Andric 495f757f3fSDimitry Andric} 505f757f3fSDimitry Andric*/ 515f757f3fSDimitry Andric 525f757f3fSDimitry Andric#include <__functional/hash.h> 535f757f3fSDimitry Andric#include <__functional/operations.h> 545f757f3fSDimitry Andric#include <__type_traits/add_lvalue_reference.h> 555f757f3fSDimitry Andric#include <__type_traits/add_pointer.h> 565f757f3fSDimitry Andric#include <__type_traits/common_type.h> 575f757f3fSDimitry Andric#include <__type_traits/enable_if.h> 585f757f3fSDimitry Andric#include <__type_traits/is_convertible.h> 595f757f3fSDimitry Andric#include <cstddef> 605f757f3fSDimitry Andric#include <experimental/__config> 615f757f3fSDimitry Andric 625f757f3fSDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 635f757f3fSDimitry Andric# pragma GCC system_header 645f757f3fSDimitry Andric#endif 655f757f3fSDimitry Andric 665f757f3fSDimitry Andric#ifdef _LIBCPP_ENABLE_EXPERIMENTAL 675f757f3fSDimitry Andric 685f757f3fSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 695f757f3fSDimitry Andric 705f757f3fSDimitry Andric# if _LIBCPP_STD_VER >= 17 715f757f3fSDimitry Andric 725f757f3fSDimitry Andrictemplate <class _Wp> 735f757f3fSDimitry Andricclass observer_ptr { 745f757f3fSDimitry Andricpublic: 755f757f3fSDimitry Andric using element_type = _Wp; 765f757f3fSDimitry Andric 775f757f3fSDimitry Andric // constructors 785f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr() noexcept : __ptr_(nullptr) {} 795f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(nullptr_t) noexcept : __ptr_(nullptr) {} 805f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit observer_ptr(element_type* __p) noexcept : __ptr_(__p) {} 815f757f3fSDimitry Andric 82*0fca6ea1SDimitry Andric template <class _W2, __enable_if_t<is_convertible<_W2*, _Wp*>::value, int> = 0> 835f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(observer_ptr<_W2> __other) noexcept : __ptr_(__other.get()) {} 845f757f3fSDimitry Andric 855f757f3fSDimitry Andric // observers 865f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr element_type* get() const noexcept { return __ptr_; } 875f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr add_lvalue_reference_t<_Wp> operator*() const { return *__ptr_; } 885f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr element_type* operator->() const noexcept { return __ptr_; } 895f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __ptr_ != nullptr; } 905f757f3fSDimitry Andric 915f757f3fSDimitry Andric // conversions 925f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit operator element_type*() const noexcept { return __ptr_; } 935f757f3fSDimitry Andric 945f757f3fSDimitry Andric // modifiers 955f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void reset(element_type* __p = nullptr) noexcept { __ptr_ = __p; } 965f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr& __other) noexcept { 975f757f3fSDimitry Andric observer_ptr __tmp = __other; 985f757f3fSDimitry Andric __other = *this; 995f757f3fSDimitry Andric *this = __tmp; 1005f757f3fSDimitry Andric } 1015f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr element_type* release() noexcept { 1025f757f3fSDimitry Andric observer_ptr __p; 1035f757f3fSDimitry Andric __p.swap(*this); 1045f757f3fSDimitry Andric return __p.get(); 1055f757f3fSDimitry Andric } 1065f757f3fSDimitry Andric 1075f757f3fSDimitry Andricprivate: 1085f757f3fSDimitry Andric element_type* __ptr_; 1095f757f3fSDimitry Andric}; 1105f757f3fSDimitry Andric 1115f757f3fSDimitry Andric// specializations 1125f757f3fSDimitry Andric 1135f757f3fSDimitry Andrictemplate <class _Wp> 1145f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr<_Wp>& __a, observer_ptr<_Wp>& __b) noexcept { 1155f757f3fSDimitry Andric __a.swap(__b); 1165f757f3fSDimitry Andric} 1175f757f3fSDimitry Andric 1185f757f3fSDimitry Andrictemplate <class _Wp> 1195f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI observer_ptr<_Wp> make_observer(_Wp* __ptr) noexcept { 1205f757f3fSDimitry Andric return observer_ptr<_Wp>{__ptr}; 1215f757f3fSDimitry Andric} 1225f757f3fSDimitry Andric 1235f757f3fSDimitry Andrictemplate <class _W1, class _W2> 1245f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1255f757f3fSDimitry Andric return __a.get() == __b.get(); 1265f757f3fSDimitry Andric} 1275f757f3fSDimitry Andric 1285f757f3fSDimitry Andrictemplate <class _W1, class _W2> 1295f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1305f757f3fSDimitry Andric return !(__a == __b); 1315f757f3fSDimitry Andric} 1325f757f3fSDimitry Andric 1335f757f3fSDimitry Andrictemplate <class _Wp> 1345f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_Wp> __p, nullptr_t) { 1355f757f3fSDimitry Andric return !__p; 1365f757f3fSDimitry Andric} 1375f757f3fSDimitry Andric 1385f757f3fSDimitry Andrictemplate <class _Wp> 1395f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, observer_ptr<_Wp> __p) { 1405f757f3fSDimitry Andric return !__p; 1415f757f3fSDimitry Andric} 1425f757f3fSDimitry Andric 1435f757f3fSDimitry Andrictemplate <class _Wp> 1445f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_Wp> __p, nullptr_t) { 1455f757f3fSDimitry Andric return (bool)__p; 1465f757f3fSDimitry Andric} 1475f757f3fSDimitry Andric 1485f757f3fSDimitry Andrictemplate <class _Wp> 1495f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, observer_ptr<_Wp> __p) { 1505f757f3fSDimitry Andric return (bool)__p; 1515f757f3fSDimitry Andric} 1525f757f3fSDimitry Andric 1535f757f3fSDimitry Andrictemplate <class _W1, class _W2> 1545f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator<(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1555f757f3fSDimitry Andric return std::less<typename std::common_type<_W1*, _W2*>::type>()(__a.get(), __b.get()); 1565f757f3fSDimitry Andric} 1575f757f3fSDimitry Andric 1585f757f3fSDimitry Andrictemplate <class _W1, class _W2> 1595f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator>(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1605f757f3fSDimitry Andric return __b < __a; 1615f757f3fSDimitry Andric} 1625f757f3fSDimitry Andric 1635f757f3fSDimitry Andrictemplate <class _W1, class _W2> 1645f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator<=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1655f757f3fSDimitry Andric return !(__a > __b); 1665f757f3fSDimitry Andric} 1675f757f3fSDimitry Andric 1685f757f3fSDimitry Andrictemplate <class _W1, class _W2> 1695f757f3fSDimitry Andric_LIBCPP_HIDE_FROM_ABI bool operator>=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1705f757f3fSDimitry Andric return !(__a < __b); 1715f757f3fSDimitry Andric} 1725f757f3fSDimitry Andric 1735f757f3fSDimitry Andric# endif // _LIBCPP_STD_VER >= 17 1745f757f3fSDimitry Andric 1755f757f3fSDimitry Andric_LIBCPP_END_NAMESPACE_LFTS_V2 1765f757f3fSDimitry Andric 1775f757f3fSDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1785f757f3fSDimitry Andric 1795f757f3fSDimitry Andric// hash 1805f757f3fSDimitry Andric 1815f757f3fSDimitry Andric# if _LIBCPP_STD_VER >= 17 1825f757f3fSDimitry Andrictemplate <class _Tp> 1835f757f3fSDimitry Andricstruct hash<experimental::observer_ptr<_Tp>> { 1845f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::observer_ptr<_Tp>& __ptr) const noexcept { 1855f757f3fSDimitry Andric return hash<_Tp*>()(__ptr.get()); 1865f757f3fSDimitry Andric } 1875f757f3fSDimitry Andric}; 1885f757f3fSDimitry Andric# endif // _LIBCPP_STD_VER >= 17 1895f757f3fSDimitry Andric 1905f757f3fSDimitry Andric_LIBCPP_END_NAMESPACE_STD 1915f757f3fSDimitry Andric 1925f757f3fSDimitry Andric#endif // _LIBCPP_ENABLE_EXPERIMENTAL 1935f757f3fSDimitry Andric 194*0fca6ea1SDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 195*0fca6ea1SDimitry Andric# include <limits> 196*0fca6ea1SDimitry Andric#endif 197*0fca6ea1SDimitry Andric 1985f757f3fSDimitry Andric#endif /* _LIBCPP_EXPERIMENTAL_MEMORY */ 199