_allocator_traits.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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_allocator_traits_H
  14. #define __TBB_allocator_traits_H
  15. #include "../tbb_stddef.h" // true/false_type
  16. #if __TBB_ALLOCATOR_TRAITS_PRESENT
  17. #include <memory> // for allocator_traits
  18. #endif
  19. #if __TBB_CPP11_RVALUE_REF_PRESENT
  20. #include <utility> // for std::move
  21. #endif
  22. // For allocator_swap helper
  23. #include __TBB_STD_SWAP_HEADER
  24. namespace tbb {
  25. namespace internal {
  26. //! Internal implementation of allocator traits, propagate_on_* use internal boolean_constant.
  27. //! In order to avoid code duplication, check what implementation of boolean constant will likely be passed.
  28. #if __TBB_ALLOCATOR_TRAITS_PRESENT
  29. typedef std::true_type traits_true_type;
  30. typedef std::false_type traits_false_type;
  31. #else
  32. typedef tbb::internal::true_type traits_true_type;
  33. typedef tbb::internal::false_type traits_false_type;
  34. #endif
  35. //! Copy assignment implementation for allocator if propagate_on_container_copy_assignment == true_type
  36. //! Noop if pocca == false_type
  37. template <typename MyAlloc, typename OtherAlloc>
  38. inline void allocator_copy_assignment(MyAlloc& my_allocator, OtherAlloc& other_allocator, traits_true_type) {
  39. my_allocator = other_allocator;
  40. }
  41. template <typename MyAlloc, typename OtherAlloc>
  42. inline void allocator_copy_assignment(MyAlloc&, OtherAlloc&, traits_false_type) { /* NO COPY */}
  43. #if __TBB_CPP11_RVALUE_REF_PRESENT
  44. //! Move assignment implementation for allocator if propagate_on_container_move_assignment == true_type.
  45. //! Noop if pocma == false_type.
  46. template <typename MyAlloc, typename OtherAlloc>
  47. inline void allocator_move_assignment(MyAlloc& my_allocator, OtherAlloc& other_allocator, traits_true_type) {
  48. my_allocator = std::move(other_allocator);
  49. }
  50. template <typename MyAlloc, typename OtherAlloc>
  51. inline void allocator_move_assignment(MyAlloc&, OtherAlloc&, traits_false_type) { /* NO MOVE */ }
  52. #endif
  53. //! Swap implementation for allocators if propagate_on_container_swap == true_type.
  54. //! Noop if pocs == false_type.
  55. template <typename MyAlloc, typename OtherAlloc>
  56. inline void allocator_swap(MyAlloc& my_allocator, OtherAlloc& other_allocator, traits_true_type) {
  57. using std::swap;
  58. swap(my_allocator, other_allocator);
  59. }
  60. template <typename MyAlloc, typename OtherAlloc>
  61. inline void allocator_swap(MyAlloc&, OtherAlloc&, traits_false_type) { /* NO SWAP */ }
  62. #if __TBB_ALLOCATOR_TRAITS_PRESENT
  63. using std::allocator_traits;
  64. #else
  65. //! Internal allocator_traits implementation, which relies on C++03 standard
  66. //! [20.1.5] allocator requirements
  67. template<typename Alloc>
  68. struct allocator_traits {
  69. // C++03 allocator doesn't have to be assignable or swappable, therefore
  70. // define these traits as false_type to do not require additional operations
  71. // that are not supposed to be in.
  72. typedef tbb::internal::false_type propagate_on_container_move_assignment;
  73. typedef tbb::internal::false_type propagate_on_container_copy_assignment;
  74. typedef tbb::internal::false_type propagate_on_container_swap;
  75. typedef Alloc allocator_type;
  76. typedef typename allocator_type::value_type value_type;
  77. typedef typename allocator_type::pointer pointer;
  78. typedef typename allocator_type::const_pointer const_pointer;
  79. typedef typename allocator_type::difference_type difference_type;
  80. typedef typename allocator_type::size_type size_type;
  81. template <typename U> struct rebind_alloc {
  82. typedef typename Alloc::template rebind<U>::other other;
  83. };
  84. static pointer allocate(Alloc& a, size_type n) {
  85. return a.allocate(n);
  86. }
  87. static void deallocate(Alloc& a, pointer p, size_type n) {
  88. a.deallocate(p, n);
  89. }
  90. template<typename PT>
  91. static void construct(Alloc&, PT* p) {
  92. ::new (static_cast<void*>(p)) PT();
  93. }
  94. template<typename PT, typename T1>
  95. static void construct(Alloc&, PT* p, __TBB_FORWARDING_REF(T1) t1) {
  96. ::new (static_cast<void*>(p)) PT(tbb::internal::forward<T1>(t1));
  97. }
  98. template<typename PT, typename T1, typename T2>
  99. static void construct(Alloc&, PT* p, __TBB_FORWARDING_REF(T1) t1, __TBB_FORWARDING_REF(T2) t2) {
  100. ::new (static_cast<void*>(p)) PT(tbb::internal::forward<T1>(t1), tbb::internal::forward<T2>(t2));
  101. }
  102. template<typename PT, typename T1, typename T2, typename T3>
  103. static void construct(Alloc&, PT* p, __TBB_FORWARDING_REF(T1) t1,
  104. __TBB_FORWARDING_REF(T2) t2, __TBB_FORWARDING_REF(T3) t3) {
  105. ::new (static_cast<void*>(p)) PT(tbb::internal::forward<T1>(t1), tbb::internal::forward<T2>(t2),
  106. tbb::internal::forward<T3>(t3));
  107. }
  108. template<typename T>
  109. static void destroy(Alloc&, T* p) {
  110. p->~T();
  111. tbb::internal::suppress_unused_warning(p);
  112. }
  113. static Alloc select_on_container_copy_construction(const Alloc& a) { return a; }
  114. };
  115. #endif // __TBB_ALLOCATOR_TRAITS_PRESENT
  116. //! C++03/C++11 compliant rebind helper, even if no std::allocator_traits available
  117. //! or rebind is not defined for allocator type
  118. template<typename Alloc, typename T>
  119. struct allocator_rebind {
  120. #if __TBB_ALLOCATOR_TRAITS_PRESENT
  121. typedef typename allocator_traits<Alloc>::template rebind_alloc<T> type;
  122. #else
  123. typedef typename allocator_traits<Alloc>::template rebind_alloc<T>::other type;
  124. #endif
  125. };
  126. }} // namespace tbb::internal
  127. #endif // __TBB_allocator_traits_H