#pragma once #if !defined(MIJIN_CONTAINER_MEMORY_VIEW_HPP_INCLUDED) #define MIJIN_CONTAINER_MEMORY_VIEW_HPP_INCLUDED 1 #include #include #include #include "../debug/assert.hpp" #include "../util/traits.hpp" namespace mijin { // // public defines // // // public constants // // // public types // template class MemoryViewBase { public: using size_type = std::size_t; private: std::span bytes_; public: MemoryViewBase() noexcept = default; MemoryViewBase(const MemoryViewBase&) noexcept = default; MemoryViewBase(copy_const_t* data, std::size_t size) noexcept : bytes_(static_cast(data), size) {} MemoryViewBase& operator=(const MemoryViewBase&) noexcept = default; [[nodiscard]] void* data() noexcept { return bytes_.data(); } [[nodiscard]] const void* data() const noexcept { return bytes_.data(); } [[nodiscard]] size_type byteSize() const noexcept { return bytes_.size(); } [[nodiscard]] bool empty() const noexcept { return bytes_.empty(); } template [[nodiscard]] std::span makeSpan(); template [[nodiscard]] std::span makeSpan() const; }; using MemoryView = MemoryViewBase; using ConstMemoryView = MemoryViewBase; // // public functions // template template std::span MemoryViewBase::makeSpan() { static_assert(!std::is_const_v, "Cannot create writable spans from const memory views."); MIJIN_ASSERT(bytes_.size() % sizeof(T) == 0, "MemoryView cannot be divided into elements of this type."); return { std::bit_cast(bytes_.data()), std::bit_cast(bytes_.data() + bytes_.size()) }; } template template std::span MemoryViewBase::makeSpan() const { MIJIN_ASSERT(bytes_.size() % sizeof(T) == 0, "MemoryView cannot be divided into elements of this type."); return { std::bit_cast(bytes_.data()), std::bit_cast(bytes_.data() + bytes_.size()) }; } } // namespace mijin #endif // !defined(MIJIN_CONTAINER_MEMORY_VIEW_HPP_INCLUDED)