xref: /oneTBB/include/oneapi/tbb/tbb_allocator.h (revision 8827ea7d)
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;
tbb_allocator(const tbb_allocator<U> &)56     template<typename U> tbb_allocator(const tbb_allocator<U>&) noexcept {}
57 
58     //! Allocate space for n objects.
allocate(std::size_t n)59     __TBB_nodiscard T* allocate(std::size_t n) {
60         return static_cast<T*>(r1::allocate_memory(n * sizeof(value_type)));
61     }
62 
63     //! Free previously allocated block of memory.
deallocate(T * p,std::size_t)64     void deallocate(T* p, std::size_t) {
65         r1::deallocate_memory(p);
66     }
67 
68     //! Returns current allocator
allocator_type()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.
max_size()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>
construct(U * p,Args &&...args)89     void construct(U *p, Args&&... args)
90         { ::new (p) U(std::forward<Args>(args)...); }
destroy(pointer p)91     void destroy( pointer p ) { p->~value_type(); }
address(reference x)92     pointer address(reference x) const { return &x; }
address(const_reference 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