+130
-20
@@ -19,10 +19,10 @@ enum class thing_t : std::uint8_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns data size of a thing.
|
* @brief Returns how many bytes a thing would take up.
|
||||||
*
|
*
|
||||||
* @param type Type of the thing.
|
* @param type Type of the thing.
|
||||||
* @return The data size of the thing.
|
* @return The byte count.
|
||||||
*/
|
*/
|
||||||
static inline std::size_t thing_type_size(thing_t type) {
|
static inline std::size_t thing_type_size(thing_t type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -35,13 +35,22 @@ template <template <typename> typename Allocator>
|
|||||||
class thing final {
|
class thing final {
|
||||||
friend class executor;
|
friend class executor;
|
||||||
public:
|
public:
|
||||||
using allocator_type = Allocator<std::byte>;
|
using allocator_type = Allocator<std::byte>; /**< Allocator type. */
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructs a thing.
|
||||||
|
*
|
||||||
|
* @param type Type of the thing.
|
||||||
|
* @param allocator Allocator for the thing's data.
|
||||||
|
*/
|
||||||
thing(thing_t type, const allocator_type& allocator = {})
|
thing(thing_t type, const allocator_type& allocator = {})
|
||||||
: m_type(type), m_allocator(allocator) {
|
: m_type(type), m_allocator(allocator) {
|
||||||
m_data = m_allocator.allocate(thing_type_size(type));
|
m_data = m_allocator.allocate(thing_type_size(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destructs a thing.
|
||||||
|
*/
|
||||||
~thing() {
|
~thing() {
|
||||||
if (m_data != nullptr) m_allocator.deallocate(m_data, thing_type_size(thing_t::Int32));
|
if (m_data != nullptr) m_allocator.deallocate(m_data, thing_type_size(thing_t::Int32));
|
||||||
}
|
}
|
||||||
@@ -74,8 +83,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Returns a clone of the thing.
|
* @brief Returns a clone of the thing.
|
||||||
*
|
*
|
||||||
* @param thing Thing to clone.
|
* @return A clone of this thing.
|
||||||
* @return Shared pointer to a clone of the thing.
|
|
||||||
*/
|
*/
|
||||||
thing clone() const {
|
thing clone() const {
|
||||||
class thing res(m_type, m_allocator);
|
class thing res(m_type, m_allocator);
|
||||||
@@ -88,7 +96,7 @@ public:
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Returns an int32 value from this thing.
|
* @brief Returns the thing's int32 value.
|
||||||
*
|
*
|
||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
@@ -98,7 +106,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns an int32 value from this thing.
|
* @brief Returns the thing's int32 value.
|
||||||
*
|
*
|
||||||
* @return The value.
|
* @return The value.
|
||||||
*/
|
*/
|
||||||
@@ -107,66 +115,132 @@ public:
|
|||||||
return *reinterpret_cast<std::int32_t*>(m_data);
|
return *reinterpret_cast<std::int32_t*>(m_data);
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Returns a sum of two things.
|
||||||
|
*
|
||||||
|
* @param rhs Thing to sum with this thing (right-hand-side).
|
||||||
|
* @return The sum.
|
||||||
|
*/
|
||||||
thing add(const thing& rhs) const {
|
thing add(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() + rhs.int32();
|
res.int32() = int32() + rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a difference of two things.
|
||||||
|
*
|
||||||
|
* @param rhs Thing to subtract from this thing (right-hand-side).
|
||||||
|
* @return The sum.
|
||||||
|
*/
|
||||||
thing sub(const thing& rhs) const {
|
thing sub(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() - rhs.int32();
|
res.int32() = int32() - rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a product of two things.
|
||||||
|
*
|
||||||
|
* @param rhs Thing to multiply with this thing (right-hand-side).
|
||||||
|
* @return The product.
|
||||||
|
*/
|
||||||
thing mul(const thing& rhs) const {
|
thing mul(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() * rhs.int32();
|
res.int32() = int32() * rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a quotient of two things.
|
||||||
|
*
|
||||||
|
* @param rhs Thing to divide this thing by (right-hand-side).
|
||||||
|
* @return The quotient.
|
||||||
|
*/
|
||||||
thing div(const thing& rhs) const {
|
thing div(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() / rhs.int32();
|
res.int32() = int32() / rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a remainder of two things.
|
||||||
|
*
|
||||||
|
* @param rhs Thing to divide this thing by (right-hand-side).
|
||||||
|
* @return The remainder.
|
||||||
|
*/
|
||||||
thing mod(const thing& rhs) const {
|
thing mod(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() % rhs.int32();
|
res.int32() = int32() % rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares two things for equality.
|
||||||
|
*
|
||||||
|
* @param rhs Thing to compare this thing with (right-hand-side).
|
||||||
|
* @return A boolean result of the comparison in a thing form.
|
||||||
|
*/
|
||||||
thing equals(const thing& rhs) const {
|
thing equals(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() == rhs.int32();
|
res.int32() = int32() == rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares two things for inequality.
|
||||||
|
*
|
||||||
|
* @param rhs Thing to compare this thing with (right-hand-side).
|
||||||
|
* @return A boolean result of the comparison in a thing form.
|
||||||
|
*/
|
||||||
thing not_equals(const thing& rhs) const {
|
thing not_equals(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() != rhs.int32();
|
res.int32() = int32() != rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares if this thing is less than an another thing.
|
||||||
|
*
|
||||||
|
* @param rhs The another thing.
|
||||||
|
* @return A boolean result of the comparison in a thing form.
|
||||||
|
*/
|
||||||
thing less_than(const thing& rhs) const {
|
thing less_than(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() < rhs.int32();
|
res.int32() = int32() < rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares if this thing is greater than an another thing.
|
||||||
|
*
|
||||||
|
* @param rhs The another thing.
|
||||||
|
* @return A boolean result of the comparison in a thing form.
|
||||||
|
*/
|
||||||
thing greater_than(const thing& rhs) const {
|
thing greater_than(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() > rhs.int32();
|
res.int32() = int32() > rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares if this thing is less than or equal to an another thing.
|
||||||
|
*
|
||||||
|
* @param rhs The another thing.
|
||||||
|
* @return A boolean result of the comparison in a thing form.
|
||||||
|
*/
|
||||||
thing less_equals(const thing& rhs) const {
|
thing less_equals(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() <= rhs.int32();
|
res.int32() = int32() <= rhs.int32();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares if this thing is greater than or equal to an another thing.
|
||||||
|
*
|
||||||
|
* @param rhs The another thing.
|
||||||
|
* @return A boolean result of the comparison in a thing form.
|
||||||
|
*/
|
||||||
thing greater_equals(const thing& rhs) const {
|
thing greater_equals(const thing& rhs) const {
|
||||||
thing res(m_type, m_allocator);
|
thing res(m_type, m_allocator);
|
||||||
res.int32() = int32() >= rhs.int32();
|
res.int32() = int32() >= rhs.int32();
|
||||||
@@ -186,27 +260,26 @@ class thing_allocator {
|
|||||||
|
|
||||||
using dead_things = std::vector<std::pair<T*, std::size_t>>;
|
using dead_things = std::vector<std::pair<T*, std::size_t>>;
|
||||||
public:
|
public:
|
||||||
using value_type = T;
|
using value_type = T; /**< Value type. */
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructs a thing allocator.
|
||||||
|
*
|
||||||
|
* @param arena Base arena allocator.
|
||||||
|
*/
|
||||||
explicit thing_allocator(furlang::arena& arena) noexcept
|
explicit thing_allocator(furlang::arena& arena) noexcept
|
||||||
: m_arena(&arena), m_deadThings(std::make_shared<dead_things>()) {}
|
: m_arena(&arena), m_deadThings(std::make_shared<dead_things>()) {}
|
||||||
|
|
||||||
template <typename U>
|
/**
|
||||||
thing_allocator(const thing_allocator<U>& other) noexcept
|
* @brief Move constructor.
|
||||||
: m_arena(other.m_arena), m_deadThings(other.m_deadThings) {}
|
*/
|
||||||
|
|
||||||
template <typename U>
|
|
||||||
thing_allocator& operator=(const thing_allocator<U>& other) noexcept {
|
|
||||||
if (this == &other) return *this;
|
|
||||||
m_arena = other.m_arena;
|
|
||||||
m_deadThings = other.m_deadThings;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
thing_allocator(thing_allocator<U>&& other) noexcept
|
thing_allocator(thing_allocator<U>&& other) noexcept
|
||||||
: m_arena(std::move(other.m_arena)), m_deadThings(std::move(other.m_deadThings)) {}
|
: m_arena(std::move(other.m_arena)), m_deadThings(std::move(other.m_deadThings)) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move constructor.
|
||||||
|
*/
|
||||||
template <typename U>
|
template <typename U>
|
||||||
thing_allocator& operator=(thing_allocator<U>&& other) noexcept {
|
thing_allocator& operator=(thing_allocator<U>&& other) noexcept {
|
||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
@@ -214,7 +287,31 @@ public:
|
|||||||
m_deadThings = std::move(other.m_deadThings);
|
m_deadThings = std::move(other.m_deadThings);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy constructor.
|
||||||
|
*/
|
||||||
|
template <typename U>
|
||||||
|
thing_allocator(const thing_allocator<U>& other) noexcept
|
||||||
|
: m_arena(other.m_arena), m_deadThings(other.m_deadThings) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy constructor.
|
||||||
|
*/
|
||||||
|
template <typename U>
|
||||||
|
thing_allocator& operator=(const thing_allocator<U>& other) noexcept {
|
||||||
|
if (this == &other) return *this;
|
||||||
|
m_arena = other.m_arena;
|
||||||
|
m_deadThings = other.m_deadThings;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Returns a free chunk of memory.
|
||||||
|
*
|
||||||
|
* @param count Count of the things that must fit inside the chunk.
|
||||||
|
* @return The chunk.
|
||||||
|
*/
|
||||||
[[nodiscard]] T* allocate(std::size_t count = 1) {
|
[[nodiscard]] T* allocate(std::size_t count = 1) {
|
||||||
for (auto it = m_deadThings->begin(); it != m_deadThings->end(); ++it) {
|
for (auto it = m_deadThings->begin(); it != m_deadThings->end(); ++it) {
|
||||||
if (it->second != count) continue;
|
if (it->second != count) continue;
|
||||||
@@ -224,13 +321,26 @@ public:
|
|||||||
return m_arena->allocate<T>(count);
|
return m_arena->allocate<T>(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Recycles the pointer.
|
||||||
|
*/
|
||||||
void deallocate(T* ptr, std::size_t count) noexcept { m_deadThings->emplace_back(ptr, count); }
|
void deallocate(T* ptr, std::size_t count) noexcept { m_deadThings->emplace_back(ptr, count); }
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Compares two thing allocators for equality.
|
||||||
|
*
|
||||||
|
* @return true if the two things are equal.
|
||||||
|
*/
|
||||||
template <typename U>
|
template <typename U>
|
||||||
bool operator==(const thing_allocator<U>& other) const noexcept {
|
bool operator==(const thing_allocator<U>& other) const noexcept {
|
||||||
return m_arena == other.m_arena && m_deadThings == other.m_deadThings;
|
return m_arena == other.m_arena && m_deadThings == other.m_deadThings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compares two thing allocators for inequality.
|
||||||
|
*
|
||||||
|
* @return true if the two things are not equal.
|
||||||
|
*/
|
||||||
template <typename U>
|
template <typename U>
|
||||||
bool operator!=(const thing_allocator<U>& other) const noexcept {
|
bool operator!=(const thing_allocator<U>& other) const noexcept {
|
||||||
return m_arena != other.m_arena || m_deadThings != other.m_deadThings;
|
return m_arena != other.m_arena || m_deadThings != other.m_deadThings;
|
||||||
|
|||||||
Reference in New Issue
Block a user