| 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 | |