17a62bee6SZoe Carver// -*- C++ -*- 27a62bee6SZoe Carver//===----------------------------------------------------------------------===// 37a62bee6SZoe Carver// 47a62bee6SZoe Carver// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 57a62bee6SZoe Carver// See https://llvm.org/LICENSE.txt for license information. 67a62bee6SZoe Carver// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 77a62bee6SZoe Carver// 87a62bee6SZoe Carver//===----------------------------------------------------------------------===// 97a62bee6SZoe Carver 107a62bee6SZoe Carver#ifndef _LIBCPP_EXPERIMENTAL_MEMORY 117a62bee6SZoe Carver#define _LIBCPP_EXPERIMENTAL_MEMORY 127a62bee6SZoe Carver 137a62bee6SZoe Carver/* 147a62bee6SZoe Carver experimental/memory synopsis 157a62bee6SZoe Carver 167a62bee6SZoe Carvernamespace std::experimental::inline fundamentals_v2 { 177a62bee6SZoe Carver 187a62bee6SZoe Carvertemplate <class W> class observer_ptr { 197a62bee6SZoe Carverpublic: 207a62bee6SZoe Carver using element_type = W; 217a62bee6SZoe Carver using pointer = add_pointer_t<W>; // exposition-only 227a62bee6SZoe Carver using reference = add_lvalue_reference_t<W>; // exposition-only 237a62bee6SZoe Carver 247a62bee6SZoe Carver // default ctor 257a62bee6SZoe Carver constexpr observer_ptr() noexcept; 267a62bee6SZoe Carver 277a62bee6SZoe Carver // pointer-accepting ctors 287a62bee6SZoe Carver constexpr observer_ptr(nullptr_t) noexcept; 297a62bee6SZoe Carver constexpr explicit observer_ptr(pointer) noexcept; 307a62bee6SZoe Carver 317a62bee6SZoe Carver // copying ctors (in addition to compiler-generated copy ctor) 327a62bee6SZoe Carver template <class W2> constexpr observer_ptr(observer_ptr<W2>) noexcept; 337a62bee6SZoe Carver 347a62bee6SZoe Carver // observers 357a62bee6SZoe Carver constexpr pointer get() const noexcept; 367a62bee6SZoe Carver constexpr reference operator*() const; 377a62bee6SZoe Carver constexpr pointer operator->() const noexcept; 387a62bee6SZoe Carver constexpr explicit operator bool() const noexcept; 397a62bee6SZoe Carver 407a62bee6SZoe Carver // conversions 417a62bee6SZoe Carver constexpr explicit operator pointer() const noexcept; 427a62bee6SZoe Carver 437a62bee6SZoe Carver // modifiers 447a62bee6SZoe Carver constexpr pointer release() noexcept; 457a62bee6SZoe Carver constexpr void reset(pointer = nullptr) noexcept; 467a62bee6SZoe Carver constexpr void swap(observer_ptr&) noexcept; 477a62bee6SZoe Carver}; 487a62bee6SZoe Carver 497a62bee6SZoe Carver} 507a62bee6SZoe Carver*/ 517a62bee6SZoe Carver 52*b9a2658aSNikolas Klauser#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) 53*b9a2658aSNikolas Klauser# include <__cxx03/experimental/memory> 54*b9a2658aSNikolas Klauser#else 55118f120eSLouis Dionne# include <__config> 56e99c4906SNikolas Klauser# include <__cstddef/nullptr_t.h> 57e99c4906SNikolas Klauser# include <__cstddef/size_t.h> 587a62bee6SZoe Carver# include <__functional/hash.h> 597a62bee6SZoe Carver# include <__functional/operations.h> 607a62bee6SZoe Carver# include <__type_traits/add_lvalue_reference.h> 617a62bee6SZoe Carver# include <__type_traits/add_pointer.h> 627a62bee6SZoe Carver# include <__type_traits/common_type.h> 637a62bee6SZoe Carver# include <__type_traits/enable_if.h> 647a62bee6SZoe Carver# include <__type_traits/is_convertible.h> 65e99c4906SNikolas Klauser# include <version> 667a62bee6SZoe Carver 677a62bee6SZoe Carver# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 687a62bee6SZoe Carver# pragma GCC system_header 697a62bee6SZoe Carver# endif 707a62bee6SZoe Carver 717a62bee6SZoe Carver# ifdef _LIBCPP_ENABLE_EXPERIMENTAL 727a62bee6SZoe Carver 737a62bee6SZoe Carver_LIBCPP_BEGIN_NAMESPACE_LFTS_V2 747a62bee6SZoe Carver 757a62bee6SZoe Carver# if _LIBCPP_STD_VER >= 17 767a62bee6SZoe Carver 777a62bee6SZoe Carvertemplate <class _Wp> 787a62bee6SZoe Carverclass observer_ptr { 797a62bee6SZoe Carverpublic: 807a62bee6SZoe Carver using element_type = _Wp; 817a62bee6SZoe Carver 827a62bee6SZoe Carver // constructors 837a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr() noexcept : __ptr_(nullptr) {} 847a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(nullptr_t) noexcept : __ptr_(nullptr) {} 857a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr explicit observer_ptr(element_type* __p) noexcept : __ptr_(__p) {} 867a62bee6SZoe Carver 8776a24727SNikolas Klauser template <class _W2, __enable_if_t<is_convertible<_W2*, _Wp*>::value, int> = 0> 887a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr observer_ptr(observer_ptr<_W2> __other) noexcept : __ptr_(__other.get()) {} 897a62bee6SZoe Carver 907a62bee6SZoe Carver // observers 917a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr element_type* get() const noexcept { return __ptr_; } 927a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr add_lvalue_reference_t<_Wp> operator*() const { return *__ptr_; } 937a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr element_type* operator->() const noexcept { return __ptr_; } 947a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const noexcept { return __ptr_ != nullptr; } 957a62bee6SZoe Carver 967a62bee6SZoe Carver // conversions 977a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr explicit operator element_type*() const noexcept { return __ptr_; } 987a62bee6SZoe Carver 997a62bee6SZoe Carver // modifiers 1007a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr void reset(element_type* __p = nullptr) noexcept { __ptr_ = __p; } 1017a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr& __other) noexcept { 1027a62bee6SZoe Carver observer_ptr __tmp = __other; 1037a62bee6SZoe Carver __other = *this; 1047a62bee6SZoe Carver *this = __tmp; 1057a62bee6SZoe Carver } 1067a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI constexpr element_type* release() noexcept { 1077a62bee6SZoe Carver observer_ptr __p; 1087a62bee6SZoe Carver __p.swap(*this); 1097a62bee6SZoe Carver return __p.get(); 1107a62bee6SZoe Carver } 1117a62bee6SZoe Carver 1127a62bee6SZoe Carverprivate: 1137a62bee6SZoe Carver element_type* __ptr_; 1147a62bee6SZoe Carver}; 1157a62bee6SZoe Carver 1167a62bee6SZoe Carver// specializations 1177a62bee6SZoe Carver 1187a62bee6SZoe Carvertemplate <class _Wp> 1197a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI constexpr void swap(observer_ptr<_Wp>& __a, observer_ptr<_Wp>& __b) noexcept { 1207a62bee6SZoe Carver __a.swap(__b); 1217a62bee6SZoe Carver} 1227a62bee6SZoe Carver 1237a62bee6SZoe Carvertemplate <class _Wp> 1247a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI observer_ptr<_Wp> make_observer(_Wp* __ptr) noexcept { 1257a62bee6SZoe Carver return observer_ptr<_Wp>{__ptr}; 1267a62bee6SZoe Carver} 1277a62bee6SZoe Carver 1287a62bee6SZoe Carvertemplate <class _W1, class _W2> 1297a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1307a62bee6SZoe Carver return __a.get() == __b.get(); 1317a62bee6SZoe Carver} 1327a62bee6SZoe Carver 1337a62bee6SZoe Carvertemplate <class _W1, class _W2> 1347a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1357a62bee6SZoe Carver return !(__a == __b); 1367a62bee6SZoe Carver} 1377a62bee6SZoe Carver 1387a62bee6SZoe Carvertemplate <class _Wp> 1397a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator==(observer_ptr<_Wp> __p, nullptr_t) { 1407a62bee6SZoe Carver return !__p; 1417a62bee6SZoe Carver} 1427a62bee6SZoe Carver 1437a62bee6SZoe Carvertemplate <class _Wp> 1447a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator==(nullptr_t, observer_ptr<_Wp> __p) { 1457a62bee6SZoe Carver return !__p; 1467a62bee6SZoe Carver} 1477a62bee6SZoe Carver 1487a62bee6SZoe Carvertemplate <class _Wp> 1497a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator!=(observer_ptr<_Wp> __p, nullptr_t) { 1507a62bee6SZoe Carver return (bool)__p; 1517a62bee6SZoe Carver} 1527a62bee6SZoe Carver 1537a62bee6SZoe Carvertemplate <class _Wp> 1547a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator!=(nullptr_t, observer_ptr<_Wp> __p) { 1557a62bee6SZoe Carver return (bool)__p; 1567a62bee6SZoe Carver} 1577a62bee6SZoe Carver 1587a62bee6SZoe Carvertemplate <class _W1, class _W2> 1597a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator<(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1607a62bee6SZoe Carver return std::less<typename std::common_type<_W1*, _W2*>::type>()(__a.get(), __b.get()); 1617a62bee6SZoe Carver} 1627a62bee6SZoe Carver 1637a62bee6SZoe Carvertemplate <class _W1, class _W2> 1647a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator>(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1657a62bee6SZoe Carver return __b < __a; 1667a62bee6SZoe Carver} 1677a62bee6SZoe Carver 1687a62bee6SZoe Carvertemplate <class _W1, class _W2> 1697a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator<=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1707a62bee6SZoe Carver return !(__a > __b); 1717a62bee6SZoe Carver} 1727a62bee6SZoe Carver 1737a62bee6SZoe Carvertemplate <class _W1, class _W2> 1747a62bee6SZoe Carver_LIBCPP_HIDE_FROM_ABI bool operator>=(observer_ptr<_W1> __a, observer_ptr<_W2> __b) { 1757a62bee6SZoe Carver return !(__a < __b); 1767a62bee6SZoe Carver} 1777a62bee6SZoe Carver 1787a62bee6SZoe Carver# endif // _LIBCPP_STD_VER >= 17 1797a62bee6SZoe Carver 1807a62bee6SZoe Carver_LIBCPP_END_NAMESPACE_LFTS_V2 1817a62bee6SZoe Carver 1827a62bee6SZoe Carver_LIBCPP_BEGIN_NAMESPACE_STD 1837a62bee6SZoe Carver 1847a62bee6SZoe Carver// hash 1857a62bee6SZoe Carver 1867a62bee6SZoe Carver# if _LIBCPP_STD_VER >= 17 1877a62bee6SZoe Carvertemplate <class _Tp> 1887a62bee6SZoe Carverstruct hash<experimental::observer_ptr<_Tp>> { 1897a62bee6SZoe Carver _LIBCPP_HIDE_FROM_ABI size_t operator()(const experimental::observer_ptr<_Tp>& __ptr) const noexcept { 1907a62bee6SZoe Carver return hash<_Tp*>()(__ptr.get()); 1917a62bee6SZoe Carver } 1927a62bee6SZoe Carver}; 1937a62bee6SZoe Carver# endif // _LIBCPP_STD_VER >= 17 1947a62bee6SZoe Carver 1957a62bee6SZoe Carver_LIBCPP_END_NAMESPACE_STD 1967a62bee6SZoe Carver 1977a62bee6SZoe Carver# endif // _LIBCPP_ENABLE_EXPERIMENTAL 1987a62bee6SZoe Carver 19995c1313fSNikolas Klauser# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 200e99c4906SNikolas Klauser# include <cstddef> 20195c1313fSNikolas Klauser# include <limits> 20295c1313fSNikolas Klauser# endif 203*b9a2658aSNikolas Klauser#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) 20495c1313fSNikolas Klauser 2057a62bee6SZoe Carver#endif /* _LIBCPP_EXPERIMENTAL_MEMORY */ 206