File indexing completed on 2025-01-18 10:12:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef __TBB_node_handle_H
0018 #define __TBB_node_handle_H
0019
0020 #include "_allocator_traits.h"
0021 #include "../tbb_config.h"
0022
0023
0024 namespace tbb {
0025
0026
0027
0028 namespace interface5 {
0029 namespace internal {
0030 template <typename T, typename Allocator>
0031 class split_ordered_list;
0032 template <typename Traits>
0033 class concurrent_unordered_base;
0034 }
0035 }
0036
0037 namespace interface10{
0038 namespace internal {
0039 template<typename Traits>
0040 class concurrent_skip_list;
0041 }
0042 }
0043
0044 namespace internal {
0045
0046 template<typename Value, typename Node, typename Allocator>
0047 class node_handle_base {
0048 public:
0049 typedef Allocator allocator_type;
0050 protected:
0051 typedef Node node;
0052 typedef tbb::internal::allocator_traits<allocator_type> traits_type;
0053 public:
0054
0055 node_handle_base() : my_node(NULL), my_allocator() {}
0056 node_handle_base(node_handle_base&& nh) : my_node(nh.my_node),
0057 my_allocator(std::move(nh.my_allocator)) {
0058 nh.my_node = NULL;
0059 }
0060
0061 bool empty() const { return my_node == NULL; }
0062 explicit operator bool() const { return my_node != NULL; }
0063
0064 ~node_handle_base() { internal_destroy(); }
0065
0066 node_handle_base& operator=(node_handle_base&& nh) {
0067 internal_destroy();
0068 my_node = nh.my_node;
0069 typedef typename traits_type::propagate_on_container_move_assignment pocma_type;
0070 tbb::internal::allocator_move_assignment(my_allocator, nh.my_allocator, pocma_type());
0071 nh.deactivate();
0072 return *this;
0073 }
0074
0075 void swap(node_handle_base& nh) {
0076 std::swap(my_node, nh.my_node);
0077 typedef typename traits_type::propagate_on_container_swap pocs_type;
0078 tbb::internal::allocator_swap(my_allocator, nh.my_allocator, pocs_type());
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) {
0090 traits_type::destroy(my_allocator, my_node->storage());
0091 typename tbb::internal::allocator_rebind<allocator_type, node>::type node_allocator;
0092 node_allocator.deallocate(my_node, 1);
0093 }
0094 }
0095
0096 void deactivate() { my_node = NULL; }
0097
0098 node* my_node;
0099 allocator_type my_allocator;
0100 };
0101
0102
0103 template<typename Key, typename Value, typename Node, typename Allocator>
0104 class node_handle : public node_handle_base<Value, Node, Allocator> {
0105 typedef node_handle_base<Value, Node, Allocator> base_type;
0106 public:
0107 typedef Key key_type;
0108 typedef typename Value::second_type mapped_type;
0109 typedef typename base_type::allocator_type allocator_type;
0110
0111 node_handle() : base_type() {}
0112
0113 key_type& key() const {
0114 __TBB_ASSERT(!this->empty(), "Cannot get key from the empty node_type object");
0115 return *const_cast<key_type*>(&(this->my_node->value().first));
0116 }
0117
0118 mapped_type& mapped() const {
0119 __TBB_ASSERT(!this->empty(), "Cannot get mapped value from the empty node_type object");
0120 return this->my_node->value().second;
0121 }
0122
0123 private:
0124 template<typename T, typename A>
0125 friend class tbb::interface5::internal::split_ordered_list;
0126
0127 template<typename Traits>
0128 friend class tbb::interface5::internal::concurrent_unordered_base;
0129
0130 template<typename Traits>
0131 friend class tbb::interface10::internal::concurrent_skip_list;
0132
0133 node_handle(typename base_type::node* n) : base_type(n) {}
0134 };
0135
0136
0137 template<typename Key, typename Node, typename Allocator>
0138 class node_handle<Key, Key, Node, Allocator> : public node_handle_base<Key, Node, Allocator> {
0139 typedef node_handle_base<Key, Node, Allocator> base_type;
0140 public:
0141 typedef Key value_type;
0142 typedef typename base_type::allocator_type allocator_type;
0143
0144 node_handle() : base_type() {}
0145
0146 value_type& value() const {
0147 __TBB_ASSERT(!this->empty(), "Cannot get value from the empty node_type object");
0148 return *const_cast<value_type*>(&(this->my_node->value()));
0149 }
0150
0151 private:
0152 template<typename T, typename A>
0153 friend class tbb::interface5::internal::split_ordered_list;
0154
0155 template<typename Traits>
0156 friend class tbb::interface5::internal::concurrent_unordered_base;
0157
0158 template<typename Traits>
0159 friend class tbb::interface10::internal::concurrent_skip_list;
0160
0161 node_handle(typename base_type::node* n) : base_type(n) {}
0162 };
0163
0164
0165 }
0166 }
0167
0168 #endif