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