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_tbb_allocator_H |
18 | #define __TBB_tbb_allocator_H |
19 | |
20 | #include "oneapi/tbb/detail/_utils.h" |
21 | #include "detail/_namespace_injection.h" |
22 | #include <cstdlib> |
23 | #include <utility> |
24 | |
25 | #if __TBB_CPP17_MEMORY_RESOURCE_PRESENT |
26 | #include <memory_resource> |
27 | #endif |
28 | |
29 | namespace tbb { |
30 | namespace detail { |
31 | |
32 | namespace r1 { |
33 | TBB_EXPORT void* __TBB_EXPORTED_FUNC allocate_memory(std::size_t size); |
34 | TBB_EXPORT void __TBB_EXPORTED_FUNC deallocate_memory(void* p); |
35 | TBB_EXPORT bool __TBB_EXPORTED_FUNC is_tbbmalloc_used(); |
36 | } |
37 | |
38 | namespace d1 { |
39 | |
40 | template<typename T> |
41 | class tbb_allocator { |
42 | public: |
43 | using value_type = T; |
44 | using propagate_on_container_move_assignment = std::true_type; |
45 | |
46 | //! Always defined for TBB containers (supported since C++17 for std containers) |
47 | using is_always_equal = std::true_type; |
48 | |
49 | //! Specifies current allocator |
50 | enum malloc_type { |
51 | scalable, |
52 | standard |
53 | }; |
54 | |
55 | tbb_allocator() = default; |
56 | template<typename U> tbb_allocator(const tbb_allocator<U>&) noexcept {} |
57 | |
58 | //! Allocate space for n objects. |
59 | __TBB_nodiscard T* allocate(std::size_t n) { |
60 | return static_cast<T*>(r1::allocate_memory(size: n * sizeof(value_type))); |
61 | } |
62 | |
63 | //! Free previously allocated block of memory. |
64 | void deallocate(T* p, std::size_t) { |
65 | r1::deallocate_memory(p); |
66 | } |
67 | |
68 | //! Returns current allocator |
69 | static malloc_type allocator_type() { |
70 | return r1::is_tbbmalloc_used() ? standard : scalable; |
71 | } |
72 | |
73 | #if TBB_ALLOCATOR_TRAITS_BROKEN |
74 | using pointer = value_type*; |
75 | using const_pointer = const value_type*; |
76 | using reference = value_type&; |
77 | using const_reference = const value_type&; |
78 | using difference_type = std::ptrdiff_t; |
79 | using size_type = std::size_t; |
80 | template<typename U> struct rebind { |
81 | using other = tbb_allocator<U>; |
82 | }; |
83 | //! Largest value for which method allocate might succeed. |
84 | size_type max_size() const noexcept { |
85 | size_type max = ~(std::size_t(0)) / sizeof(value_type); |
86 | return (max > 0 ? max : 1); |
87 | } |
88 | template<typename U, typename... Args> |
89 | void construct(U *p, Args&&... args) |
90 | { ::new (p) U(std::forward<Args>(args)...); } |
91 | void destroy( pointer p ) { p->~value_type(); } |
92 | pointer address(reference x) const { return &x; } |
93 | const_pointer address(const_reference x) const { return &x; } |
94 | #endif // TBB_ALLOCATOR_TRAITS_BROKEN |
95 | }; |
96 | |
97 | #if TBB_ALLOCATOR_TRAITS_BROKEN |
98 | template<> |
99 | class tbb_allocator<void> { |
100 | public: |
101 | using pointer = void*; |
102 | using const_pointer = const void*; |
103 | using value_type = void; |
104 | template<typename U> struct rebind { |
105 | using other = tbb_allocator<U>; |
106 | }; |
107 | }; |
108 | #endif |
109 | |
110 | template<typename T, typename U> |
111 | inline bool operator==(const tbb_allocator<T>&, const tbb_allocator<U>&) noexcept { return true; } |
112 | |
113 | #if !__TBB_CPP20_COMPARISONS_PRESENT |
114 | template<typename T, typename U> |
115 | inline bool operator!=(const tbb_allocator<T>&, const tbb_allocator<U>&) noexcept { return false; } |
116 | #endif |
117 | |
118 | } // namespace d1 |
119 | } // namespace detail |
120 | |
121 | inline namespace v1 { |
122 | using detail::d1::tbb_allocator; |
123 | } // namespace v1 |
124 | } // namespace tbb |
125 | |
126 | #endif /* __TBB_tbb_allocator_H */ |
127 | |