[ox/fs/ptrarith] Make everything in ptrarith noexcept

This commit is contained in:
Gary Talent 2021-04-18 14:33:06 -05:00
parent 5ad7c963b1
commit 9d74c5b464
2 changed files with 110 additions and 99 deletions

View File

@ -34,45 +34,48 @@ class OX_PACKED NodeBuffer {
size_t m_it = 0; size_t m_it = 0;
public: public:
Iterator(NodeBuffer *buffer, ItemPtr current) { Iterator(NodeBuffer *buffer, ItemPtr current) noexcept {
m_buffer = buffer; m_buffer = buffer;
m_current = current; m_current = current;
oxTrace("ox::ptrarith::Iterator::start") << current.offset(); oxTrace("ox::ptrarith::Iterator::start") << current.offset();
} }
operator const Item*() const { operator const Item*() const noexcept {
return m_current; return m_current;
} }
ItemPtr ptr() { ItemPtr ptr() noexcept {
return m_current; return m_current;
} }
Item *get() { [[nodiscard]]
Item *get() noexcept {
return m_current; return m_current;
} }
operator ItemPtr() { operator ItemPtr() noexcept {
return m_current; return m_current;
} }
operator Item*() { operator Item*() noexcept {
return m_current; return m_current;
} }
const Item *operator->() const { const Item *operator->() const noexcept {
return m_current; return m_current;
} }
Item *operator->() { Item *operator->() noexcept {
return m_current; return m_current;
} }
[[nodiscard]] bool valid() const noexcept { [[nodiscard]]
bool valid() const noexcept {
return m_current.valid(); return m_current.valid();
} }
bool hasNext() { [[nodiscard]]
bool hasNext() noexcept {
if (m_current.valid()) { if (m_current.valid()) {
oxTrace("ox::ptrarith::NodeBuffer::Iterator::hasNext::current") << m_current.offset(); oxTrace("ox::ptrarith::NodeBuffer::Iterator::hasNext::current") << m_current.offset();
auto next = m_buffer->next(m_current); auto next = m_buffer->next(m_current);
@ -81,7 +84,7 @@ class OX_PACKED NodeBuffer {
return false; return false;
} }
void next() { void next() noexcept {
oxTrace("ox::ptrarith::NodeBuffer::Iterator::next") << m_it++; oxTrace("ox::ptrarith::NodeBuffer::Iterator::next") << m_it++;
if (hasNext()) { if (hasNext()) {
m_current = m_buffer->next(m_current); m_current = m_buffer->next(m_current);
@ -94,76 +97,83 @@ class OX_PACKED NodeBuffer {
Header m_header; Header m_header;
public: public:
NodeBuffer(); NodeBuffer() noexcept;
NodeBuffer(const NodeBuffer &other, size_t size); NodeBuffer(const NodeBuffer &other, size_t size) noexcept;
explicit NodeBuffer(size_t size); explicit NodeBuffer(size_t size) noexcept;
const Iterator iterator() const; [[nodiscard]]
const Iterator iterator() const noexcept;
Iterator iterator(); [[nodiscard]]
Iterator iterator() noexcept;
ItemPtr firstItem(); ItemPtr firstItem() noexcept;
ItemPtr lastItem(); ItemPtr lastItem() noexcept;
/** /**
* @return the data section of the given item * @return the data section of the given item
*/ */
template<typename T> template<typename T>
Ptr<T, size_t, sizeof(Item)> dataOf(ItemPtr); Ptr<T, size_t, sizeof(Item)> dataOf(ItemPtr) noexcept;
[[nodiscard]] ItemPtr prev(Item *item); ItemPtr prev(Item *item) noexcept;
[[nodiscard]] ItemPtr next(Item *item); ItemPtr next(Item *item) noexcept;
/** /**
* Like pointer but omits checks that assume the memory at the offset has * Like pointer but omits checks that assume the memory at the offset has
* already been initialed as an Item. * already been initialed as an Item.
*/ */
[[nodiscard]] ItemPtr uninitializedPtr(size_t offset); ItemPtr uninitializedPtr(size_t offset) noexcept;
[[nodiscard]] ItemPtr ptr(size_t offset); ItemPtr ptr(size_t offset) noexcept;
[[nodiscard]] ItemPtr malloc(size_t size); ItemPtr malloc(size_t size) noexcept;
Error free(ItemPtr item); Error free(ItemPtr item) noexcept;
[[nodiscard]] bool valid(size_t maxSize); [[nodiscard]]
bool valid(size_t maxSize) noexcept;
/** /**
* Set size, capacity. * Set size, capacity.
*/ */
Error setSize(size_t size); Error setSize(size_t size) noexcept;
/** /**
* Get size, capacity. * Get size, capacity.
* @return capacity * @return capacity
*/ */
size_t size(); [[nodiscard]]
constexpr size_t size() const noexcept;
/** /**
* @return the bytes still available in this NodeBuffer * @return the bytes still available in this NodeBuffer
*/ */
size_t available(); [[nodiscard]]
size_t available() noexcept;
/** /**
* @return the actual number a bytes need to store the given number of * @return the actual number a bytes need to store the given number of
* bytes * bytes
*/ */
static size_t spaceNeeded(size_t size); [[nodiscard]]
static size_t spaceNeeded(size_t size) noexcept;
template<typename F> template<typename F>
Error compact(F cb = [](uint64_t, ItemPtr) {}); Error compact(F cb = [](uint64_t, ItemPtr) {}) noexcept;
private: private:
uint8_t *data(); [[nodiscard]]
uint8_t *data() noexcept;
}; };
template<typename size_t, typename Item> template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(size_t size) { NodeBuffer<size_t, Item>::NodeBuffer(size_t size) noexcept {
m_header.size = size; m_header.size = size;
auto data = reinterpret_cast<uint8_t*>(this) + sizeof(*this); auto data = reinterpret_cast<uint8_t*>(this) + sizeof(*this);
ox_memset(data, 0, size - sizeof(*this)); ox_memset(data, 0, size - sizeof(*this));
@ -171,7 +181,7 @@ NodeBuffer<size_t, Item>::NodeBuffer(size_t size) {
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
NodeBuffer<size_t, Item>::NodeBuffer(const NodeBuffer &other, size_t size) { NodeBuffer<size_t, Item>::NodeBuffer(const NodeBuffer &other, size_t size) noexcept {
oxTrace("ox::ptrarith::NodeBuffer::copy") << "other.m_header.firstItem:" << other.m_header.firstItem; oxTrace("ox::ptrarith::NodeBuffer::copy") << "other.m_header.firstItem:" << other.m_header.firstItem;
auto data = reinterpret_cast<uint8_t*>(this) + sizeof(*this); auto data = reinterpret_cast<uint8_t*>(this) + sizeof(*this);
ox_memset(data, 0, size - sizeof(*this)); ox_memset(data, 0, size - sizeof(*this));
@ -179,24 +189,24 @@ NodeBuffer<size_t, Item>::NodeBuffer(const NodeBuffer &other, size_t size) {
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
const typename NodeBuffer<size_t, Item>::Iterator NodeBuffer<size_t, Item>::iterator() const { const typename NodeBuffer<size_t, Item>::Iterator NodeBuffer<size_t, Item>::iterator() const noexcept {
return Iterator(this, firstItem()); return Iterator(this, firstItem());
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::Iterator NodeBuffer<size_t, Item>::iterator() { typename NodeBuffer<size_t, Item>::Iterator NodeBuffer<size_t, Item>::iterator() noexcept {
oxTrace("ox::ptrarith::NodeBuffer::iterator::size") << m_header.size; oxTrace("ox::ptrarith::NodeBuffer::iterator::size") << m_header.size;
return Iterator(this, firstItem()); return Iterator(this, firstItem());
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::firstItem() { typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::firstItem() noexcept {
//oxTrace("ox::ptrarith::NodeBuffer::firstItem") << m_header.firstItem; //oxTrace("ox::ptrarith::NodeBuffer::firstItem") << m_header.firstItem;
return ptr(m_header.firstItem); return ptr(m_header.firstItem);
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::lastItem() { typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::lastItem() noexcept {
auto first = ptr(m_header.firstItem); auto first = ptr(m_header.firstItem);
if (first.valid()) { if (first.valid()) {
return prev(first); return prev(first);
@ -206,24 +216,24 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::lastItem()
template<typename size_t, typename Item> template<typename size_t, typename Item>
template<typename T> template<typename T>
Ptr<T, size_t, sizeof(Item)> NodeBuffer<size_t, Item>::dataOf(ItemPtr ip) { Ptr<T, size_t, sizeof(Item)> NodeBuffer<size_t, Item>::dataOf(ItemPtr ip) noexcept {
auto out = ip.template subPtr<T>(sizeof(Item)); auto out = ip.template subPtr<T>(sizeof(Item));
oxAssert(out.size() == ip.size() - sizeof(Item), "Sub Ptr has invalid size."); oxAssert(out.size() == ip.size() - sizeof(Item), "Sub Ptr has invalid size.");
return out; return out;
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::prev(Item *item) { typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::prev(Item *item) noexcept {
return ptr(item->prev); return ptr(item->prev);
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::next(Item *item) { typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::next(Item *item) noexcept {
return ptr(item->next); return ptr(item->next);
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::uninitializedPtr(size_t itemOffset) { typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::uninitializedPtr(size_t itemOffset) noexcept {
// make sure this can be read as an Item, and then use Item::size for the size // make sure this can be read as an Item, and then use Item::size for the size
std::size_t itemSpace = m_header.size - itemOffset; std::size_t itemSpace = m_header.size - itemOffset;
if (itemOffset >= sizeof(Header) && if (itemOffset >= sizeof(Header) &&
@ -240,7 +250,7 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::uninitializ
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t itemOffset) { typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t itemOffset) noexcept {
// make sure this can be read as an Item, and then use Item::size for the size // make sure this can be read as an Item, and then use Item::size for the size
std::size_t itemSpace = m_header.size - itemOffset; std::size_t itemSpace = m_header.size - itemOffset;
auto item = reinterpret_cast<Item*>(reinterpret_cast<uint8_t*>(this) + itemOffset); auto item = reinterpret_cast<Item*>(reinterpret_cast<uint8_t*>(this) + itemOffset);
@ -259,7 +269,7 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size_t size) { typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size_t size) noexcept {
oxTrace("ox::ptrarith::NodeBuffer::malloc") << "Size:" << size; oxTrace("ox::ptrarith::NodeBuffer::malloc") << "Size:" << size;
size_t fullSize = size + sizeof(Item); size_t fullSize = size + sizeof(Item);
if (m_header.size - m_header.bytesUsed >= fullSize) { if (m_header.size - m_header.bytesUsed >= fullSize) {
@ -318,7 +328,7 @@ typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
Error NodeBuffer<size_t, Item>::free(ItemPtr item) { Error NodeBuffer<size_t, Item>::free(ItemPtr item) noexcept {
oxTrace("ox::ptrarith::NodeBuffer::free") << "offset:" << item.offset(); oxTrace("ox::ptrarith::NodeBuffer::free") << "offset:" << item.offset();
auto prev = this->prev(item); auto prev = this->prev(item);
auto next = this->next(item); auto next = this->next(item);
@ -349,7 +359,7 @@ Error NodeBuffer<size_t, Item>::free(ItemPtr item) {
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
Error NodeBuffer<size_t, Item>::setSize(size_t size) { Error NodeBuffer<size_t, Item>::setSize(size_t size) noexcept {
oxTracef("ox::ptrarith::NodeBuffer::setSize", "{} to {}", m_header.size.get(), size); oxTracef("ox::ptrarith::NodeBuffer::setSize", "{} to {}", m_header.size.get(), size);
auto last = lastItem(); auto last = lastItem();
auto end = last.valid() ? last.end() : sizeof(m_header); auto end = last.valid() ? last.end() : sizeof(m_header);
@ -366,28 +376,28 @@ Error NodeBuffer<size_t, Item>::setSize(size_t size) {
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
size_t NodeBuffer<size_t, Item>::size() { constexpr size_t NodeBuffer<size_t, Item>::size() const noexcept {
return m_header.size; return m_header.size;
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
bool NodeBuffer<size_t, Item>::valid(size_t maxSize) { bool NodeBuffer<size_t, Item>::valid(size_t maxSize) noexcept {
return m_header.size <= maxSize; return m_header.size <= maxSize;
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
size_t NodeBuffer<size_t, Item>::available() { size_t NodeBuffer<size_t, Item>::available() noexcept {
return m_header.size - m_header.bytesUsed; return m_header.size - m_header.bytesUsed;
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
size_t NodeBuffer<size_t, Item>::spaceNeeded(size_t size) { size_t NodeBuffer<size_t, Item>::spaceNeeded(size_t size) noexcept {
return sizeof(Item) + size; return sizeof(Item) + size;
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
template<typename F> template<typename F>
Error NodeBuffer<size_t, Item>::compact(F cb) { Error NodeBuffer<size_t, Item>::compact(F cb) noexcept {
auto src = firstItem(); auto src = firstItem();
auto dest = ptr(sizeof(*this)); auto dest = ptr(sizeof(*this));
while (dest.offset() <= src.offset()) { while (dest.offset() <= src.offset()) {
@ -417,7 +427,7 @@ Error NodeBuffer<size_t, Item>::compact(F cb) {
} }
template<typename size_t, typename Item> template<typename size_t, typename Item>
uint8_t *NodeBuffer<size_t, Item>::data() { uint8_t *NodeBuffer<size_t, Item>::data() noexcept {
return reinterpret_cast<uint8_t*>(ptr(sizeof(*this)).get()); return reinterpret_cast<uint8_t*>(ptr(sizeof(*this)).get());
} }

View File

@ -13,7 +13,7 @@
namespace ox::ptrarith { namespace ox::ptrarith {
template<typename T, typename size_t, size_t minOffset = 1> template<typename T, typename size_t, size_t minOffset = 1>
class Ptr { class [[nodiscard]] Ptr {
private: private:
uint8_t *m_dataStart = nullptr; uint8_t *m_dataStart = nullptr;
@ -25,65 +25,66 @@ class Ptr {
mutable uint8_t m_validated = false; mutable uint8_t m_validated = false;
public: public:
inline Ptr() = default; constexpr Ptr() noexcept = default;
inline Ptr(std::nullptr_t); constexpr Ptr(std::nullptr_t) noexcept;
inline Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize = sizeof(T), size_t itemTypeSize = sizeof(T)); constexpr Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize = sizeof(T), size_t itemTypeSize = sizeof(T)) noexcept;
[[nodiscard]] inline bool valid() const; [[nodiscard]]
constexpr bool valid() const noexcept;
inline size_t size() const; constexpr size_t size() const noexcept;
inline size_t offset() const; constexpr size_t offset() const noexcept;
inline size_t end(); constexpr size_t end() noexcept;
inline const T *get() const; constexpr const T *get() const noexcept;
inline T *get(); constexpr T *get() noexcept;
inline const T *operator->() const; constexpr const T *operator->() const noexcept;
inline T *operator->(); constexpr T *operator->() noexcept;
inline operator const T*() const; constexpr operator const T*() const noexcept;
inline operator T*(); constexpr operator T*() noexcept;
inline const T &operator*() const; constexpr const T &operator*() const noexcept;
inline T &operator*(); constexpr T &operator*() noexcept;
inline operator size_t() const; constexpr operator size_t() const noexcept;
inline bool operator==(const Ptr<T, size_t, minOffset> &other) const; constexpr bool operator==(const Ptr<T, size_t, minOffset> &other) const noexcept;
inline bool operator!=(const Ptr<T, size_t, minOffset> &other) const; constexpr bool operator!=(const Ptr<T, size_t, minOffset> &other) const noexcept;
template<typename SubT> template<typename SubT>
inline const Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset, size_t size) const; constexpr const Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset, size_t size) const noexcept;
template<typename SubT> template<typename SubT>
inline const Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset) const; constexpr const Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset) const noexcept;
template<typename SubT> template<typename SubT>
inline Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset, size_t size); constexpr Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset, size_t size) noexcept;
template<typename SubT> template<typename SubT>
inline Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset); constexpr Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset) noexcept;
template<typename SubT> template<typename SubT>
inline const Ptr<SubT, size_t, minOffset> to() const; constexpr const Ptr<SubT, size_t, minOffset> to() const noexcept;
}; };
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline Ptr<T, size_t, minOffset>::Ptr(std::nullptr_t) { constexpr Ptr<T, size_t, minOffset>::Ptr(std::nullptr_t) noexcept {
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline Ptr<T, size_t, minOffset>::Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize, size_t itemTypeSize) { constexpr Ptr<T, size_t, minOffset>::Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize, size_t itemTypeSize) noexcept {
// do some sanity checks before assuming this is valid // do some sanity checks before assuming this is valid
if (itemSize >= itemTypeSize && if (itemSize >= itemTypeSize &&
dataStart && dataStart &&
@ -97,84 +98,84 @@ inline Ptr<T, size_t, minOffset>::Ptr(void *dataStart, size_t dataSize, size_t i
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline bool Ptr<T, size_t, minOffset>::valid() const { constexpr bool Ptr<T, size_t, minOffset>::valid() const noexcept {
m_validated = m_dataStart != nullptr; m_validated = m_dataStart != nullptr;
return m_validated; return m_validated;
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline size_t Ptr<T, size_t, minOffset>::size() const { constexpr size_t Ptr<T, size_t, minOffset>::size() const noexcept {
return m_itemSize; return m_itemSize;
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline size_t Ptr<T, size_t, minOffset>::offset() const { constexpr size_t Ptr<T, size_t, minOffset>::offset() const noexcept {
return m_itemOffset; return m_itemOffset;
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline size_t Ptr<T, size_t, minOffset>::end() { constexpr size_t Ptr<T, size_t, minOffset>::end() noexcept {
return m_itemOffset + m_itemSize; return m_itemOffset + m_itemSize;
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline const T *Ptr<T, size_t, minOffset>::get() const { constexpr const T *Ptr<T, size_t, minOffset>::get() const noexcept {
oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::get())"); oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::get())");
oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::get())"); oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::get())");
return reinterpret_cast<T*>(m_dataStart + m_itemOffset); return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline T *Ptr<T, size_t, minOffset>::get() { constexpr T *Ptr<T, size_t, minOffset>::get() noexcept {
oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::get())"); oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::get())");
oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::get())"); oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::get())");
return reinterpret_cast<T*>(m_dataStart + m_itemOffset); return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline const T *Ptr<T, size_t, minOffset>::operator->() const { constexpr const T *Ptr<T, size_t, minOffset>::operator->() const noexcept {
oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator->())"); oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator->())");
oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator->())"); oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator->())");
return reinterpret_cast<T*>(m_dataStart + m_itemOffset); return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline T *Ptr<T, size_t, minOffset>::operator->() { constexpr T *Ptr<T, size_t, minOffset>::operator->() noexcept {
oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator->())"); oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator->())");
oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator->())"); oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator->())");
return reinterpret_cast<T*>(m_dataStart + m_itemOffset); return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline Ptr<T, size_t, minOffset>::operator const T*() const { constexpr Ptr<T, size_t, minOffset>::operator const T*() const noexcept {
oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator const T*())"); oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator const T*())");
oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator const T*())"); oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator const T*())");
return reinterpret_cast<T*>(m_dataStart + m_itemOffset); return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline Ptr<T, size_t, minOffset>::operator T*() { constexpr Ptr<T, size_t, minOffset>::operator T*() noexcept {
oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator T*())"); oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator T*())");
oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator T*())"); oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator T*())");
return reinterpret_cast<T*>(m_dataStart + m_itemOffset); return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline const T &Ptr<T, size_t, minOffset>::operator*() const { constexpr const T &Ptr<T, size_t, minOffset>::operator*() const noexcept {
oxAssert(m_validated, "Unvalidated pointer dereference. (ox::fs::Ptr::operator*())"); oxAssert(m_validated, "Unvalidated pointer dereference. (ox::fs::Ptr::operator*())");
oxAssert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())"); oxAssert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())");
return *reinterpret_cast<T*>(m_dataStart + m_itemOffset); return *reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline T &Ptr<T, size_t, minOffset>::operator*() { constexpr T &Ptr<T, size_t, minOffset>::operator*() noexcept {
oxAssert(m_validated, "Unvalidated pointer dereference. (ox::fs::Ptr::operator*())"); oxAssert(m_validated, "Unvalidated pointer dereference. (ox::fs::Ptr::operator*())");
oxAssert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())"); oxAssert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())");
return *reinterpret_cast<T*>(m_dataStart + m_itemOffset); return *reinterpret_cast<T*>(m_dataStart + m_itemOffset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline Ptr<T, size_t, minOffset>::operator size_t() const { constexpr Ptr<T, size_t, minOffset>::operator size_t() const noexcept {
if (m_dataStart && m_itemOffset) { if (m_dataStart && m_itemOffset) {
return m_itemOffset; return m_itemOffset;
} }
@ -182,14 +183,14 @@ inline Ptr<T, size_t, minOffset>::operator size_t() const {
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline bool Ptr<T, size_t, minOffset>::operator==(const Ptr<T, size_t, minOffset> &other) const { constexpr bool Ptr<T, size_t, minOffset>::operator==(const Ptr<T, size_t, minOffset> &other) const noexcept {
return m_dataStart == other.m_dataStart && return m_dataStart == other.m_dataStart &&
m_itemOffset == other.m_itemOffset && m_itemOffset == other.m_itemOffset &&
m_itemSize == other.m_itemSize; m_itemSize == other.m_itemSize;
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
inline bool Ptr<T, size_t, minOffset>::operator!=(const Ptr<T, size_t, minOffset> &other) const { constexpr bool Ptr<T, size_t, minOffset>::operator!=(const Ptr<T, size_t, minOffset> &other) const noexcept {
return m_dataStart != other.m_dataStart || return m_dataStart != other.m_dataStart ||
m_itemOffset != other.m_itemOffset || m_itemOffset != other.m_itemOffset ||
m_itemSize != other.m_itemSize; m_itemSize != other.m_itemSize;
@ -197,33 +198,33 @@ inline bool Ptr<T, size_t, minOffset>::operator!=(const Ptr<T, size_t, minOffset
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
template<typename SubT> template<typename SubT>
inline const Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset, size_t size) const { constexpr const Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset, size_t size) const noexcept {
return Ptr<SubT, size_t, sizeof(T)>(get(), this->size(), offset, size); return Ptr<SubT, size_t, sizeof(T)>(get(), this->size(), offset, size);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
template<typename SubT> template<typename SubT>
inline const Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset) const { constexpr const Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset) const noexcept {
oxTrace("ox::fs::Ptr::subPtr") << m_itemOffset << this->size() << offset << m_itemSize << (m_itemSize - offset); oxTrace("ox::fs::Ptr::subPtr") << m_itemOffset << this->size() << offset << m_itemSize << (m_itemSize - offset);
return subPtr<SubT>(offset, m_itemSize - offset); return subPtr<SubT>(offset, m_itemSize - offset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
template<typename SubT> template<typename SubT>
inline Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset, size_t size) { constexpr Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset, size_t size) noexcept {
return Ptr<SubT, size_t, sizeof(T)>(get(), this->size(), offset, size); return Ptr<SubT, size_t, sizeof(T)>(get(), this->size(), offset, size);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
template<typename SubT> template<typename SubT>
inline Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset) { constexpr Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset) noexcept {
oxTrace("ox::fs::Ptr::subPtr") << m_itemOffset << this->size() << offset << m_itemSize << (m_itemSize - offset); oxTrace("ox::fs::Ptr::subPtr") << m_itemOffset << this->size() << offset << m_itemSize << (m_itemSize - offset);
return subPtr<SubT>(offset, m_itemSize - offset); return subPtr<SubT>(offset, m_itemSize - offset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>
template<typename SubT> template<typename SubT>
inline const Ptr<SubT, size_t, minOffset> Ptr<T, size_t, minOffset>::to() const { constexpr const Ptr<SubT, size_t, minOffset> Ptr<T, size_t, minOffset>::to() const noexcept {
return Ptr<SubT, size_t, minOffset>(m_dataStart, m_dataSize, m_itemOffset, m_itemSize); return Ptr<SubT, size_t, minOffset>(m_dataStart, m_dataSize, m_itemOffset, m_itemSize);
} }