File indexing completed on 2025-07-30 08:46:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB_detail__node_handle_H
0018 #define __TBB_detail__node_handle_H
0019
0020 #include "_allocator_traits.h"
0021 #include "_assert.h"
0022
0023 namespace tbb {
0024 namespace detail {
0025 namespace d1 {
0026
0027
0028
0029
0030 struct node_handle_accessor {
0031 template <typename NodeHandleType>
0032 static typename NodeHandleType::node* get_node_ptr( NodeHandleType& nh ) {
0033 return nh.get_node_ptr();
0034 }
0035
0036 template <typename NodeHandleType>
0037 static NodeHandleType construct( typename NodeHandleType::node* node_ptr ) {
0038 return NodeHandleType{node_ptr};
0039 }
0040
0041 template <typename NodeHandleType>
0042 static void deactivate( NodeHandleType& nh ) {
0043 nh.deactivate();
0044 }
0045 };
0046
0047 template<typename Value, typename Node, typename Allocator>
0048 class node_handle_base {
0049 public:
0050 using allocator_type = Allocator;
0051 protected:
0052 using node = Node;
0053 using allocator_traits_type = tbb::detail::allocator_traits<allocator_type>;
0054 public:
0055
0056 node_handle_base() : my_node(nullptr), my_allocator() {}
0057 node_handle_base(node_handle_base&& nh) : my_node(nh.my_node),
0058 my_allocator(std::move(nh.my_allocator)) {
0059 nh.my_node = nullptr;
0060 }
0061
0062 __TBB_nodiscard bool empty() const { return my_node == nullptr; }
0063 explicit operator bool() const { return my_node != nullptr; }
0064
0065 ~node_handle_base() { internal_destroy(); }
0066
0067 node_handle_base& operator=( node_handle_base&& nh ) {
0068 internal_destroy();
0069 my_node = nh.my_node;
0070 move_assign_allocators(my_allocator, nh.my_allocator);
0071 nh.deactivate();
0072 return *this;
0073 }
0074
0075 void swap( node_handle_base& nh ) {
0076 using std::swap;
0077 swap(my_node, nh.my_node);
0078 swap_allocators(my_allocator, nh.my_allocator);
0079 }
0080
0081 allocator_type get_allocator() const {
0082 return my_allocator;
0083 }
0084
0085 protected:
0086 node_handle_base( node* n ) : my_node(n) {}
0087
0088 void internal_destroy() {
0089 if(my_node != nullptr) {
0090 allocator_traits_type::destroy(my_allocator, my_node->storage());
0091 typename allocator_traits_type::template rebind_alloc<node> node_allocator(my_allocator);
0092 node_allocator.deallocate(my_node, 1);
0093 }
0094 }
0095
0096 node* get_node_ptr() { return my_node; }
0097
0098 void deactivate() { my_node = nullptr; }
0099
0100 node* my_node;
0101 allocator_type my_allocator;
0102 };
0103
0104
0105 template<typename Key, typename Value, typename Node, typename Allocator>
0106 class node_handle : public node_handle_base<Value, Node, Allocator> {
0107 using base_type = node_handle_base<Value, Node, Allocator>;
0108 public:
0109 using key_type = Key;
0110 using mapped_type = typename Value::second_type;
0111 using allocator_type = typename base_type::allocator_type;
0112
0113 node_handle() = default;
0114
0115 key_type& key() const {
0116 __TBB_ASSERT(!this->empty(), "Cannot get key from the empty node_type object");
0117 return *const_cast<key_type*>(&(this->my_node->value().first));
0118 }
0119
0120 mapped_type& mapped() const {
0121 __TBB_ASSERT(!this->empty(), "Cannot get mapped value from the empty node_type object");
0122 return this->my_node->value().second;
0123 }
0124
0125 private:
0126 friend struct node_handle_accessor;
0127
0128 node_handle( typename base_type::node* n ) : base_type(n) {}
0129 };
0130
0131
0132 template<typename Key, typename Node, typename Allocator>
0133 class node_handle<Key, Key, Node, Allocator> : public node_handle_base<Key, Node, Allocator> {
0134 using base_type = node_handle_base<Key, Node, Allocator>;
0135 public:
0136 using value_type = Key;
0137 using allocator_type = typename base_type::allocator_type;
0138
0139 node_handle() = default;
0140
0141 value_type& value() const {
0142 __TBB_ASSERT(!this->empty(), "Cannot get value from the empty node_type object");
0143 return *const_cast<value_type*>(&(this->my_node->value()));
0144 }
0145
0146 private:
0147 friend struct node_handle_accessor;
0148
0149 node_handle( typename base_type::node* n ) : base_type(n) {}
0150 };
0151
0152 template <typename Key, typename Value, typename Node, typename Allocator>
0153 void swap( node_handle<Key, Value, Node, Allocator>& lhs,
0154 node_handle<Key, Value, Node, Allocator>& rhs ) {
0155 return lhs.swap(rhs);
0156 }
0157
0158 }
0159 }
0160 }
0161
0162 #endif