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 void* __TBB_EXPORTED_FUNC allocate_memory(std::size_t size); 34 void __TBB_EXPORTED_FUNC deallocate_memory(void* p); 35 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(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