rpcsx/orbis-kernel/include/orbis/KernelAllocator.hpp

79 lines
2.4 KiB
C++

#pragma once
#include "utils/Rc.hpp"
#include <deque>
#include <map>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
namespace orbis {
inline namespace utils {
void *kalloc(std::size_t size, std::size_t align);
void kfree(void *ptr, std::size_t size);
template <typename T> 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 <typename U> constexpr kallocator(const kallocator<U> &) noexcept {}
template <typename U> struct rebind {
using other = kallocator<U>;
};
T *allocate(std::size_t n) {
return static_cast<T *>(kalloc(sizeof(T) * n, alignof(T)));
}
void deallocate(T *p, std::size_t n) { kfree(p, sizeof(T) * n); }
template <typename U>
friend constexpr bool operator==(const kallocator &,
const kallocator<U> &) noexcept {
return true;
}
};
using kstring =
std::basic_string<char, std::char_traits<char>, kallocator<char>>;
template <typename T> using kvector = std::vector<T, kallocator<T>>;
template <typename T> using kdeque = std::deque<T, kallocator<T>>;
template <typename K, typename T, typename Cmp = std::less<>>
using kmap = std::map<K, T, Cmp, kallocator<std::pair<const K, T>>>;
template <typename K, typename T, typename Cmp = std::less<>>
using kmultimap = std::multimap<K, T, Cmp, kallocator<std::pair<const K, T>>>;
template <typename K, typename T, typename Hash = std::hash<K>,
typename Pred = std::equal_to<K>>
using kunmap =
std::unordered_map<K, T, Hash, Pred, kallocator<std::pair<const K, T>>>;
} // namespace utils
template <typename T, typename... Args>
requires(std::is_constructible_v<T, Args...>)
T *knew(Args &&...args) {
auto loc = static_cast<T *>(utils::kalloc(sizeof(T), alignof(T)));
auto res = std::construct_at(loc, std::forward<Args>(args)...);
if constexpr (requires(T *t) { t->_total_size = sizeof(T); })
res->_total_size = sizeof(T);
return res;
}
// clang-format off
template <typename T> 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<T>, "Uncertain type size");
ptr->~T();
utils::kfree(ptr, total_size);
}
// clang-format on
} // namespace orbis