mijin2/source/mijin/container/memory_view.hpp
2025-01-18 18:38:37 +01:00

85 lines
2.2 KiB
C++

#pragma once
#if !defined(MIJIN_CONTAINER_MEMORY_VIEW_HPP_INCLUDED)
#define MIJIN_CONTAINER_MEMORY_VIEW_HPP_INCLUDED 1
#include <bit>
#include <cstddef>
#include <span>
#include "../debug/assert.hpp"
#include "../util/traits.hpp"
namespace mijin
{
//
// public defines
//
//
// public constants
//
//
// public types
//
template<typename TBytes>
class MemoryViewBase
{
public:
using size_type = std::size_t;
private:
std::span<TBytes> bytes_;
public:
MemoryViewBase() noexcept = default;
MemoryViewBase(const MemoryViewBase&) noexcept = default;
MemoryViewBase(copy_const_t<TBytes, void>* data, std::size_t size) noexcept : bytes_(static_cast<TBytes*>(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<typename T>
[[nodiscard]] std::span<T> makeSpan();
template<typename T>
[[nodiscard]] std::span<const T> makeSpan() const;
};
using MemoryView = MemoryViewBase<std::byte>;
using ConstMemoryView = MemoryViewBase<const std::byte>;
//
// public functions
//
template<typename TBytes>
template<typename T>
std::span<T> MemoryViewBase<TBytes>::makeSpan()
{
static_assert(!std::is_const_v<TBytes>, "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<T*>(bytes_.data()),
std::bit_cast<T*>(bytes_.data() + bytes_.size())
};
}
template<typename TBytes>
template<typename T>
std::span<const T> MemoryViewBase<TBytes>::makeSpan() const
{
MIJIN_ASSERT(bytes_.size() % sizeof(T) == 0, "MemoryView cannot be divided into elements of this type.");
return {
std::bit_cast<const T*>(bytes_.data()),
std::bit_cast<const T*>(bytes_.data() + bytes_.size())
};
}
} // namespace mijin
#endif // !defined(MIJIN_CONTAINER_MEMORY_VIEW_HPP_INCLUDED)