#pragma once #include #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) { } template ByteSpanGeneral(const ByteSpanGeneral& other) requires(CONST || !SRC_CONST) : m_data(other.data()) , m_size(other.size()) { } template ByteSpanGeneral(ByteSpanGeneral&& other) requires(CONST || !SRC_CONST) : m_data(other.data()) , m_size(other.size()) { other.clear(); } template ByteSpanGeneral(const Span& other) requires(is_same_v || (is_same_v && CONST)) : m_data(other.data()) , m_size(other.size()) { } template ByteSpanGeneral(Span&& other) requires(is_same_v || (is_same_v && CONST)) : m_data(other.data()) , m_size(other.size()) { other.clear(); } template ByteSpanGeneral& operator=(const ByteSpanGeneral& other) requires(CONST || !SRC_CONST) { m_data = other.data(); m_size = other.size(); return *this; } template ByteSpanGeneral& operator=(ByteSpanGeneral&& other) requires(CONST || !SRC_CONST) { m_data = other.data(); m_size = other.size(); other.clear(); return *this; } template static ByteSpanGeneral from(S& value) requires(CONST || !is_const_v) { return ByteSpanGeneral(reinterpret_cast(&value), sizeof(S)); } template S& as() const requires(!CONST || is_const_v) { ASSERT(m_data); ASSERT(m_size >= sizeof(S)); return *reinterpret_cast(m_data); } template Span as_span() const requires(!CONST || is_const_v) { ASSERT(m_data); return Span(reinterpret_cast(m_data), m_size / sizeof(S)); } [[nodiscard]] ByteSpanGeneral slice(size_type offset, size_type length = size_type(-1)) const { ASSERT(m_data); ASSERT(m_size >= offset); if (length == size_type(-1)) length = m_size - offset; ASSERT(m_size >= offset + length); return ByteSpanGeneral(m_data + offset, length); } value_type& operator[](size_type offset) const { ASSERT(offset < m_size); return m_data[offset]; } value_type* data() const { return m_data; } bool empty() const { return m_size == 0; } size_type size() const { return m_size; } void clear() { m_data = nullptr; m_size = 0; } private: value_type* m_data { nullptr }; size_type m_size { 0 }; friend class ByteSpanGeneral; }; using ByteSpan = ByteSpanGeneral; using ConstByteSpan = ByteSpanGeneral; }