[ox] Move NodeBuffer and Ptr to ptrarith package
This commit is contained in:
		
							
								
								
									
										7
									
								
								deps/ox/src/ox/ptrarith/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								deps/ox/src/ox/ptrarith/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
install(
 | 
			
		||||
	FILES
 | 
			
		||||
		nodebuffer.hpp
 | 
			
		||||
		ptr.hpp
 | 
			
		||||
	DESTINATION
 | 
			
		||||
		include/ox/ptrarith
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										279
									
								
								deps/ox/src/ox/ptrarith/nodebuffer.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								deps/ox/src/ox/ptrarith/nodebuffer.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,279 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2015 - 2018 gtalent2@gmail.com
 | 
			
		||||
 *
 | 
			
		||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
			
		||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
			
		||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <ox/trace/trace.hpp>
 | 
			
		||||
 | 
			
		||||
#include "ptr.hpp"
 | 
			
		||||
 | 
			
		||||
namespace ox::ptrarith {
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
class __attribute__((packed)) NodeBuffer {
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		struct __attribute__((packed)) Header {
 | 
			
		||||
			ox::LittleEndian<size_t> size = sizeof(Header);
 | 
			
		||||
			ox::LittleEndian<size_t> bytesUsed = sizeof(Header);
 | 
			
		||||
			ox::LittleEndian<size_t> firstItem = 0;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		using ItemPtr = ox::ptrarith::Ptr<Item, size_t, sizeof(Header)>;
 | 
			
		||||
 | 
			
		||||
		Header m_header;
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		NodeBuffer() = default;
 | 
			
		||||
 | 
			
		||||
		explicit NodeBuffer(size_t size);
 | 
			
		||||
 | 
			
		||||
		ItemPtr firstItem();
 | 
			
		||||
 | 
			
		||||
		ItemPtr lastItem();
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @return the data section of the given item
 | 
			
		||||
		 */
 | 
			
		||||
		template<typename T>
 | 
			
		||||
		Ptr<T, size_t, sizeof(Item)> dataOf(ItemPtr);
 | 
			
		||||
 | 
			
		||||
		ItemPtr prev(Item *item);
 | 
			
		||||
 | 
			
		||||
		ItemPtr next(Item *item);
 | 
			
		||||
 | 
			
		||||
		ItemPtr ptr(size_t offset);
 | 
			
		||||
 | 
			
		||||
		ItemPtr ptr(void *item);
 | 
			
		||||
 | 
			
		||||
		ItemPtr malloc(size_t size);
 | 
			
		||||
 | 
			
		||||
		void free(ItemPtr item);
 | 
			
		||||
 | 
			
		||||
		bool valid(size_t maxSize);
 | 
			
		||||
 | 
			
		||||
		Error setSize(size_t size);
 | 
			
		||||
 | 
			
		||||
		size_t size();
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @return the bytes still available in this NodeBuffer
 | 
			
		||||
		 */
 | 
			
		||||
		size_t available();
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @return the actual number a bytes need to store the given number of
 | 
			
		||||
		 * bytes
 | 
			
		||||
		 */
 | 
			
		||||
		size_t spaceNeeded(size_t size);
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		void compact(void (*cb)(ItemPtr itemMoved));
 | 
			
		||||
 | 
			
		||||
		uint8_t *data();
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
NodeBuffer<size_t, Item>::NodeBuffer(size_t size) {
 | 
			
		||||
	m_header.size = size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::firstItem() {
 | 
			
		||||
	return ptr(m_header.firstItem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::lastItem() {
 | 
			
		||||
	auto first = ptr(m_header.firstItem);
 | 
			
		||||
	if (first.valid()) {
 | 
			
		||||
		return prev(first);
 | 
			
		||||
	}
 | 
			
		||||
	return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
template<typename T>
 | 
			
		||||
Ptr<T, size_t, sizeof(Item)> NodeBuffer<size_t, Item>::dataOf(ItemPtr ip) {
 | 
			
		||||
	auto out = ip.template subPtr<T>(sizeof(Item));
 | 
			
		||||
	oxAssert(out.size() == ip.size() - sizeof(Item), "Sub Ptr has invalid size.");
 | 
			
		||||
	return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::prev(Item *item) {
 | 
			
		||||
	return ptr(item->prev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::next(Item *item) {
 | 
			
		||||
	return ptr(item->next);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::ptr(size_t itemOffset) {
 | 
			
		||||
	// make sure this can be read as an Item, and then use Item::size for the size
 | 
			
		||||
	auto itemSpace = m_header.size - itemOffset;
 | 
			
		||||
	auto item = reinterpret_cast<Item*>(reinterpret_cast<uint8_t*>(this) + itemOffset);
 | 
			
		||||
	if (itemOffset >= sizeof(Header) and
 | 
			
		||||
		 itemOffset < m_header.size - sizeof(Item) and
 | 
			
		||||
		 itemSpace >= static_cast<size_t>(sizeof(Item)) and
 | 
			
		||||
		 itemSpace >= item->fullSize()) {
 | 
			
		||||
		return ItemPtr(this, m_header.size, itemOffset, item->fullSize());
 | 
			
		||||
	} else {
 | 
			
		||||
		return ItemPtr(this, m_header.size, 0, 0);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
typename NodeBuffer<size_t, Item>::ItemPtr NodeBuffer<size_t, Item>::malloc(size_t size) {
 | 
			
		||||
	auto fullSize = size + sizeof(Item);
 | 
			
		||||
	if (m_header.size - m_header.bytesUsed >= fullSize) {
 | 
			
		||||
		auto last = lastItem();
 | 
			
		||||
		size_t addr = 0;
 | 
			
		||||
		if (last.valid()) {
 | 
			
		||||
			addr = last.offset() + last.size();
 | 
			
		||||
		} else {
 | 
			
		||||
			// there is no first item, so this may be the first item
 | 
			
		||||
			if (!m_header.firstItem) {
 | 
			
		||||
				oxTrace("ox::fs::NodeBuffer::malloc") << "No first item, initializing.";
 | 
			
		||||
				m_header.firstItem = sizeof(m_header);
 | 
			
		||||
				addr = m_header.firstItem;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		auto out = ItemPtr(this, m_header.size, addr, fullSize);
 | 
			
		||||
		if (out.valid()) {
 | 
			
		||||
			new (out) Item(size);
 | 
			
		||||
 | 
			
		||||
			auto first = firstItem();
 | 
			
		||||
			out->next = first.offset();
 | 
			
		||||
			if (first.valid()) {
 | 
			
		||||
				first->prev = out.offset();
 | 
			
		||||
			} else {
 | 
			
		||||
				oxTrace("ox::fs::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid first element pointer.";
 | 
			
		||||
				return nullptr;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			auto last = lastItem();
 | 
			
		||||
			out->prev = last.offset();
 | 
			
		||||
			if (last.valid()) {
 | 
			
		||||
				last->next = out.offset();
 | 
			
		||||
			} else {
 | 
			
		||||
				oxTrace("ox::fs::NodeBuffer::malloc::fail") << "NodeBuffer malloc failed due to invalid last element pointer.";
 | 
			
		||||
				return nullptr;
 | 
			
		||||
			}
 | 
			
		||||
			m_header.bytesUsed += out.size();
 | 
			
		||||
		} else {
 | 
			
		||||
			oxTrace("ox::fs::NodeBuffer::malloc::fail") << "Unknown";
 | 
			
		||||
		}
 | 
			
		||||
		return out;
 | 
			
		||||
	}
 | 
			
		||||
	oxTrace("ox::fs::NodeBuffer::malloc::fail") << "Insufficient space:" << fullSize << "needed," << available() << "available";
 | 
			
		||||
	return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
void NodeBuffer<size_t, Item>::free(ItemPtr item) {
 | 
			
		||||
	auto prev = this->prev(item);
 | 
			
		||||
	auto next = this->next(item);
 | 
			
		||||
	if (prev.valid()) {
 | 
			
		||||
		prev->next = next.offset();
 | 
			
		||||
	} else {
 | 
			
		||||
		oxTrace("ox::fs::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid prev element pointer.";
 | 
			
		||||
	}
 | 
			
		||||
	if (next.valid()) {
 | 
			
		||||
		next->prev = prev.offset();
 | 
			
		||||
	} else {
 | 
			
		||||
		oxTrace("ox::fs::NodeBuffer::free::fail") << "NodeBuffer free failed due to invalid next element pointer.";
 | 
			
		||||
	}
 | 
			
		||||
	m_header.bytesUsed -= item.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
Error NodeBuffer<size_t, Item>::setSize(size_t size) {
 | 
			
		||||
	auto last = lastItem();
 | 
			
		||||
	if ((last.valid() and last.end() >= size) or size < sizeof(m_header)) {
 | 
			
		||||
		return 1;
 | 
			
		||||
	} else {
 | 
			
		||||
		m_header.size = size;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
size_t NodeBuffer<size_t, Item>::size() {
 | 
			
		||||
	return m_header.size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
bool NodeBuffer<size_t, Item>::valid(size_t maxSize) {
 | 
			
		||||
	return m_header.size <= maxSize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
size_t NodeBuffer<size_t, Item>::available() {
 | 
			
		||||
	return m_header.size - m_header.bytesUsed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
size_t NodeBuffer<size_t, Item>::spaceNeeded(size_t size) {
 | 
			
		||||
	return sizeof(Item) + size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
void NodeBuffer<size_t, Item>::compact(void (*cb)(ItemPtr)) {
 | 
			
		||||
	auto src = firstItem();
 | 
			
		||||
	auto dest = ptr(sizeof(*this));
 | 
			
		||||
	while (src.valid() && dest.valid()) {
 | 
			
		||||
		// move node
 | 
			
		||||
		ox_memcpy(dest, src, src.size());
 | 
			
		||||
		if (cb) {
 | 
			
		||||
			cb(dest);
 | 
			
		||||
		}
 | 
			
		||||
		// update surrounding nodes
 | 
			
		||||
		auto prev = ptr(dest->next);
 | 
			
		||||
		if (prev.valid()) {
 | 
			
		||||
			prev->next = dest;
 | 
			
		||||
		}
 | 
			
		||||
		auto next = ptr(dest->next);
 | 
			
		||||
		if (next.valid()) {
 | 
			
		||||
			next->prev = dest;
 | 
			
		||||
		}
 | 
			
		||||
		// update iterators
 | 
			
		||||
		src = ptr(dest->next);
 | 
			
		||||
		dest = ptr(dest.offset() + dest.size());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename size_t, typename Item>
 | 
			
		||||
uint8_t *NodeBuffer<size_t, Item>::data() {
 | 
			
		||||
	return reinterpret_cast<uint8_t*>(ptr(sizeof(*this)).get());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename size_t>
 | 
			
		||||
struct __attribute__((packed)) Item {
 | 
			
		||||
	public:
 | 
			
		||||
		ox::LittleEndian<size_t> prev = 0;
 | 
			
		||||
		ox::LittleEndian<size_t> next = 0;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		ox::LittleEndian<size_t> m_size = sizeof(Item);
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		explicit Item(size_t size) {
 | 
			
		||||
			this->m_size = size;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		size_t size() const {
 | 
			
		||||
			return m_size;
 | 
			
		||||
		}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										199
									
								
								deps/ox/src/ox/ptrarith/ptr.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								deps/ox/src/ox/ptrarith/ptr.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,199 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2015 - 2018 gtalent2@gmail.com
 | 
			
		||||
 *
 | 
			
		||||
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
			
		||||
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
			
		||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <ox/std/std.hpp>
 | 
			
		||||
 | 
			
		||||
namespace ox::ptrarith {
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset = 1>
 | 
			
		||||
class Ptr {
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		uint8_t *m_dataStart = nullptr;
 | 
			
		||||
		size_t m_itemOffset = 0;
 | 
			
		||||
		size_t m_itemSize = 0;
 | 
			
		||||
		// this should be removed later on, but the excessive validation is
 | 
			
		||||
		// desirable during during heavy development
 | 
			
		||||
		mutable uint8_t m_validated = false;
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		inline Ptr() = default;
 | 
			
		||||
 | 
			
		||||
		inline Ptr(std::nullptr_t);
 | 
			
		||||
 | 
			
		||||
		inline Ptr(void *dataStart, size_t dataSize, size_t itemStart, size_t itemSize = sizeof(T));
 | 
			
		||||
 | 
			
		||||
		inline bool valid() const;
 | 
			
		||||
 | 
			
		||||
		inline size_t size() const;
 | 
			
		||||
 | 
			
		||||
		inline size_t offset() const;
 | 
			
		||||
 | 
			
		||||
		inline size_t end();
 | 
			
		||||
 | 
			
		||||
		inline const T *get() const;
 | 
			
		||||
 | 
			
		||||
		inline T *get();
 | 
			
		||||
 | 
			
		||||
		inline const T *operator->() const;
 | 
			
		||||
 | 
			
		||||
		inline T *operator->();
 | 
			
		||||
 | 
			
		||||
		inline operator const T*() const;
 | 
			
		||||
 | 
			
		||||
		inline operator T*();
 | 
			
		||||
 | 
			
		||||
		inline const T &operator*() const;
 | 
			
		||||
 | 
			
		||||
		inline T &operator*();
 | 
			
		||||
 | 
			
		||||
		inline operator size_t() const;
 | 
			
		||||
 | 
			
		||||
		template<typename SubT>
 | 
			
		||||
		inline const Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset, size_t size) const;
 | 
			
		||||
 | 
			
		||||
		template<typename SubT>
 | 
			
		||||
		inline const Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset) const;
 | 
			
		||||
 | 
			
		||||
		template<typename SubT>
 | 
			
		||||
		inline Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset, size_t size);
 | 
			
		||||
 | 
			
		||||
		template<typename SubT>
 | 
			
		||||
		inline Ptr<SubT, size_t, sizeof(T)> subPtr(size_t offset);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline Ptr<T, size_t, minOffset>::Ptr(std::nullptr_t) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
	// do some sanity checks before assuming this is valid
 | 
			
		||||
	if (itemSize >= sizeof(T) and
 | 
			
		||||
	    dataStart and
 | 
			
		||||
	    itemStart >= minOffset and
 | 
			
		||||
	    itemStart + itemSize <= dataSize) {
 | 
			
		||||
		m_dataStart = reinterpret_cast<uint8_t*>(dataStart);
 | 
			
		||||
		m_itemOffset = itemStart;
 | 
			
		||||
		m_itemSize = itemSize;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline bool Ptr<T, size_t, minOffset>::valid() const {
 | 
			
		||||
	m_validated = m_dataStart != nullptr;
 | 
			
		||||
	return m_validated;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline size_t Ptr<T, size_t, minOffset>::size() const {
 | 
			
		||||
	return m_itemSize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline size_t Ptr<T, size_t, minOffset>::offset() const {
 | 
			
		||||
	return m_itemOffset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline size_t Ptr<T, size_t, minOffset>::end() {
 | 
			
		||||
	return m_itemOffset + m_itemSize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline const T *Ptr<T, size_t, minOffset>::get() const {
 | 
			
		||||
	oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::get())");
 | 
			
		||||
	oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::get())");
 | 
			
		||||
	return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline T *Ptr<T, size_t, minOffset>::get() {
 | 
			
		||||
	oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::get())");
 | 
			
		||||
	oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::get())");
 | 
			
		||||
	return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline const T *Ptr<T, size_t, minOffset>::operator->() const {
 | 
			
		||||
	oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator->())");
 | 
			
		||||
	oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator->())");
 | 
			
		||||
	return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline T *Ptr<T, size_t, minOffset>::operator->() {
 | 
			
		||||
	oxAssert(m_validated, "Unvalidated pointer access. (ox::fs::Ptr::operator->())");
 | 
			
		||||
	oxAssert(valid(), "Invalid pointer access. (ox::fs::Ptr::operator->())");
 | 
			
		||||
	return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline Ptr<T, size_t, minOffset>::operator const T*() const {
 | 
			
		||||
	return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline Ptr<T, size_t, minOffset>::operator T*() {
 | 
			
		||||
	return reinterpret_cast<T*>(m_dataStart + m_itemOffset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline const T &Ptr<T, size_t, minOffset>::operator*() const {
 | 
			
		||||
	oxAssert(m_validated, "Unvalidated pointer dereference. (ox::fs::Ptr::operator*())");
 | 
			
		||||
	oxAssert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())");
 | 
			
		||||
	return *reinterpret_cast<T*>(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline T &Ptr<T, size_t, minOffset>::operator*() {
 | 
			
		||||
	oxAssert(m_validated, "Unvalidated pointer dereference. (ox::fs::Ptr::operator*())");
 | 
			
		||||
	oxAssert(valid(), "Invalid pointer dereference. (ox::fs::Ptr::operator*())");
 | 
			
		||||
	return *reinterpret_cast<T*>(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
inline Ptr<T, size_t, minOffset>::operator size_t() const {
 | 
			
		||||
	if (m_dataStart and m_itemOffset) {
 | 
			
		||||
		return m_itemOffset;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
template<typename SubT>
 | 
			
		||||
inline const Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset, size_t size) const {
 | 
			
		||||
	auto out = Ptr<SubT, size_t, sizeof(T)>(get(), this->size(), offset, size);
 | 
			
		||||
	return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
template<typename SubT>
 | 
			
		||||
inline const Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset) const {
 | 
			
		||||
	oxTrace("ox::fs::Ptr::subPtr") << m_itemOffset << this->size() << offset << m_itemSize << (m_itemSize - offset);
 | 
			
		||||
	return subPtr<SubT>(offset, m_itemSize - offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
template<typename SubT>
 | 
			
		||||
inline Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset, size_t size) {
 | 
			
		||||
	auto out = Ptr<SubT, size_t, sizeof(T)>(get(), this->size(), offset, size);
 | 
			
		||||
	return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T, typename size_t, size_t minOffset>
 | 
			
		||||
template<typename SubT>
 | 
			
		||||
inline Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset) {
 | 
			
		||||
	oxTrace("ox::fs::Ptr::subPtr") << m_itemOffset << this->size() << offset << m_itemSize << (m_itemSize - offset);
 | 
			
		||||
	return subPtr<SubT>(offset, m_itemSize - offset);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user