diff --git a/BAN/include/BAN/ByteSpan.h b/BAN/include/BAN/ByteSpan.h new file mode 100644 index 00000000..589b988e --- /dev/null +++ b/BAN/include/BAN/ByteSpan.h @@ -0,0 +1,121 @@ +#pragma once + +#include + +namespace BAN +{ + + template + class ByteSpanGeneral + { + public: + using value_type = maybe_const_t; + using size_type = size_t; + + public: + ByteSpanGeneral() = default; + ByteSpanGeneral(value_type* data, size_type size) + : m_data(data) + , m_size(size) + { } + + ByteSpanGeneral(ByteSpanGeneral& other) + : m_data(other.data()) + , m_size(other.size()) + { } + template + ByteSpanGeneral(const ByteSpanGeneral& other) requires(CONST) + : m_data(other.data()) + , m_size(other.size()) + { } + ByteSpanGeneral(Span other) + : m_data(other.data()) + , m_size(other.size()) + { } + ByteSpanGeneral(const Span& other) requires(CONST) + : m_data(other.data()) + , m_size(other.size()) + { } + + ByteSpanGeneral& operator=(ByteSpanGeneral other) + { + m_data = other.data(); + m_size = other.size(); + return *this; + } + template + ByteSpanGeneral& operator=(const ByteSpanGeneral& other) requires(CONST) + { + m_data = other.data(); + m_size = other.size(); + return *this; + } + ByteSpanGeneral& operator=(Span other) + { + m_data = other.data(); + m_size = other.size(); + return *this; + } + ByteSpanGeneral& operator=(const Span& other) requires(CONST) + { + m_data = other.data(); + m_size = other.size(); + return *this; + } + + template + requires(CONST || !is_const_v) + static ByteSpanGeneral from(S& value) + { + return ByteSpanGeneral(reinterpret_cast(&value), sizeof(S)); + } + + template + requires(!CONST && !is_const_v) + S& as() + { + ASSERT(m_data); + ASSERT(m_size >= sizeof(S)); + return *reinterpret_cast(m_data); + } + + template + const S& as() const + { + ASSERT(m_data); + ASSERT(m_size >= sizeof(S)); + return *reinterpret_cast(m_data); + } + + ByteSpanGeneral slice(size_type offset, size_type length) + { + ASSERT(m_data); + ASSERT(m_size >= offset + length); + return ByteSpanGeneral(m_data + offset, length); + } + + value_type& operator[](size_type offset) + { + ASSERT(offset < m_size); + return m_data[offset]; + } + const value_type& operator[](size_type offset) const + { + ASSERT(offset < m_size); + return m_data[offset]; + } + + value_type* data() { return m_data; } + const value_type* data() const { return m_data; } + + size_type size() const { return m_size; } + + private: + value_type* m_data { nullptr }; + size_type m_size { 0 }; + }; + + using ByteSpan = ByteSpanGeneral; + using ConstByteSpan = ByteSpanGeneral; + +} \ No newline at end of file