1 /* 2 Copyright (c) 2005-2021 Intel Corporation 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #ifndef __TBB_detail__allocator_traits_H 18 #define __TBB_detail__allocator_traits_H 19 20 #include "_config.h" 21 #include "_template_helpers.h" 22 #include <memory> 23 #include <type_traits> 24 25 namespace tbb { 26 namespace detail { 27 inline namespace d0 { 28 29 #if !__TBB_CPP17_ALLOCATOR_IS_ALWAYS_EQUAL_PRESENT 30 // Struct is_always_equal_detector provides the member type "type" which is 31 // Allocator::is_always_equal if it is present, std::false_type otherwise 32 template <typename Allocator, typename = void> 33 struct is_always_equal_detector { 34 using type = std::false_type; 35 }; 36 37 template <typename Allocator> 38 struct is_always_equal_detector<Allocator, tbb::detail::void_t<typename Allocator::is_always_equal>> 39 { 40 using type = typename Allocator::is_always_equal; 41 }; 42 #endif // !__TBB_CPP17_ALLOCATOR_IS_ALWAYS_EQUAL_PRESENT 43 44 template <typename Allocator> 45 class allocator_traits : public std::allocator_traits<Allocator> 46 { 47 using base_type = std::allocator_traits<Allocator>; 48 public: 49 #if !__TBB_CPP17_ALLOCATOR_IS_ALWAYS_EQUAL_PRESENT 50 using is_always_equal = typename is_always_equal_detector<Allocator>::type; 51 #endif 52 53 template <typename T> 54 using rebind_traits = typename tbb::detail::allocator_traits<typename base_type::template rebind_alloc<T>>; 55 }; // struct allocator_traits 56 57 template <typename Allocator> 58 void copy_assign_allocators_impl( Allocator& lhs, const Allocator& rhs, /*pocca = */std::true_type ) { 59 lhs = rhs; 60 } 61 62 template <typename Allocator> 63 void copy_assign_allocators_impl( Allocator&, const Allocator&, /*pocca = */ std::false_type ) {} 64 65 // Copy assigns allocators only if propagate_on_container_copy_assignment is true 66 template <typename Allocator> 67 void copy_assign_allocators( Allocator& lhs, const Allocator& rhs ) { 68 using pocca_type = typename allocator_traits<Allocator>::propagate_on_container_copy_assignment; 69 copy_assign_allocators_impl(lhs, rhs, pocca_type()); 70 } 71 72 template <typename Allocator> 73 void move_assign_allocators_impl( Allocator& lhs, Allocator& rhs, /*pocma = */ std::true_type ) { 74 lhs = std::move(rhs); 75 } 76 77 template <typename Allocator> 78 void move_assign_allocators_impl( Allocator&, Allocator&, /*pocma = */ std::false_type ) {} 79 80 // Move assigns allocators only if propagate_on_container_move_assignment is true 81 template <typename Allocator> 82 void move_assign_allocators( Allocator& lhs, Allocator& rhs ) { 83 using pocma_type = typename allocator_traits<Allocator>::propagate_on_container_move_assignment; 84 move_assign_allocators_impl(lhs, rhs, pocma_type()); 85 } 86 87 template <typename Allocator> 88 void swap_allocators_impl( Allocator& lhs, Allocator& rhs, /*pocs = */ std::true_type ) { 89 using std::swap; 90 swap(lhs, rhs); 91 } 92 93 template <typename Allocator> 94 void swap_allocators_impl( Allocator&, Allocator&, /*pocs = */ std::false_type ) {} 95 96 // Swaps allocators only if propagate_on_container_swap is true 97 template <typename Allocator> 98 void swap_allocators( Allocator& lhs, Allocator& rhs ) { 99 using pocs_type = typename allocator_traits<Allocator>::propagate_on_container_swap; 100 swap_allocators_impl(lhs, rhs, pocs_type()); 101 } 102 103 } // inline namespace d0 104 } // namespace detail 105 } // namespace tbb 106 107 #endif // __TBB_detail__allocator_traits_H 108