diff --git a/source/mijin/container/memory_view.hpp b/source/mijin/container/memory_view.hpp new file mode 100644 index 0000000..09ee688 --- /dev/null +++ b/source/mijin/container/memory_view.hpp @@ -0,0 +1,84 @@ + +#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)