// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2021 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_BUFFER_BUFFERS_H namespace ircd::buffer::buffers { template class I> using const_buffers = I; template class I> using mutable_buffers = I; // Convenience null buffers [[clang::internal_linkage]] extern const ilist null_buffers; // Iterable of buffers tools template class I, class T> size_t size(const I &buffers); template class I, class T> size_t copy(const mutable_buffer &, const I &buffer); template class I, class T> size_t consume(I &buffers, const size_t &bytes); template class I, class T> std::ostream &operator<<(std::ostream &s, const I &buffers); } template class buffers, class T> std::ostream & ircd::buffer::buffers::operator<<(std::ostream &s, const buffers &b) { using it = typename T::iterator; std::for_each(std::begin(b), std::end(b), [&s] (const buffer &b) { s << b; }); return s; } template class buffers, class T> size_t ircd::buffer::buffers::consume(buffers &b, const size_t &bytes) { ssize_t remain(bytes); for(auto it(std::begin(b)); it != std::end(b) && remain > 0; ++it) { using buffer = typename buffers::value_type; using iterator = typename buffer::iterator; using ircd::buffer::size; using ircd::buffer::consume; buffer &b(const_cast(*it)); const ssize_t bsz(size(b)); const ssize_t csz{std::min(remain, bsz)}; remain -= consume(b, csz); assert(remain >= 0); } assert(ssize_t(bytes) >= remain); return bytes - remain; } template class buffers, class T> size_t ircd::buffer::buffers::copy(const mutable_buffer &dest, const buffers &b) { using it = typename T::iterator; using ircd::buffer::copy; using ircd::buffer::size; size_t ret(0); for(const buffer &b : b) ret += copy(dest + ret, b); return ret; } template class buffers, class T> size_t ircd::buffer::buffers::size(const buffers &b) { using it = typename T::iterator; using ircd::buffer::size; return std::accumulate(std::begin(b), std::end(b), size_t(0), [] (auto ret, const buffer &b) { return ret += size(b); }); }