_node_handle_impl.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. Copyright (c) 2019-2020 Intel Corporation
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. #ifndef __TBB_node_handle_H
  14. #define __TBB_node_handle_H
  15. #include "_allocator_traits.h"
  16. #include "../tbb_config.h"
  17. namespace tbb {
  18. // This classes must be declared here for correct friendly relationship
  19. // TODO: Consider creation some internal class to access node_handle private fields without any friendly classes
  20. namespace interface5 {
  21. namespace internal {
  22. template <typename T, typename Allocator>
  23. class split_ordered_list;
  24. template <typename Traits>
  25. class concurrent_unordered_base;
  26. }
  27. }
  28. namespace interface10{
  29. namespace internal {
  30. template<typename Traits>
  31. class concurrent_skip_list;
  32. }
  33. }
  34. namespace internal {
  35. template<typename Value, typename Node, typename Allocator>
  36. class node_handle_base {
  37. public:
  38. typedef Allocator allocator_type;
  39. protected:
  40. typedef Node node;
  41. typedef tbb::internal::allocator_traits<allocator_type> traits_type;
  42. public:
  43. node_handle_base() : my_node(NULL), my_allocator() {}
  44. node_handle_base(node_handle_base&& nh) : my_node(nh.my_node),
  45. my_allocator(std::move(nh.my_allocator)) {
  46. nh.my_node = NULL;
  47. }
  48. bool empty() const { return my_node == NULL; }
  49. explicit operator bool() const { return my_node != NULL; }
  50. ~node_handle_base() { internal_destroy(); }
  51. node_handle_base& operator=(node_handle_base&& nh) {
  52. internal_destroy();
  53. my_node = nh.my_node;
  54. typedef typename traits_type::propagate_on_container_move_assignment pocma_type;
  55. tbb::internal::allocator_move_assignment(my_allocator, nh.my_allocator, pocma_type());
  56. nh.deactivate();
  57. return *this;
  58. }
  59. void swap(node_handle_base& nh) {
  60. std::swap(my_node, nh.my_node);
  61. typedef typename traits_type::propagate_on_container_swap pocs_type;
  62. tbb::internal::allocator_swap(my_allocator, nh.my_allocator, pocs_type());
  63. }
  64. allocator_type get_allocator() const {
  65. return my_allocator;
  66. }
  67. protected:
  68. node_handle_base(node* n) : my_node(n) {}
  69. void internal_destroy() {
  70. if(my_node) {
  71. traits_type::destroy(my_allocator, my_node->storage());
  72. typename tbb::internal::allocator_rebind<allocator_type, node>::type node_allocator;
  73. node_allocator.deallocate(my_node, 1);
  74. }
  75. }
  76. void deactivate() { my_node = NULL; }
  77. node* my_node;
  78. allocator_type my_allocator;
  79. };
  80. // node handle for maps
  81. template<typename Key, typename Value, typename Node, typename Allocator>
  82. class node_handle : public node_handle_base<Value, Node, Allocator> {
  83. typedef node_handle_base<Value, Node, Allocator> base_type;
  84. public:
  85. typedef Key key_type;
  86. typedef typename Value::second_type mapped_type;
  87. typedef typename base_type::allocator_type allocator_type;
  88. node_handle() : base_type() {}
  89. key_type& key() const {
  90. __TBB_ASSERT(!this->empty(), "Cannot get key from the empty node_type object");
  91. return *const_cast<key_type*>(&(this->my_node->value().first));
  92. }
  93. mapped_type& mapped() const {
  94. __TBB_ASSERT(!this->empty(), "Cannot get mapped value from the empty node_type object");
  95. return this->my_node->value().second;
  96. }
  97. private:
  98. template<typename T, typename A>
  99. friend class tbb::interface5::internal::split_ordered_list;
  100. template<typename Traits>
  101. friend class tbb::interface5::internal::concurrent_unordered_base;
  102. template<typename Traits>
  103. friend class tbb::interface10::internal::concurrent_skip_list;
  104. node_handle(typename base_type::node* n) : base_type(n) {}
  105. };
  106. // node handle for sets
  107. template<typename Key, typename Node, typename Allocator>
  108. class node_handle<Key, Key, Node, Allocator> : public node_handle_base<Key, Node, Allocator> {
  109. typedef node_handle_base<Key, Node, Allocator> base_type;
  110. public:
  111. typedef Key value_type;
  112. typedef typename base_type::allocator_type allocator_type;
  113. node_handle() : base_type() {}
  114. value_type& value() const {
  115. __TBB_ASSERT(!this->empty(), "Cannot get value from the empty node_type object");
  116. return *const_cast<value_type*>(&(this->my_node->value()));
  117. }
  118. private:
  119. template<typename T, typename A>
  120. friend class tbb::interface5::internal::split_ordered_list;
  121. template<typename Traits>
  122. friend class tbb::interface5::internal::concurrent_unordered_base;
  123. template<typename Traits>
  124. friend class tbb::interface10::internal::concurrent_skip_list;
  125. node_handle(typename base_type::node* n) : base_type(n) {}
  126. };
  127. }// namespace internal
  128. }// namespace tbb
  129. #endif /*__TBB_node_handle_H*/