xref: /oneTBB/include/oneapi/tbb/tbb_allocator.h (revision 8827ea7d)
149e08aacStbbdev /*
2b15aabb3Stbbdev     Copyright (c) 2005-2021 Intel Corporation
349e08aacStbbdev 
449e08aacStbbdev     Licensed under the Apache License, Version 2.0 (the "License");
549e08aacStbbdev     you may not use this file except in compliance with the License.
649e08aacStbbdev     You may obtain a copy of the License at
749e08aacStbbdev 
849e08aacStbbdev         http://www.apache.org/licenses/LICENSE-2.0
949e08aacStbbdev 
1049e08aacStbbdev     Unless required by applicable law or agreed to in writing, software
1149e08aacStbbdev     distributed under the License is distributed on an "AS IS" BASIS,
1249e08aacStbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349e08aacStbbdev     See the License for the specific language governing permissions and
1449e08aacStbbdev     limitations under the License.
1549e08aacStbbdev */
1649e08aacStbbdev 
1749e08aacStbbdev #ifndef __TBB_tbb_allocator_H
1849e08aacStbbdev #define __TBB_tbb_allocator_H
1949e08aacStbbdev 
2049e08aacStbbdev #include "oneapi/tbb/detail/_utils.h"
2149e08aacStbbdev #include "detail/_namespace_injection.h"
2249e08aacStbbdev #include <cstdlib>
2349e08aacStbbdev #include <utility>
2449e08aacStbbdev 
2549e08aacStbbdev #if __TBB_CPP17_MEMORY_RESOURCE_PRESENT
2649e08aacStbbdev #include <memory_resource>
2749e08aacStbbdev #endif
2849e08aacStbbdev 
2949e08aacStbbdev namespace tbb {
3049e08aacStbbdev namespace detail {
3149e08aacStbbdev 
3249e08aacStbbdev namespace r1 {
33*8827ea7dSLong Nguyen TBB_EXPORT void* __TBB_EXPORTED_FUNC allocate_memory(std::size_t size);
34*8827ea7dSLong Nguyen TBB_EXPORT void  __TBB_EXPORTED_FUNC deallocate_memory(void* p);
35*8827ea7dSLong Nguyen TBB_EXPORT bool  __TBB_EXPORTED_FUNC is_tbbmalloc_used();
3649e08aacStbbdev }
3749e08aacStbbdev 
3849e08aacStbbdev namespace d1 {
3949e08aacStbbdev 
4049e08aacStbbdev template<typename T>
4149e08aacStbbdev class tbb_allocator {
4249e08aacStbbdev public:
4349e08aacStbbdev     using value_type = T;
4449e08aacStbbdev     using propagate_on_container_move_assignment = std::true_type;
4549e08aacStbbdev 
4649e08aacStbbdev     //! Always defined for TBB containers (supported since C++17 for std containers)
4749e08aacStbbdev     using is_always_equal = std::true_type;
4849e08aacStbbdev 
4949e08aacStbbdev     //! Specifies current allocator
5049e08aacStbbdev     enum malloc_type {
5149e08aacStbbdev         scalable,
5249e08aacStbbdev         standard
5349e08aacStbbdev     };
5449e08aacStbbdev 
5549e08aacStbbdev     tbb_allocator() = default;
tbb_allocator(const tbb_allocator<U> &)5649e08aacStbbdev     template<typename U> tbb_allocator(const tbb_allocator<U>&) noexcept {}
5749e08aacStbbdev 
5849e08aacStbbdev     //! Allocate space for n objects.
allocate(std::size_t n)59b15aabb3Stbbdev     __TBB_nodiscard T* allocate(std::size_t n) {
6049e08aacStbbdev         return static_cast<T*>(r1::allocate_memory(n * sizeof(value_type)));
6149e08aacStbbdev     }
6249e08aacStbbdev 
6349e08aacStbbdev     //! Free previously allocated block of memory.
deallocate(T * p,std::size_t)6449e08aacStbbdev     void deallocate(T* p, std::size_t) {
6549e08aacStbbdev         r1::deallocate_memory(p);
6649e08aacStbbdev     }
6749e08aacStbbdev 
6849e08aacStbbdev     //! Returns current allocator
allocator_type()6949e08aacStbbdev     static malloc_type allocator_type() {
7049e08aacStbbdev         return r1::is_tbbmalloc_used() ? standard : scalable;
7149e08aacStbbdev     }
7249e08aacStbbdev 
7349e08aacStbbdev #if TBB_ALLOCATOR_TRAITS_BROKEN
7449e08aacStbbdev     using pointer = value_type*;
7549e08aacStbbdev     using const_pointer = const value_type*;
7649e08aacStbbdev     using reference = value_type&;
7749e08aacStbbdev     using const_reference = const value_type&;
7849e08aacStbbdev     using difference_type = std::ptrdiff_t;
7949e08aacStbbdev     using size_type = std::size_t;
8049e08aacStbbdev     template<typename U> struct rebind {
8149e08aacStbbdev         using other = tbb_allocator<U>;
8249e08aacStbbdev     };
8349e08aacStbbdev     //! Largest value for which method allocate might succeed.
max_size()8449e08aacStbbdev     size_type max_size() const noexcept {
8549e08aacStbbdev         size_type max = ~(std::size_t(0)) / sizeof(value_type);
8649e08aacStbbdev         return (max > 0 ? max : 1);
8749e08aacStbbdev     }
8849e08aacStbbdev     template<typename U, typename... Args>
construct(U * p,Args &&...args)8949e08aacStbbdev     void construct(U *p, Args&&... args)
9049e08aacStbbdev         { ::new (p) U(std::forward<Args>(args)...); }
destroy(pointer p)9149e08aacStbbdev     void destroy( pointer p ) { p->~value_type(); }
address(reference x)9249e08aacStbbdev     pointer address(reference x) const { return &x; }
address(const_reference x)9349e08aacStbbdev     const_pointer address(const_reference x) const { return &x; }
9449e08aacStbbdev #endif // TBB_ALLOCATOR_TRAITS_BROKEN
9549e08aacStbbdev };
9649e08aacStbbdev 
9749e08aacStbbdev #if TBB_ALLOCATOR_TRAITS_BROKEN
9849e08aacStbbdev     template<>
9949e08aacStbbdev     class tbb_allocator<void> {
10049e08aacStbbdev     public:
10149e08aacStbbdev         using pointer = void*;
10249e08aacStbbdev         using const_pointer = const void*;
10349e08aacStbbdev         using value_type = void;
10449e08aacStbbdev         template<typename U> struct rebind {
10549e08aacStbbdev             using other = tbb_allocator<U>;
10649e08aacStbbdev         };
10749e08aacStbbdev     };
10849e08aacStbbdev #endif
10949e08aacStbbdev 
11049e08aacStbbdev template<typename T, typename U>
11149e08aacStbbdev inline bool operator==(const tbb_allocator<T>&, const tbb_allocator<U>&) noexcept { return true; }
11249e08aacStbbdev 
113b15aabb3Stbbdev #if !__TBB_CPP20_COMPARISONS_PRESENT
11449e08aacStbbdev template<typename T, typename U>
11549e08aacStbbdev inline bool operator!=(const tbb_allocator<T>&, const tbb_allocator<U>&) noexcept { return false; }
116b15aabb3Stbbdev #endif
11749e08aacStbbdev 
11849e08aacStbbdev } // namespace d1
11949e08aacStbbdev } // namespace detail
12049e08aacStbbdev 
12149e08aacStbbdev inline namespace v1 {
12249e08aacStbbdev using detail::d1::tbb_allocator;
12349e08aacStbbdev } // namespace v1
12449e08aacStbbdev } // namespace tbb
12549e08aacStbbdev 
12649e08aacStbbdev #endif /* __TBB_tbb_allocator_H */
127