io: ensure write/pwrite views use pointer iterators

This commit is contained in:
Danny Robson 2018-12-19 17:13:06 +11:00
parent fb7c989487
commit 072dce8891

25
io.hpp
View File

@ -9,6 +9,7 @@
#ifndef __UTIL_IO_HPP #ifndef __UTIL_IO_HPP
#define __UTIL_IO_HPP #define __UTIL_IO_HPP
#include "std.hpp"
#include "platform.hpp" #include "platform.hpp"
#include "posix/fd.hpp" #include "posix/fd.hpp"
@ -67,25 +68,23 @@ namespace cruft {
/// ///
/// An exception may be throw in the event forward progress is impossible /// An exception may be throw in the event forward progress is impossible
/// (depending on the supplied FunctionT). /// (depending on the supplied FunctionT).
///
/// TODO: enforce constness of view iterators
template < template <
typename DstT, typename DstT,
typename FunctionT, typename FunctionT,
typename IteratorA, typename ValueT,
typename IteratorB,
typename ...Args typename ...Args
> >
[[nodiscard]] decltype(auto) [[nodiscard]] decltype(auto)
drain ( drain (
DstT &&dst, DstT &&dst,
FunctionT &&func, FunctionT &&func,
cruft::view<IteratorA,IteratorB> const &src, cruft::view<ValueT*> const &src,
Args&& ...args Args&& ...args
) { ) {
static_assert (std::is_pointer_v<IteratorA>); auto cursor = reinterpret_cast<u08 const*> (src.data ());
static_assert (std::is_pointer_v<IteratorB>); auto remain = src.size () * sizeof (ValueT);
auto cursor = reinterpret_cast<std::byte const*> (src.data ());
auto remain = src.size ();
while (remain) { while (remain) {
auto count = std::invoke (func, dst, cursor, remain, args...); auto count = std::invoke (func, dst, cursor, remain, args...);
@ -105,11 +104,10 @@ namespace cruft {
/// to `src`. /// to `src`.
template < template <
typename DstT, typename DstT,
typename IteratorA, typename ValueT
typename IteratorB
> >
decltype(auto) decltype(auto)
write (DstT &&dst, const cruft::view<IteratorA, IteratorB> &src) write (DstT &&dst, cruft::view<ValueT*> const &src)
{ {
constexpr auto func = &std::decay_t<DstT>::write; constexpr auto func = &std::decay_t<DstT>::write;
return drain (std::forward<DstT> (dst), func, src); return drain (std::forward<DstT> (dst), func, src);
@ -124,11 +122,10 @@ namespace cruft {
/// to `src`. /// to `src`.
template < template <
typename DstT, typename DstT,
typename IteratorA, typename ValueT
typename IteratorB
> >
decltype(auto) decltype(auto)
pwrite (DstT &&dst, const cruft::view<IteratorA, IteratorB> &src, size_t offset) pwrite (DstT &&dst, cruft::view<ValueT*> const &src, size_t offset)
{ {
return drain (std::forward<DstT> (dst), &std::decay_t<DstT>::pwrite, src, offset); return drain (std::forward<DstT> (dst), &std::decay_t<DstT>::pwrite, src, offset);
} }