94 lines
2.7 KiB
C++
94 lines
2.7 KiB
C++
#ifndef __JABYENGINE_LINKED_ELEMENTS_HPP__
|
|
#define __JABYENGINE_LINKED_ELEMENTS_HPP__
|
|
#include "../../Auxiliary/bits.hpp"
|
|
|
|
namespace JabyEngine {
|
|
namespace GPU {
|
|
struct Link {
|
|
static constexpr auto AdrRange = BitRange::from_to(0, 23);
|
|
static constexpr auto SizeRange = BitRange::from_to(24, 31);
|
|
|
|
static constexpr uint32_t TerminationValue = 0x00FFFFFF;
|
|
|
|
static constexpr uint32_t default_link_value(size_t size) {
|
|
return SizeRange.as_value(size >> 2) | TerminationValue;
|
|
}
|
|
|
|
uint32_t link_value;
|
|
|
|
constexpr void set_link_identitiy(size_t size) {
|
|
this->link_value = default_link_value(size);
|
|
}
|
|
|
|
void set_adr(const void* adr) {
|
|
this->link_value = bit::value::set_normalized(this->link_value, AdrRange.with(reinterpret_cast<uint32_t>(adr)));
|
|
}
|
|
|
|
void* get_adr() const {
|
|
return reinterpret_cast<void*>(bit::value::get_normalized(this->link_value, AdrRange));
|
|
}
|
|
|
|
template<typename T>
|
|
T& insert_after(T& obj) {
|
|
const auto adr = Link::get_adr();
|
|
|
|
Link::set_adr(&obj);
|
|
obj.set_adr(adr);
|
|
return obj;
|
|
}
|
|
|
|
template<typename T>
|
|
T& concat(T& obj) {
|
|
Link::set_adr(&obj);
|
|
return obj;
|
|
}
|
|
|
|
template<typename T>
|
|
const T& concat(const T& obj) {
|
|
return concat(const_cast<T&>(obj));
|
|
}
|
|
|
|
constexpr void terminate() {
|
|
this->link_value |= TerminationValue;
|
|
}
|
|
};
|
|
|
|
template<typename T>
|
|
struct LinkedElement : public Link {
|
|
T element;
|
|
|
|
static constexpr LinkedElement create(const T& element) {
|
|
LinkedElement new_element;
|
|
|
|
new_element.element = element;
|
|
new_element.set_link_identitiy();
|
|
return new_element;
|
|
}
|
|
|
|
constexpr void set_link_identitiy() {
|
|
Link::set_link_identitiy(sizeof(T));
|
|
}
|
|
|
|
constexpr const T* operator->() const {
|
|
return &this->element;
|
|
}
|
|
|
|
constexpr T* operator->() {
|
|
return &this->element;
|
|
}
|
|
};
|
|
|
|
namespace internal {
|
|
template<typename T>
|
|
struct LinkedElementCreator {
|
|
typedef LinkedElement<T> Linked;
|
|
|
|
constexpr LinkedElement<T> linked() {
|
|
return LinkedElement<T>::create(*static_cast<T*>(this));
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // !__JABYENGINE_LINKED_ELEMENTS_HPP__
|