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