/** * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RUNTIME_MEM_ALLOCATOR_ADAPTER_H #define RUNTIME_MEM_ALLOCATOR_ADAPTER_H #include "runtime/include/mem/allocator.h" namespace panda::mem { template class AllocatorAdapter; template class AllocatorAdapter { public: using value_type = void; using pointer = void *; using const_pointer = const void *; template struct Rebind { using other = AllocatorAdapter; }; template using rebind = Rebind; explicit AllocatorAdapter(Allocator *allocator = InternalAllocator<>::GetInternalAllocatorFromRuntime()) : allocator_(allocator) { } template // NOLINTNEXTLINE(google-explicit-constructor) AllocatorAdapter(const AllocatorAdapter &other) : allocator_(other.allocator_) { } AllocatorAdapter(const AllocatorAdapter &) = default; AllocatorAdapter &operator=(const AllocatorAdapter &) = default; AllocatorAdapter(AllocatorAdapter &&other) noexcept { allocator_ = other.allocator_; other.allocator_ = nullptr; } AllocatorAdapter &operator=(AllocatorAdapter &&other) noexcept { allocator_ = other.allocator_; other.allocator_ = nullptr; return *this; } ~AllocatorAdapter() = default; private: Allocator *allocator_; template friend class AllocatorAdapter; }; template class AllocatorAdapter { public: using value_type = T; using pointer = T *; using reference = T &; using const_pointer = const T *; using const_reference = const T &; using size_type = size_t; using difference_type = ptrdiff_t; template struct Rebind { using other = AllocatorAdapter; }; template using rebind = Rebind; explicit AllocatorAdapter(Allocator *allocator = InternalAllocator<>::GetInternalAllocatorFromRuntime()) : allocator_(allocator) { } template // NOLINTNEXTLINE(google-explicit-constructor) AllocatorAdapter(const AllocatorAdapter &other) : allocator_(other.allocator_) { } AllocatorAdapter(const AllocatorAdapter &) = default; AllocatorAdapter &operator=(const AllocatorAdapter &) = default; AllocatorAdapter(AllocatorAdapter &&other) noexcept { allocator_ = other.allocator_; other.allocator_ = nullptr; } AllocatorAdapter &operator=(AllocatorAdapter &&other) noexcept { allocator_ = other.allocator_; other.allocator_ = nullptr; return *this; } ~AllocatorAdapter() = default; // NOLINTNEXTLINE(readability-identifier-naming) pointer allocate(size_type size, [[maybe_unused]] const void *hint = nullptr) { // NOLINTNEXTLINE(bugprone-suspicious-semicolon, readability-braces-around-statements) if constexpr (AllocScopeT == AllocScope::GLOBAL) { return allocator_->AllocArray(size); // NOLINTNEXTLINE(readability-misleading-indentation) } else { return allocator_->AllocArrayLocal(size); } } // NOLINTNEXTLINE(readability-identifier-naming) void deallocate(pointer ptr, [[maybe_unused]] size_type size) { allocator_->Free(ptr); } template void construct(U *ptr, Args &&... args) // NOLINT(readability-identifier-naming) { ::new (static_cast(ptr)) U(std::forward(args)...); } template void destroy(U *ptr) // NOLINT(readability-identifier-naming) { ptr->~U(); } template bool operator==(const AllocatorAdapter &other) const { return this->allocator_ == other.allocator_; } template bool operator!=(const AllocatorAdapter &other) const { return this->allocator_ != other.allocator_; } private: Allocator *allocator_; template friend class AllocatorAdapter; }; template inline AllocatorAdapter Allocator::Adapter() { return AllocatorAdapter(this); } } // namespace panda::mem #endif // RUNTIME_MEM_ALLOCATOR_ADAPTER_H