// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2018 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_IOV_H namespace ircd { template struct iov; } /// iov (iovector) is a forward list composed on a trip up the stack /// presenting an iteration of items to a scatter/gather operation like a /// socket or JSON generator etc. Add items to the iov by constructing nodes /// on your stack. /// template struct ircd::iov :std::forward_list::allocator> { struct node; using allocator_state = allocator::node; using allocator_type = typename allocator_state::allocator; using list = std::forward_list; using list_node = typename list::iterator::_Node; //TODO: YYY auto size() const { return std::distance(std::begin(*this), std::end(*this)); } allocator_state a; iov(): list{a} {} }; template struct ircd::iov::node :iov::list_node { iov *const i {nullptr}; operator const T &() const; operator T &(); node() = default; template node(iov *const &, args&&...); template node(iov &, args&&...); node(node &&) = delete; node(const node &) = delete; node &operator=(node &&) = delete; node &operator=(const node &) = delete; ~node() noexcept; }; template template ircd::iov::node::node(iov &iov, args&&... a) :node { &iov, std::forward(a)... } {} template template ircd::iov::node::node(iov *const &iov, args&&... a) :i{iov} { if(!iov) return; auto &list { *static_cast(iov) }; auto &list_node { *static_cast(this) }; const auto &address { reinterpret_cast(&list_node) }; list.get_allocator().s->next = reinterpret_cast(address); list.emplace_front(std::forward(a)...); } template ircd::iov::node::~node() noexcept { if(i) i->remove_if([this](const T &x) { return &x == &static_cast(*this); }); } template ircd::iov::node::operator T &() { assert(i); auto &list_node(static_cast(*this)); return *list_node._M_valptr(); //TODO: XXX } template ircd::iov::node::operator const T &() const { assert(i); const auto &list_node(static_cast(*this)); return *list_node._M_valptr(); //TODO: XXX }