10b57cec5SDimitry Andric// -*- C++ -*- 20b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP___NODE_HANDLE 110b57cec5SDimitry Andric#define _LIBCPP___NODE_HANDLE 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric#include <__config> 14*fe6060f1SDimitry Andric#include <__debug> 150b57cec5SDimitry Andric#include <memory> 160b57cec5SDimitry Andric#include <optional> 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 190b57cec5SDimitry Andric#pragma GCC system_header 200b57cec5SDimitry Andric#endif 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 230b57cec5SDimitry Andric#include <__undef_macros> 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 14 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric// Specialized in __tree & __hash_table for their _NodeType. 300b57cec5SDimitry Andrictemplate <class _NodeType, class _Alloc> 310b57cec5SDimitry Andricstruct __generic_container_node_destructor; 320b57cec5SDimitry Andric 330b57cec5SDimitry Andrictemplate <class _NodeType, class _Alloc, 340b57cec5SDimitry Andric template <class, class> class _MapOrSetSpecifics> 350b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS __basic_node_handle 360b57cec5SDimitry Andric : public _MapOrSetSpecifics< 370b57cec5SDimitry Andric _NodeType, 380b57cec5SDimitry Andric __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>> 390b57cec5SDimitry Andric{ 400b57cec5SDimitry Andric template <class _Tp, class _Compare, class _Allocator> 410b57cec5SDimitry Andric friend class __tree; 420b57cec5SDimitry Andric template <class _Tp, class _Hash, class _Equal, class _Allocator> 430b57cec5SDimitry Andric friend class __hash_table; 440b57cec5SDimitry Andric friend struct _MapOrSetSpecifics< 450b57cec5SDimitry Andric _NodeType, __basic_node_handle<_NodeType, _Alloc, _MapOrSetSpecifics>>; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric typedef allocator_traits<_Alloc> __alloc_traits; 480b57cec5SDimitry Andric typedef typename __rebind_pointer<typename __alloc_traits::void_pointer, 490b57cec5SDimitry Andric _NodeType>::type 500b57cec5SDimitry Andric __node_pointer_type; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andricpublic: 530b57cec5SDimitry Andric typedef _Alloc allocator_type; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andricprivate: 560b57cec5SDimitry Andric __node_pointer_type __ptr_ = nullptr; 570b57cec5SDimitry Andric optional<allocator_type> __alloc_; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 600b57cec5SDimitry Andric void __release_ptr() 610b57cec5SDimitry Andric { 620b57cec5SDimitry Andric __ptr_ = nullptr; 630b57cec5SDimitry Andric __alloc_ = _VSTD::nullopt; 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 670b57cec5SDimitry Andric void __destroy_node_pointer() 680b57cec5SDimitry Andric { 690b57cec5SDimitry Andric if (__ptr_ != nullptr) 700b57cec5SDimitry Andric { 710b57cec5SDimitry Andric typedef typename __allocator_traits_rebind< 720b57cec5SDimitry Andric allocator_type, _NodeType>::type __node_alloc_type; 730b57cec5SDimitry Andric __node_alloc_type __alloc(*__alloc_); 740b57cec5SDimitry Andric __generic_container_node_destructor<_NodeType, __node_alloc_type>( 750b57cec5SDimitry Andric __alloc, true)(__ptr_); 760b57cec5SDimitry Andric __ptr_ = nullptr; 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 810b57cec5SDimitry Andric __basic_node_handle(__node_pointer_type __ptr, 820b57cec5SDimitry Andric allocator_type const& __alloc) 830b57cec5SDimitry Andric : __ptr_(__ptr), __alloc_(__alloc) 840b57cec5SDimitry Andric { 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andricpublic: 880b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 890b57cec5SDimitry Andric __basic_node_handle() = default; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 920b57cec5SDimitry Andric __basic_node_handle(__basic_node_handle&& __other) noexcept 930b57cec5SDimitry Andric : __ptr_(__other.__ptr_), 940b57cec5SDimitry Andric __alloc_(_VSTD::move(__other.__alloc_)) 950b57cec5SDimitry Andric { 960b57cec5SDimitry Andric __other.__ptr_ = nullptr; 970b57cec5SDimitry Andric __other.__alloc_ = _VSTD::nullopt; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1010b57cec5SDimitry Andric __basic_node_handle& operator=(__basic_node_handle&& __other) 1020b57cec5SDimitry Andric { 1030b57cec5SDimitry Andric _LIBCPP_ASSERT( 1040b57cec5SDimitry Andric __alloc_ == _VSTD::nullopt || 1050b57cec5SDimitry Andric __alloc_traits::propagate_on_container_move_assignment::value || 1060b57cec5SDimitry Andric __alloc_ == __other.__alloc_, 1070b57cec5SDimitry Andric "node_type with incompatible allocator passed to " 1080b57cec5SDimitry Andric "node_type::operator=(node_type&&)"); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric __destroy_node_pointer(); 1110b57cec5SDimitry Andric __ptr_ = __other.__ptr_; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric if (__alloc_traits::propagate_on_container_move_assignment::value || 1140b57cec5SDimitry Andric __alloc_ == _VSTD::nullopt) 1150b57cec5SDimitry Andric __alloc_ = _VSTD::move(__other.__alloc_); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric __other.__ptr_ = nullptr; 1180b57cec5SDimitry Andric __other.__alloc_ = _VSTD::nullopt; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric return *this; 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1240b57cec5SDimitry Andric allocator_type get_allocator() const { return *__alloc_; } 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1270b57cec5SDimitry Andric explicit operator bool() const { return __ptr_ != nullptr; } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 1300b57cec5SDimitry Andric bool empty() const { return __ptr_ == nullptr; } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1330b57cec5SDimitry Andric void swap(__basic_node_handle& __other) noexcept( 1340b57cec5SDimitry Andric __alloc_traits::propagate_on_container_swap::value || 1350b57cec5SDimitry Andric __alloc_traits::is_always_equal::value) 1360b57cec5SDimitry Andric { 1370b57cec5SDimitry Andric using _VSTD::swap; 1380b57cec5SDimitry Andric swap(__ptr_, __other.__ptr_); 1390b57cec5SDimitry Andric if (__alloc_traits::propagate_on_container_swap::value || 1400b57cec5SDimitry Andric __alloc_ == _VSTD::nullopt || __other.__alloc_ == _VSTD::nullopt) 1410b57cec5SDimitry Andric swap(__alloc_, __other.__alloc_); 1420b57cec5SDimitry Andric } 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1450b57cec5SDimitry Andric friend void swap(__basic_node_handle& __a, __basic_node_handle& __b) 1460b57cec5SDimitry Andric noexcept(noexcept(__a.swap(__b))) { __a.swap(__b); } 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1490b57cec5SDimitry Andric ~__basic_node_handle() 1500b57cec5SDimitry Andric { 1510b57cec5SDimitry Andric __destroy_node_pointer(); 1520b57cec5SDimitry Andric } 1530b57cec5SDimitry Andric}; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andrictemplate <class _NodeType, class _Derived> 1560b57cec5SDimitry Andricstruct __set_node_handle_specifics 1570b57cec5SDimitry Andric{ 1580b57cec5SDimitry Andric typedef typename _NodeType::__node_value_type value_type; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1610b57cec5SDimitry Andric value_type& value() const 1620b57cec5SDimitry Andric { 1630b57cec5SDimitry Andric return static_cast<_Derived const*>(this)->__ptr_->__value_; 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric}; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andrictemplate <class _NodeType, class _Derived> 1680b57cec5SDimitry Andricstruct __map_node_handle_specifics 1690b57cec5SDimitry Andric{ 1700b57cec5SDimitry Andric typedef typename _NodeType::__node_value_type::key_type key_type; 1710b57cec5SDimitry Andric typedef typename _NodeType::__node_value_type::mapped_type mapped_type; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1740b57cec5SDimitry Andric key_type& key() const 1750b57cec5SDimitry Andric { 1760b57cec5SDimitry Andric return static_cast<_Derived const*>(this)-> 1770b57cec5SDimitry Andric __ptr_->__value_.__ref().first; 1780b57cec5SDimitry Andric } 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1810b57cec5SDimitry Andric mapped_type& mapped() const 1820b57cec5SDimitry Andric { 1830b57cec5SDimitry Andric return static_cast<_Derived const*>(this)-> 1840b57cec5SDimitry Andric __ptr_->__value_.__ref().second; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric}; 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andrictemplate <class _NodeType, class _Alloc> 1890b57cec5SDimitry Andricusing __set_node_handle = 1900b57cec5SDimitry Andric __basic_node_handle< _NodeType, _Alloc, __set_node_handle_specifics>; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andrictemplate <class _NodeType, class _Alloc> 1930b57cec5SDimitry Andricusing __map_node_handle = 1940b57cec5SDimitry Andric __basic_node_handle< _NodeType, _Alloc, __map_node_handle_specifics>; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andrictemplate <class _Iterator, class _NodeType> 1970b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS __insert_return_type 1980b57cec5SDimitry Andric{ 1990b57cec5SDimitry Andric _Iterator position; 2000b57cec5SDimitry Andric bool inserted; 2010b57cec5SDimitry Andric _NodeType node; 2020b57cec5SDimitry Andric}; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 14 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 2070b57cec5SDimitry Andric_LIBCPP_POP_MACROS 2080b57cec5SDimitry Andric 209*fe6060f1SDimitry Andric#endif // _LIBCPP___NODE_HANDLE 210