xref: /aosp_15_r20/external/libcxx/include/__node_handle (revision 58b9f456b02922dfdb1fad8a988d5fd8765ecb80)
1*58b9f456SAndroid Build Coastguard Worker// -*- C++ -*-
2*58b9f456SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
3*58b9f456SAndroid Build Coastguard Worker//
4*58b9f456SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
5*58b9f456SAndroid Build Coastguard Worker//
6*58b9f456SAndroid Build Coastguard Worker// This file is dual licensed under the MIT and the University of Illinois Open
7*58b9f456SAndroid Build Coastguard Worker// Source Licenses. See LICENSE.TXT for details.
8*58b9f456SAndroid Build Coastguard Worker//
9*58b9f456SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
10*58b9f456SAndroid Build Coastguard Worker
11*58b9f456SAndroid Build Coastguard Worker#ifndef _LIBCPP___NODE_HANDLE
12*58b9f456SAndroid Build Coastguard Worker#define _LIBCPP___NODE_HANDLE
13*58b9f456SAndroid Build Coastguard Worker
14*58b9f456SAndroid Build Coastguard Worker#include <__config>
15*58b9f456SAndroid Build Coastguard Worker#include <memory>
16*58b9f456SAndroid Build Coastguard Worker#include <optional>
17*58b9f456SAndroid Build Coastguard Worker
18*58b9f456SAndroid Build Coastguard Worker#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19*58b9f456SAndroid Build Coastguard Worker#pragma GCC system_header
20*58b9f456SAndroid Build Coastguard Worker#endif
21*58b9f456SAndroid Build Coastguard Worker
22*58b9f456SAndroid Build Coastguard Worker_LIBCPP_PUSH_MACROS
23*58b9f456SAndroid Build Coastguard Worker#include <__undef_macros>
24*58b9f456SAndroid Build Coastguard Worker
25*58b9f456SAndroid Build Coastguard Worker_LIBCPP_BEGIN_NAMESPACE_STD
26*58b9f456SAndroid Build Coastguard Worker
27*58b9f456SAndroid Build Coastguard Worker#if _LIBCPP_STD_VER > 14
28*58b9f456SAndroid Build Coastguard Worker
29*58b9f456SAndroid Build Coastguard Worker// Specialized in __tree & __hash_table for their _NodeType.
30*58b9f456SAndroid Build Coastguard Workertemplate <class _NodeType, class _Alloc>
31*58b9f456SAndroid Build Coastguard Workerstruct __generic_container_node_destructor;
32*58b9f456SAndroid Build Coastguard Worker
33*58b9f456SAndroid Build Coastguard Workertemplate <class _NodeType, class _Alloc,
34*58b9f456SAndroid Build Coastguard Worker          template <class, class> class _MapOrSetSpecifics>
35*58b9f456SAndroid Build Coastguard Workerclass _LIBCPP_TEMPLATE_VIS __basic_node_handle
36*58b9f456SAndroid Build Coastguard Worker    : public _MapOrSetSpecifics<
37*58b9f456SAndroid Build Coastguard Worker          _NodeType,
38*58b9f456SAndroid Build Coastguard Worker          __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>
39*58b9f456SAndroid Build Coastguard Worker{
40*58b9f456SAndroid Build Coastguard Worker    template <class _Tp, class _Compare, class _Allocator>
41*58b9f456SAndroid Build Coastguard Worker        friend class __tree;
42*58b9f456SAndroid Build Coastguard Worker    template <class _Tp, class _Hash, class _Equal, class _Allocator>
43*58b9f456SAndroid Build Coastguard Worker        friend class __hash_table;
44*58b9f456SAndroid Build Coastguard Worker    friend struct _MapOrSetSpecifics<
45*58b9f456SAndroid Build Coastguard Worker        _NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>;
46*58b9f456SAndroid Build Coastguard Worker
47*58b9f456SAndroid Build Coastguard Worker    typedef allocator_traits<_Alloc> __alloc_traits;
48*58b9f456SAndroid Build Coastguard Worker    typedef typename __rebind_pointer<typename __alloc_traits::void_pointer,
49*58b9f456SAndroid Build Coastguard Worker                                      _NodeType>::type
50*58b9f456SAndroid Build Coastguard Worker        __node_pointer_type;
51*58b9f456SAndroid Build Coastguard Worker
52*58b9f456SAndroid Build Coastguard Workerpublic:
53*58b9f456SAndroid Build Coastguard Worker    typedef _Alloc allocator_type;
54*58b9f456SAndroid Build Coastguard Worker
55*58b9f456SAndroid Build Coastguard Workerprivate:
56*58b9f456SAndroid Build Coastguard Worker    __node_pointer_type __ptr_ = nullptr;
57*58b9f456SAndroid Build Coastguard Worker    optional<allocator_type> __alloc_;
58*58b9f456SAndroid Build Coastguard Worker
59*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
60*58b9f456SAndroid Build Coastguard Worker    void __release()
61*58b9f456SAndroid Build Coastguard Worker    {
62*58b9f456SAndroid Build Coastguard Worker        __ptr_ = nullptr;
63*58b9f456SAndroid Build Coastguard Worker        __alloc_ = _VSTD::nullopt;
64*58b9f456SAndroid Build Coastguard Worker    }
65*58b9f456SAndroid Build Coastguard Worker
66*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
67*58b9f456SAndroid Build Coastguard Worker    void __destroy_node_pointer()
68*58b9f456SAndroid Build Coastguard Worker    {
69*58b9f456SAndroid Build Coastguard Worker        if (__ptr_ != nullptr)
70*58b9f456SAndroid Build Coastguard Worker        {
71*58b9f456SAndroid Build Coastguard Worker            typedef typename __allocator_traits_rebind<
72*58b9f456SAndroid Build Coastguard Worker                allocator_type, _NodeType>::type __node_alloc_type;
73*58b9f456SAndroid Build Coastguard Worker            __node_alloc_type __alloc(*__alloc_);
74*58b9f456SAndroid Build Coastguard Worker            __generic_container_node_destructor<_NodeType, __node_alloc_type>(
75*58b9f456SAndroid Build Coastguard Worker                __alloc, true)(__ptr_);
76*58b9f456SAndroid Build Coastguard Worker            __ptr_ = nullptr;
77*58b9f456SAndroid Build Coastguard Worker        }
78*58b9f456SAndroid Build Coastguard Worker    }
79*58b9f456SAndroid Build Coastguard Worker
80*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
81*58b9f456SAndroid Build Coastguard Worker    __basic_node_handle(__node_pointer_type __ptr,
82*58b9f456SAndroid Build Coastguard Worker                        allocator_type const& __alloc)
83*58b9f456SAndroid Build Coastguard Worker            : __ptr_(__ptr), __alloc_(__alloc)
84*58b9f456SAndroid Build Coastguard Worker    {
85*58b9f456SAndroid Build Coastguard Worker    }
86*58b9f456SAndroid Build Coastguard Worker
87*58b9f456SAndroid Build Coastguard Workerpublic:
88*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
89*58b9f456SAndroid Build Coastguard Worker    __basic_node_handle() = default;
90*58b9f456SAndroid Build Coastguard Worker
91*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
92*58b9f456SAndroid Build Coastguard Worker    __basic_node_handle(__basic_node_handle&& __other) noexcept
93*58b9f456SAndroid Build Coastguard Worker            : __ptr_(__other.__ptr_),
94*58b9f456SAndroid Build Coastguard Worker              __alloc_(_VSTD::move(__other.__alloc_))
95*58b9f456SAndroid Build Coastguard Worker    {
96*58b9f456SAndroid Build Coastguard Worker        __other.__ptr_ = nullptr;
97*58b9f456SAndroid Build Coastguard Worker        __other.__alloc_ = _VSTD::nullopt;
98*58b9f456SAndroid Build Coastguard Worker    }
99*58b9f456SAndroid Build Coastguard Worker
100*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
101*58b9f456SAndroid Build Coastguard Worker    __basic_node_handle& operator=(__basic_node_handle&& __other)
102*58b9f456SAndroid Build Coastguard Worker    {
103*58b9f456SAndroid Build Coastguard Worker        _LIBCPP_ASSERT(
104*58b9f456SAndroid Build Coastguard Worker            __alloc_ == _VSTD::nullopt ||
105*58b9f456SAndroid Build Coastguard Worker            __alloc_traits::propagate_on_container_move_assignment::value ||
106*58b9f456SAndroid Build Coastguard Worker            __alloc_ == __other.__alloc_,
107*58b9f456SAndroid Build Coastguard Worker            "node_type with incompatible allocator passed to "
108*58b9f456SAndroid Build Coastguard Worker            "node_type::operator=(node_type&&)");
109*58b9f456SAndroid Build Coastguard Worker
110*58b9f456SAndroid Build Coastguard Worker        __destroy_node_pointer();
111*58b9f456SAndroid Build Coastguard Worker        __ptr_ = __other.__ptr_;
112*58b9f456SAndroid Build Coastguard Worker
113*58b9f456SAndroid Build Coastguard Worker        if (__alloc_traits::propagate_on_container_move_assignment::value ||
114*58b9f456SAndroid Build Coastguard Worker            __alloc_ == _VSTD::nullopt)
115*58b9f456SAndroid Build Coastguard Worker            __alloc_ = _VSTD::move(__other.__alloc_);
116*58b9f456SAndroid Build Coastguard Worker
117*58b9f456SAndroid Build Coastguard Worker        __other.__ptr_ = nullptr;
118*58b9f456SAndroid Build Coastguard Worker        __other.__alloc_ = _VSTD::nullopt;
119*58b9f456SAndroid Build Coastguard Worker
120*58b9f456SAndroid Build Coastguard Worker        return *this;
121*58b9f456SAndroid Build Coastguard Worker    }
122*58b9f456SAndroid Build Coastguard Worker
123*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
124*58b9f456SAndroid Build Coastguard Worker    allocator_type get_allocator() const { return *__alloc_; }
125*58b9f456SAndroid Build Coastguard Worker
126*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
127*58b9f456SAndroid Build Coastguard Worker    explicit operator bool() const { return __ptr_ != nullptr; }
128*58b9f456SAndroid Build Coastguard Worker
129*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
130*58b9f456SAndroid Build Coastguard Worker    bool empty() const { return __ptr_ == nullptr; }
131*58b9f456SAndroid Build Coastguard Worker
132*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
133*58b9f456SAndroid Build Coastguard Worker    void swap(__basic_node_handle& __other) noexcept(
134*58b9f456SAndroid Build Coastguard Worker        __alloc_traits::propagate_on_container_swap::value ||
135*58b9f456SAndroid Build Coastguard Worker        __alloc_traits::is_always_equal::value)
136*58b9f456SAndroid Build Coastguard Worker    {
137*58b9f456SAndroid Build Coastguard Worker        using _VSTD::swap;
138*58b9f456SAndroid Build Coastguard Worker        swap(__ptr_, __other.__ptr_);
139*58b9f456SAndroid Build Coastguard Worker        if (__alloc_traits::propagate_on_container_swap::value ||
140*58b9f456SAndroid Build Coastguard Worker            __alloc_ == _VSTD::nullopt || __other.__alloc_ == _VSTD::nullopt)
141*58b9f456SAndroid Build Coastguard Worker            swap(__alloc_, __other.__alloc_);
142*58b9f456SAndroid Build Coastguard Worker    }
143*58b9f456SAndroid Build Coastguard Worker
144*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
145*58b9f456SAndroid Build Coastguard Worker    friend void swap(__basic_node_handle& __a, __basic_node_handle& __b)
146*58b9f456SAndroid Build Coastguard Worker        noexcept(noexcept(__a.swap(__b))) { __a.swap(__b); }
147*58b9f456SAndroid Build Coastguard Worker
148*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
149*58b9f456SAndroid Build Coastguard Worker    ~__basic_node_handle()
150*58b9f456SAndroid Build Coastguard Worker    {
151*58b9f456SAndroid Build Coastguard Worker        __destroy_node_pointer();
152*58b9f456SAndroid Build Coastguard Worker    }
153*58b9f456SAndroid Build Coastguard Worker};
154*58b9f456SAndroid Build Coastguard Worker
155*58b9f456SAndroid Build Coastguard Workertemplate <class _NodeType, class _Derived>
156*58b9f456SAndroid Build Coastguard Workerstruct __set_node_handle_specifics
157*58b9f456SAndroid Build Coastguard Worker{
158*58b9f456SAndroid Build Coastguard Worker    typedef typename _NodeType::__node_value_type value_type;
159*58b9f456SAndroid Build Coastguard Worker
160*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
161*58b9f456SAndroid Build Coastguard Worker    value_type& value() const
162*58b9f456SAndroid Build Coastguard Worker    {
163*58b9f456SAndroid Build Coastguard Worker        return static_cast<_Derived const*>(this)->__ptr_->__value_;
164*58b9f456SAndroid Build Coastguard Worker    }
165*58b9f456SAndroid Build Coastguard Worker};
166*58b9f456SAndroid Build Coastguard Worker
167*58b9f456SAndroid Build Coastguard Workertemplate <class _NodeType, class _Derived>
168*58b9f456SAndroid Build Coastguard Workerstruct __map_node_handle_specifics
169*58b9f456SAndroid Build Coastguard Worker{
170*58b9f456SAndroid Build Coastguard Worker    typedef typename _NodeType::__node_value_type::key_type key_type;
171*58b9f456SAndroid Build Coastguard Worker    typedef typename _NodeType::__node_value_type::mapped_type mapped_type;
172*58b9f456SAndroid Build Coastguard Worker
173*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
174*58b9f456SAndroid Build Coastguard Worker    key_type& key() const
175*58b9f456SAndroid Build Coastguard Worker    {
176*58b9f456SAndroid Build Coastguard Worker        return static_cast<_Derived const*>(this)->
177*58b9f456SAndroid Build Coastguard Worker            __ptr_->__value_.__ref().first;
178*58b9f456SAndroid Build Coastguard Worker    }
179*58b9f456SAndroid Build Coastguard Worker
180*58b9f456SAndroid Build Coastguard Worker    _LIBCPP_INLINE_VISIBILITY
181*58b9f456SAndroid Build Coastguard Worker    mapped_type& mapped() const
182*58b9f456SAndroid Build Coastguard Worker    {
183*58b9f456SAndroid Build Coastguard Worker        return static_cast<_Derived const*>(this)->
184*58b9f456SAndroid Build Coastguard Worker            __ptr_->__value_.__ref().second;
185*58b9f456SAndroid Build Coastguard Worker    }
186*58b9f456SAndroid Build Coastguard Worker};
187*58b9f456SAndroid Build Coastguard Worker
188*58b9f456SAndroid Build Coastguard Workertemplate <class _NodeType, class _Alloc>
189*58b9f456SAndroid Build Coastguard Workerusing __set_node_handle =
190*58b9f456SAndroid Build Coastguard Worker    __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>;
191*58b9f456SAndroid Build Coastguard Worker
192*58b9f456SAndroid Build Coastguard Workertemplate <class _NodeType, class _Alloc>
193*58b9f456SAndroid Build Coastguard Workerusing __map_node_handle =
194*58b9f456SAndroid Build Coastguard Worker    __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>;
195*58b9f456SAndroid Build Coastguard Worker
196*58b9f456SAndroid Build Coastguard Workertemplate <class _Iterator, class _NodeType>
197*58b9f456SAndroid Build Coastguard Worker_LIBCPP_TEMPLATE_VIS
198*58b9f456SAndroid Build Coastguard Workerstruct __insert_return_type
199*58b9f456SAndroid Build Coastguard Worker{
200*58b9f456SAndroid Build Coastguard Worker    _Iterator position;
201*58b9f456SAndroid Build Coastguard Worker    bool inserted;
202*58b9f456SAndroid Build Coastguard Worker    _NodeType node;
203*58b9f456SAndroid Build Coastguard Worker};
204*58b9f456SAndroid Build Coastguard Worker
205*58b9f456SAndroid Build Coastguard Worker#endif // _LIBCPP_STD_VER > 14
206*58b9f456SAndroid Build Coastguard Worker
207*58b9f456SAndroid Build Coastguard Worker_LIBCPP_END_NAMESPACE_STD
208*58b9f456SAndroid Build Coastguard Worker_LIBCPP_POP_MACROS
209*58b9f456SAndroid Build Coastguard Worker
210*58b9f456SAndroid Build Coastguard Worker#endif
211