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