#pragma once #include "utils/Rc.hpp" #include #include #include #include #include #include #include namespace orbis { inline namespace utils { void *kalloc(std::size_t size, std::size_t align); void kfree(void *ptr, std::size_t size); template struct kallocator { using value_type = T; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using propagate_on_container_move_assignment = std::true_type; constexpr kallocator() = default; template constexpr kallocator(const kallocator &) noexcept {} template struct rebind { using other = kallocator; }; T *allocate(std::size_t n) { return static_cast(kalloc(sizeof(T) * n, alignof(T))); } void deallocate(T *p, std::size_t n) { kfree(p, sizeof(T) * n); } template friend constexpr bool operator==(const kallocator &, const kallocator &) noexcept { return true; } }; using kstring = std::basic_string, kallocator>; template using kvector = std::vector>; template using kdeque = std::deque>; template > using kmap = std::map>>; template > using kmultimap = std::multimap>>; template , typename Pred = std::equal_to> using kunmap = std::unordered_map>>; } // namespace utils template requires(std::is_constructible_v) T *knew(Args &&...args) { auto loc = static_cast(utils::kalloc(sizeof(T), alignof(T))); auto res = std::construct_at(loc, std::forward(args)...); if constexpr (requires(T *t) { t->_total_size = sizeof(T); }) res->_total_size = sizeof(T); return res; } // clang-format off template void kdelete(T *ptr) { auto total_size = sizeof(T); if constexpr (requires(T *t) { t->_total_size = sizeof(T); }) total_size = ptr->_total_size; else static_assert(std::is_final_v, "Uncertain type size"); ptr->~T(); utils::kfree(ptr, total_size); } // clang-format on } // namespace orbis