// SPDX-License-Identifier: Apache-2.0 #pragma once #include #include #include #include namespace tt { /** Allocator backed by tactility/memory.h's memory_alloc_with_policy(), with Required/Desired as * its required/desired MemoryCapability flags (bitwise-OR'd, e.g. MEMORY_CAPABILITY_EXTERNAL). */ template struct Allocator { using value_type = T; // libstdc++'s default rebind_alloc only pattern-matches allocator templates whose parameters // are all types, which Required/Desired (non-type) breaks; spelling it out here restores it. template struct rebind { using other = Allocator; }; Allocator() noexcept = default; template constexpr Allocator(const Allocator&) noexcept {} T* allocate(std::size_t n) { const MemoryPolicy policy { .required = Required, .desired = Desired, .alignment = alignof(T) }; void* ptr = memory_alloc_with_policy(n * sizeof(T), &policy); if (ptr == nullptr) { std::abort(); // Exceptions are disabled project-wide, so OOM can't be signalled via std::bad_alloc. } return static_cast(ptr); } void deallocate(T* ptr, std::size_t) noexcept { memory_free(ptr); } }; template bool operator==(const Allocator&, const Allocator&) noexcept { return true; } /** Prefers external memory, falling back to internal RAM when unavailable. */ template using OptExternalAllocator = Allocator; } // namespace tt