1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-23 03:02:53 +01:00
rpcs3/rpcs3/io_buffer.h

66 lines
1.2 KiB
C++

#pragma once
#include <util/types.hpp>
#include <span>
#include <vector>
#include <functional>
namespace rsx
{
template <typename T>
concept SpanLike = requires(T t)
{
{ t.data() } -> std::convertible_to<void*>;
{ t.size_bytes() } -> std::convertible_to<usz>;
};
template <typename T>
concept Integral = std::is_integral_v<T> || std::is_same_v<T, u128>;
class io_buffer
{
void* m_ptr = nullptr;
usz m_size = 0;
std::function<std::tuple<void*, usz> ()> m_allocator = nullptr;
public:
io_buffer() = default;
template <SpanLike T>
io_buffer(T& container)
{
m_ptr = reinterpret_cast<void*>(container.data());
m_size = container.size_bytes();
}
io_buffer(std::function<std::tuple<void*, usz> ()> allocator)
{
ensure(allocator);
m_allocator = allocator;
}
template<Integral T>
T* data()
{
if (!m_ptr && m_allocator)
{
std::tie(m_ptr, m_size) = m_allocator();
}
return static_cast<T*>(m_ptr);
}
usz size() const
{
return m_size;
}
template<Integral T>
std::span<T> as_span()
{
const auto bytes = data<T>();
return { bytes, m_size / sizeof(T) };
}
};
}