xref: /openbsd-src/gnu/llvm/libcxx/include/__node_handle (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick// -*- C++ -*-
246035553Spatrick//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP___NODE_HANDLE
1146035553Spatrick#define _LIBCPP___NODE_HANDLE
1246035553Spatrick
13*4bdff4beSrobert/*
14*4bdff4beSrobert
15*4bdff4beSroberttemplate<unspecified>
16*4bdff4beSrobertclass node-handle {
17*4bdff4beSrobertpublic:
18*4bdff4beSrobert  using value_type     = see below;     // not present for map containers
19*4bdff4beSrobert  using key_type       = see below;     // not present for set containers
20*4bdff4beSrobert  using mapped_type    = see below;     // not present for set containers
21*4bdff4beSrobert  using allocator_type = see below;
22*4bdff4beSrobert
23*4bdff4beSrobertprivate:
24*4bdff4beSrobert  using container_node_type = unspecified;                  // exposition only
25*4bdff4beSrobert  using ator_traits = allocator_traits<allocator_type>;     // exposition only
26*4bdff4beSrobert
27*4bdff4beSrobert  typename ator_traits::template
28*4bdff4beSrobert    rebind_traits<container_node_type>::pointer ptr_;       // exposition only
29*4bdff4beSrobert  optional<allocator_type> alloc_;                          // exposition only
30*4bdff4beSrobert
31*4bdff4beSrobertpublic:
32*4bdff4beSrobert  // [container.node.cons], constructors, copy, and assignment
33*4bdff4beSrobert  constexpr node-handle() noexcept : ptr_(), alloc_() {}
34*4bdff4beSrobert  node-handle(node-handle&&) noexcept;
35*4bdff4beSrobert  node-handle& operator=(node-handle&&);
36*4bdff4beSrobert
37*4bdff4beSrobert  // [container.node.dtor], destructor
38*4bdff4beSrobert  ~node-handle();
39*4bdff4beSrobert
40*4bdff4beSrobert  // [container.node.observers], observers
41*4bdff4beSrobert  value_type& value() const;            // not present for map containers
42*4bdff4beSrobert  key_type& key() const;                // not present for set containers
43*4bdff4beSrobert  mapped_type& mapped() const;          // not present for set containers
44*4bdff4beSrobert
45*4bdff4beSrobert  allocator_type get_allocator() const;
46*4bdff4beSrobert  explicit operator bool() const noexcept;
47*4bdff4beSrobert  [[nodiscard]] bool empty() const noexcept; // nodiscard since C++20
48*4bdff4beSrobert
49*4bdff4beSrobert  // [container.node.modifiers], modifiers
50*4bdff4beSrobert  void swap(node-handle&)
51*4bdff4beSrobert    noexcept(ator_traits::propagate_on_container_swap::value ||
52*4bdff4beSrobert             ator_traits::is_always_equal::value);
53*4bdff4beSrobert
54*4bdff4beSrobert  friend void swap(node-handle& x, node-handle& y) noexcept(noexcept(x.swap(y))) {
55*4bdff4beSrobert    x.swap(y);
56*4bdff4beSrobert  }
57*4bdff4beSrobert};
58*4bdff4beSrobert
59*4bdff4beSrobert*/
60*4bdff4beSrobert
61*4bdff4beSrobert#include <__assert>
6246035553Spatrick#include <__config>
63*4bdff4beSrobert#include <__memory/allocator_traits.h>
64*4bdff4beSrobert#include <__memory/pointer_traits.h>
6546035553Spatrick#include <optional>
6646035553Spatrick
6746035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6846035553Spatrick#  pragma GCC system_header
6946035553Spatrick#endif
7046035553Spatrick
7146035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
7246035553Spatrick
7346035553Spatrick#if _LIBCPP_STD_VER > 14
7446035553Spatrick
7546035553Spatrick// Specialized in __tree & __hash_table for their _NodeType.
7646035553Spatricktemplate <class _NodeType, class _Alloc>
7746035553Spatrickstruct __generic_container_node_destructor;
7846035553Spatrick
7946035553Spatricktemplate <class _NodeType, class _Alloc,
8046035553Spatrick          template <class, class> class _MapOrSetSpecifics>
8146035553Spatrickclass _LIBCPP_TEMPLATE_VIS __basic_node_handle
8246035553Spatrick    : public _MapOrSetSpecifics<
8346035553Spatrick          _NodeType,
8446035553Spatrick          __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>
8546035553Spatrick{
8646035553Spatrick    template <class _Tp, class _Compare, class _Allocator>
8746035553Spatrick        friend class __tree;
8846035553Spatrick    template <class _Tp, class _Hash, class _Equal, class _Allocator>
8946035553Spatrick        friend class __hash_table;
9046035553Spatrick    friend struct _MapOrSetSpecifics<
9146035553Spatrick        _NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>;
9246035553Spatrick
9346035553Spatrick    typedef allocator_traits<_Alloc> __alloc_traits;
94*4bdff4beSrobert    typedef __rebind_pointer_t<typename __alloc_traits::void_pointer,
95*4bdff4beSrobert                                      _NodeType>
9646035553Spatrick        __node_pointer_type;
9746035553Spatrick
9846035553Spatrickpublic:
9946035553Spatrick    typedef _Alloc allocator_type;
10046035553Spatrick
10146035553Spatrickprivate:
10246035553Spatrick    __node_pointer_type __ptr_ = nullptr;
10346035553Spatrick    optional<allocator_type> __alloc_;
10446035553Spatrick
10546035553Spatrick    _LIBCPP_INLINE_VISIBILITY
10646035553Spatrick    void __release_ptr()
10746035553Spatrick    {
10846035553Spatrick        __ptr_ = nullptr;
10946035553Spatrick        __alloc_ = _VSTD::nullopt;
11046035553Spatrick    }
11146035553Spatrick
11246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
11346035553Spatrick    void __destroy_node_pointer()
11446035553Spatrick    {
11546035553Spatrick        if (__ptr_ != nullptr)
11646035553Spatrick        {
11746035553Spatrick            typedef typename __allocator_traits_rebind<
11846035553Spatrick                allocator_type, _NodeType>::type __node_alloc_type;
11946035553Spatrick            __node_alloc_type __alloc(*__alloc_);
12046035553Spatrick            __generic_container_node_destructor<_NodeType, __node_alloc_type>(
12146035553Spatrick                __alloc, true)(__ptr_);
12246035553Spatrick            __ptr_ = nullptr;
12346035553Spatrick        }
12446035553Spatrick    }
12546035553Spatrick
12646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
12746035553Spatrick    __basic_node_handle(__node_pointer_type __ptr,
12846035553Spatrick                        allocator_type const& __alloc)
12946035553Spatrick            : __ptr_(__ptr), __alloc_(__alloc)
13046035553Spatrick    {
13146035553Spatrick    }
13246035553Spatrick
13346035553Spatrickpublic:
13446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
13546035553Spatrick    __basic_node_handle() = default;
13646035553Spatrick
13746035553Spatrick    _LIBCPP_INLINE_VISIBILITY
13846035553Spatrick    __basic_node_handle(__basic_node_handle&& __other) noexcept
13946035553Spatrick            : __ptr_(__other.__ptr_),
14046035553Spatrick              __alloc_(_VSTD::move(__other.__alloc_))
14146035553Spatrick    {
14246035553Spatrick        __other.__ptr_ = nullptr;
14346035553Spatrick        __other.__alloc_ = _VSTD::nullopt;
14446035553Spatrick    }
14546035553Spatrick
14646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
14746035553Spatrick    __basic_node_handle& operator=(__basic_node_handle&& __other)
14846035553Spatrick    {
14946035553Spatrick        _LIBCPP_ASSERT(
15046035553Spatrick            __alloc_ == _VSTD::nullopt ||
15146035553Spatrick            __alloc_traits::propagate_on_container_move_assignment::value ||
15246035553Spatrick            __alloc_ == __other.__alloc_,
15346035553Spatrick            "node_type with incompatible allocator passed to "
15446035553Spatrick            "node_type::operator=(node_type&&)");
15546035553Spatrick
15646035553Spatrick        __destroy_node_pointer();
15746035553Spatrick        __ptr_ = __other.__ptr_;
15846035553Spatrick
15946035553Spatrick        if (__alloc_traits::propagate_on_container_move_assignment::value ||
16046035553Spatrick            __alloc_ == _VSTD::nullopt)
16146035553Spatrick            __alloc_ = _VSTD::move(__other.__alloc_);
16246035553Spatrick
16346035553Spatrick        __other.__ptr_ = nullptr;
16446035553Spatrick        __other.__alloc_ = _VSTD::nullopt;
16546035553Spatrick
16646035553Spatrick        return *this;
16746035553Spatrick    }
16846035553Spatrick
16946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
17046035553Spatrick    allocator_type get_allocator() const { return *__alloc_; }
17146035553Spatrick
17246035553Spatrick    _LIBCPP_INLINE_VISIBILITY
17346035553Spatrick    explicit operator bool() const { return __ptr_ != nullptr; }
17446035553Spatrick
17546035553Spatrick    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
17646035553Spatrick    bool empty() const { return __ptr_ == nullptr; }
17746035553Spatrick
17846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
17946035553Spatrick    void swap(__basic_node_handle& __other) noexcept(
18046035553Spatrick        __alloc_traits::propagate_on_container_swap::value ||
18146035553Spatrick        __alloc_traits::is_always_equal::value)
18246035553Spatrick    {
18346035553Spatrick        using _VSTD::swap;
18446035553Spatrick        swap(__ptr_, __other.__ptr_);
18546035553Spatrick        if (__alloc_traits::propagate_on_container_swap::value ||
18646035553Spatrick            __alloc_ == _VSTD::nullopt || __other.__alloc_ == _VSTD::nullopt)
18746035553Spatrick            swap(__alloc_, __other.__alloc_);
18846035553Spatrick    }
18946035553Spatrick
19046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
19146035553Spatrick    friend void swap(__basic_node_handle& __a, __basic_node_handle& __b)
19246035553Spatrick        noexcept(noexcept(__a.swap(__b))) { __a.swap(__b); }
19346035553Spatrick
19446035553Spatrick    _LIBCPP_INLINE_VISIBILITY
19546035553Spatrick    ~__basic_node_handle()
19646035553Spatrick    {
19746035553Spatrick        __destroy_node_pointer();
19846035553Spatrick    }
19946035553Spatrick};
20046035553Spatrick
20146035553Spatricktemplate <class _NodeType, class _Derived>
20246035553Spatrickstruct __set_node_handle_specifics
20346035553Spatrick{
20446035553Spatrick    typedef typename _NodeType::__node_value_type value_type;
20546035553Spatrick
20646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
20746035553Spatrick    value_type& value() const
20846035553Spatrick    {
20946035553Spatrick        return static_cast<_Derived const*>(this)->__ptr_->__value_;
21046035553Spatrick    }
21146035553Spatrick};
21246035553Spatrick
21346035553Spatricktemplate <class _NodeType, class _Derived>
21446035553Spatrickstruct __map_node_handle_specifics
21546035553Spatrick{
21646035553Spatrick    typedef typename _NodeType::__node_value_type::key_type key_type;
21746035553Spatrick    typedef typename _NodeType::__node_value_type::mapped_type mapped_type;
21846035553Spatrick
21946035553Spatrick    _LIBCPP_INLINE_VISIBILITY
22046035553Spatrick    key_type& key() const
22146035553Spatrick    {
22246035553Spatrick        return static_cast<_Derived const*>(this)->
22346035553Spatrick            __ptr_->__value_.__ref().first;
22446035553Spatrick    }
22546035553Spatrick
22646035553Spatrick    _LIBCPP_INLINE_VISIBILITY
22746035553Spatrick    mapped_type& mapped() const
22846035553Spatrick    {
22946035553Spatrick        return static_cast<_Derived const*>(this)->
23046035553Spatrick            __ptr_->__value_.__ref().second;
23146035553Spatrick    }
23246035553Spatrick};
23346035553Spatrick
23446035553Spatricktemplate <class _NodeType, class _Alloc>
23546035553Spatrickusing __set_node_handle =
23646035553Spatrick    __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>;
23746035553Spatrick
23846035553Spatricktemplate <class _NodeType, class _Alloc>
23946035553Spatrickusing __map_node_handle =
24046035553Spatrick    __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>;
24146035553Spatrick
24246035553Spatricktemplate <class _Iterator, class _NodeType>
24346035553Spatrickstruct _LIBCPP_TEMPLATE_VIS __insert_return_type
24446035553Spatrick{
24546035553Spatrick    _Iterator position;
24646035553Spatrick    bool inserted;
24746035553Spatrick    _NodeType node;
24846035553Spatrick};
24946035553Spatrick
25046035553Spatrick#endif // _LIBCPP_STD_VER > 14
25146035553Spatrick
25246035553Spatrick_LIBCPP_END_NAMESPACE_STD
25346035553Spatrick
25476d0caaeSpatrick#endif  // _LIBCPP___NODE_HANDLE
255