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