xref: /freebsd/contrib/llvm-project/libcxx/include/experimental/memory (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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