Refactor buffers_adaptor (API Change):

* Tidy up tests
* Increase code coverage
* Remove move special members
* Correct behavior for default constructed iterators

API Changes:

* buffers_adaptor is renamed (was buffers_adapter)

Actions Required:

* Replace buffers_adapter.hpp with buffers_adaptor.hpp, and
  replace buffers_adapter with buffers_adaptor. Or, define
  BOOST_BEAST_ALLOW_DEPRECATED
This commit is contained in:
Vinnie Falco committed 2018-12-19 20:59:20 -08:00
1 parent c1d7a83af2
commit 117dda7b31
15 files changed
+1037 -537

No files matched your search

@@ -12,7 +12,7 @@
#include <boost/beast/_experimental/core/detail/dynamic_buffer_ref.hpp>
#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/core/buffers_adapter.hpp>
#include <boost/beast/core/buffers_adaptor.hpp>
#include <boost/beast/core/buffers_prefix.hpp>
#include <boost/beast/core/buffers_suffix.hpp>
#include <boost/beast/core/detail/buffers_ref.hpp>
@@ -132,7 +132,7 @@ class icy_stream<NextLayer>::read_op
struct data
{
icy_stream<NextLayer>& s;
buffers_adapter<MutableBufferSequence> b;
buffers_adaptor<MutableBufferSequence> b;
bool match = false;
data(
@@ -234,7 +234,7 @@ operator()(
{
using iterator = net::buffers_iterator<
typename beast::detail::dynamic_buffer_ref<
buffers_adapter<MutableBufferSequence>>::const_buffers_type>;
buffers_adaptor<MutableBufferSequence>>::const_buffers_type>;
auto& d = *d_;
BOOST_ASIO_CORO_REENTER(*this)
{
@@ -400,8 +400,8 @@ read_some(MutableBufferSequence const& buffers, error_code& ec)
"MutableBufferSequence requirements not met");
using iterator = net::buffers_iterator<
typename beast::detail::dynamic_buffer_ref<
buffers_adapter<MutableBufferSequence>>::const_buffers_type>;
buffers_adapter<MutableBufferSequence> b(buffers);
buffers_adaptor<MutableBufferSequence>>::const_buffers_type>;
buffers_adaptor<MutableBufferSequence> b(buffers);
if(b.max_size() == 0)
{
ec = {};
+1 -1
View File
@@ -15,7 +15,7 @@
#include <boost/beast/core/bind_handler.hpp>
#include <boost/beast/core/buffer_traits.hpp>
#include <boost/beast/core/buffered_read_stream.hpp>
#include <boost/beast/core/buffers_adapter.hpp>
#include <boost/beast/core/buffers_adaptor.hpp>
#include <boost/beast/core/buffers_cat.hpp>
#include <boost/beast/core/buffers_prefix.hpp>
#include <boost/beast/core/buffers_range.hpp>
+11 -202
View File
@@ -11,216 +11,25 @@
#define BOOST_BEAST_BUFFERS_ADAPTER_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/optional.hpp>
#include <type_traits>
#ifdef BOOST_BEAST_ALLOW_DEPRECATED
#include <boost/beast/core/buffers_adaptor.hpp>
namespace boost {
namespace beast {
/** Adapts a <em>MutableBufferSequence</em> into a <em>DynamicBuffer</em>.
This class wraps a <em>MutableBufferSequence</em> to meet the requirements
of <em>DynamicBuffer</em>. Upon construction the input and output sequences
are empty. A copy of the mutable buffer sequence object is stored; however,
ownership of the underlying memory is not transferred. The caller is
responsible for making sure that referenced memory remains valid
for the duration of any operations.
The size of the mutable buffer sequence determines the maximum
number of bytes which may be prepared and committed.
@tparam MutableBufferSequence The type of mutable buffer sequence to wrap.
*/
template<class MutableBufferSequence>
class buffers_adapter
{
static_assert(net::is_mutable_buffer_sequence<
MutableBufferSequence>::value,
"MutableBufferSequence requirements not met");
using iter_type = typename
detail::buffer_sequence_iterator<
MutableBufferSequence>::type;
MutableBufferSequence bs_;
iter_type begin_;
iter_type out_;
iter_type end_;
std::size_t max_size_;
std::size_t in_pos_ = 0; // offset in *begin_
std::size_t in_size_ = 0; // size of input sequence
std::size_t out_pos_ = 0; // offset in *out_
std::size_t out_end_ = 0; // output end offset
template<class Deduced>
buffers_adapter(Deduced&& other,
std::size_t nbegin, std::size_t nout,
std::size_t nend)
: bs_(std::forward<Deduced>(other).bs_)
, begin_(std::next(bs_.begin(), nbegin))
, out_(std::next(bs_.begin(), nout))
, end_(std::next(bs_.begin(), nend))
, max_size_(other.max_size_)
, in_pos_(other.in_pos_)
, in_size_(other.in_size_)
, out_pos_(other.out_pos_)
, out_end_(other.out_end_)
{
}
iter_type end_impl() const;
public:
/// The type of the underlying mutable buffer sequence
using value_type = MutableBufferSequence;
/// Move constructor.
buffers_adapter(buffers_adapter&& other);
/// Copy constructor.
buffers_adapter(buffers_adapter const& other);
/// Move assignment.
buffers_adapter& operator=(buffers_adapter&& other);
/// Copy assignment.
buffers_adapter& operator=(buffers_adapter const&);
/** Construct a buffers adapter.
@param buffers The mutable buffer sequence to wrap. A copy of
the object will be made, but ownership of the memory is not
transferred.
*/
explicit
buffers_adapter(MutableBufferSequence const& buffers);
/** Constructor
This constructs the buffer adapter in-place from
a list of arguments.
@param args Arguments forwarded to the buffers constructor.
*/
template<class... Args>
explicit
buffers_adapter(boost::in_place_init_t, Args&&... args);
/// Returns the original mutable buffer sequence
value_type const&
value() const
{
return bs_;
}
//--------------------------------------------------------------------------
#if BOOST_BEAST_DOXYGEN
/// The ConstBufferSequence used to represent the readable bytes.
using const_buffers_type = __implementation_defined__;
/// The MutableBufferSequence used to represent the writable bytes.
using mutable_buffers_type = __implementation_defined__;
#else
class const_buffers_type;
class mutable_buffers_type;
#endif
/// Returns the number of readable bytes.
std::size_t
size() const noexcept
{
return in_size_;
}
/// Return the maximum number of bytes, both readable and writable, that can ever be held.
std::size_t
max_size() const noexcept
{
return max_size_;
}
/// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation.
std::size_t
capacity() const noexcept
{
return max_size_;
}
/// Returns a constant buffer sequence representing the readable bytes
const_buffers_type
data() const noexcept;
/** Returns a mutable buffer sequence representing writable bytes.
Returns a mutable buffer sequence representing the writable
bytes containing exactly `n` bytes of storage. This function
does not allocate memory. Instead, the storage comes from
the underlying mutable buffer sequence.
All buffer sequences previously obtained using @ref prepare are
invalidated. Buffer sequences previously obtained using @ref data
remain valid.
@param n The desired number of bytes in the returned buffer
sequence.
@throws std::length_error if `size() + n` exceeds `max_size()`.
@par Exception Safety
Strong guarantee.
*/
mutable_buffers_type
prepare(std::size_t n);
/** Append writable bytes to the readable bytes.
Appends n bytes from the start of the writable bytes to the
end of the readable bytes. The remainder of the writable bytes
are discarded. If n is greater than the number of writable
bytes, all writable bytes are appended to the readable bytes.
All buffer sequences previously obtained using @ref prepare are
invalidated. Buffer sequences previously obtained using @ref data
remain valid.
@param n The number of bytes to append. If this number
is greater than the number of writable bytes, all
writable bytes are appended.
@par Exception Safety
No-throw guarantee.
*/
void
commit(std::size_t n) noexcept;
/** Remove bytes from beginning of the readable bytes.
Removes n bytes from the beginning of the readable bytes.
All buffers sequences previously obtained using
@ref data or @ref prepare are invalidated.
@param n The number of bytes to remove. If this number
is greater than the number of readable bytes, all
readable bytes are removed.
@par Exception Safety
No-throw guarantee.
*/
void
consume(std::size_t n) noexcept;
};
using buffers_adapter = buffers_adaptor<MutableBufferSequence>;
} // beast
} // boost
#include <boost/beast/core/impl/buffers_adapter.hpp>
#else
// The new filename is <boost/beast/core/buffers_adaptor.hpp>
#error The file <boost/beast/core/buffers_adapter.hpp> is deprecated, define BOOST_BEAST_ALLOW_DEPRECATED to disable this error
#endif
#endif
@@ -0,0 +1,228 @@
//
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_BUFFERS_ADAPTOR_HPP
#define BOOST_BEAST_BUFFERS_ADAPTOR_HPP
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/optional.hpp>
#include <type_traits>
namespace boost {
namespace beast {
/** Adapts a <em>MutableBufferSequence</em> into a <em>DynamicBuffer</em>.
This class wraps a <em>MutableBufferSequence</em> to meet the requirements
of <em>DynamicBuffer</em>. Upon construction the input and output sequences
are empty. A copy of the mutable buffer sequence object is stored; however,
ownership of the underlying memory is not transferred. The caller is
responsible for making sure that referenced memory remains valid
for the duration of any operations.
The size of the mutable buffer sequence determines the maximum
number of bytes which may be prepared and committed.
@tparam MutableBufferSequence The type of mutable buffer sequence to adapt.
*/
template<class MutableBufferSequence>
class buffers_adaptor
{
static_assert(net::is_mutable_buffer_sequence<
MutableBufferSequence>::value,
"MutableBufferSequence requirements not met");
using iter_type = typename
detail::buffer_sequence_iterator<
MutableBufferSequence>::type;
template<bool>
class readable_bytes;
MutableBufferSequence bs_;
iter_type begin_;
iter_type out_;
iter_type end_;
std::size_t max_size_;
std::size_t in_pos_ = 0; // offset in *begin_
std::size_t in_size_ = 0; // size of input sequence
std::size_t out_pos_ = 0; // offset in *out_
std::size_t out_end_ = 0; // output end offset
iter_type end_impl() const;
buffers_adaptor(
buffers_adaptor const& other,
std::size_t nbegin,
std::size_t nout,
std::size_t nend);
public:
/// The type of the underlying mutable buffer sequence
using value_type = MutableBufferSequence;
/** Construct a buffers adaptor.
@param buffers The mutable buffer sequence to wrap. A copy of
the object will be made, but ownership of the memory is not
transferred.
*/
explicit
buffers_adaptor(MutableBufferSequence const& buffers);
/** Constructor
This constructs the buffer adaptor in-place from
a list of arguments.
@param args Arguments forwarded to the buffers constructor.
*/
template<class... Args>
explicit
buffers_adaptor(boost::in_place_init_t, Args&&... args);
/// Copy Constructor
buffers_adaptor(buffers_adaptor const& other);
/// Copy Assignment
buffers_adaptor& operator=(buffers_adaptor const&);
/// Returns the original mutable buffer sequence
value_type const&
value() const
{
return bs_;
}
//--------------------------------------------------------------------------
#if BOOST_BEAST_DOXYGEN
/// The ConstBufferSequence used to represent the readable bytes.
using const_buffers_type = __implementation_defined__;
/// The MutableBufferSequence used to represent the readable bytes.
using mutable_data_type = __implementation_defined__;
/// The MutableBufferSequence used to represent the writable bytes.
using mutable_buffers_type = __implementation_defined__;
#else
using const_buffers_type = readable_bytes<false>;
using mutable_data_type = readable_bytes<true>;
class mutable_buffers_type;
#endif
/// Returns the number of readable bytes.
std::size_t
size() const noexcept
{
return in_size_;
}
/// Return the maximum number of bytes, both readable and writable, that can ever be held.
std::size_t
max_size() const noexcept
{
return max_size_;
}
/// Return the maximum number of bytes, both readable and writable, that can be held without requiring an allocation.
std::size_t
capacity() const noexcept
{
return max_size_;
}
/// Returns a constant buffer sequence representing the readable bytes
const_buffers_type
data() const noexcept;
/// Returns a constant buffer sequence representing the readable bytes
const_buffers_type
cdata() const noexcept
{
return data();
}
/// Returns a mutable buffer sequence representing the readable bytes.
mutable_data_type
data() noexcept;
/** Returns a mutable buffer sequence representing writable bytes.
Returns a mutable buffer sequence representing the writable
bytes containing exactly `n` bytes of storage. This function
does not allocate memory. Instead, the storage comes from
the underlying mutable buffer sequence.
All buffer sequences previously obtained using @ref prepare are
invalidated. Buffer sequences previously obtained using @ref data
remain valid.
@param n The desired number of bytes in the returned buffer
sequence.
@throws std::length_error if `size() + n` exceeds `max_size()`.
@par Exception Safety
Strong guarantee.
*/
mutable_buffers_type
prepare(std::size_t n);
/** Append writable bytes to the readable bytes.
Appends n bytes from the start of the writable bytes to the
end of the readable bytes. The remainder of the writable bytes
are discarded. If n is greater than the number of writable
bytes, all writable bytes are appended to the readable bytes.
All buffer sequences previously obtained using @ref prepare are
invalidated. Buffer sequences previously obtained using @ref data
remain valid.
@param n The number of bytes to append. If this number
is greater than the number of writable bytes, all
writable bytes are appended.
@par Exception Safety
No-throw guarantee.
*/
void
commit(std::size_t n) noexcept;
/** Remove bytes from beginning of the readable bytes.
Removes n bytes from the beginning of the readable bytes.
All buffers sequences previously obtained using
@ref data or @ref prepare are invalidated.
@param n The number of bytes to remove. If this number
is greater than the number of readable bytes, all
readable bytes are removed.
@par Exception Safety
No-throw guarantee.
*/
void
consume(std::size_t n) noexcept;
};
} // beast
} // boost
#include <boost/beast/core/impl/buffers_adaptor.hpp>
#endif
@@ -7,37 +7,84 @@
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_IMPL_BUFFERS_ADAPTER_IPP
#define BOOST_BEAST_IMPL_BUFFERS_ADAPTER_IPP
#ifndef BOOST_BEAST_IMPL_BUFFERS_ADAPTOR_HPP
#define BOOST_BEAST_IMPL_BUFFERS_ADAPTOR_HPP
#include <boost/beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/config/workaround.hpp>
#include <boost/throw_exception.hpp>
#include <algorithm>
#include <cstring>
#include <iterator>
#include <stdexcept>
#include <type_traits>
#include <utility>
namespace boost {
namespace beast {
//------------------------------------------------------------------------------
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
# pragma warning (push)
# pragma warning (disable: 4521) // multiple copy constructors specified
# pragma warning (disable: 4522) // multiple assignment operators specified
#endif
template<class MutableBufferSequence>
class buffers_adapter<MutableBufferSequence>::
const_buffers_type
template<bool isMutable>
class buffers_adaptor<MutableBufferSequence>::
readable_bytes
{
buffers_adapter const* b_;
buffers_adaptor const* b_;
public:
using value_type = net::const_buffer;
using value_type = typename
std::conditional<isMutable,
net::mutable_buffer,
net::const_buffer>::type;
class const_iterator;
const_buffers_type() = delete;
const_buffers_type(
const_buffers_type const&) = default;
const_buffers_type& operator=(
const_buffers_type const&) = default;
readable_bytes() = delete;
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
readable_bytes(
readable_bytes const& other)
: b_(other.b_)
{
}
readable_bytes& operator=(
readable_bytes const& other)
{
b_ = other.b_;
return *this;
}
#else
readable_bytes(
readable_bytes const&) = default;
readable_bytes& operator=(
readable_bytes const&) = default;
#endif
template<bool isMutable_ = isMutable, class =
typename std::enable_if<! isMutable_>::type>
readable_bytes(
readable_bytes<true> const& other) noexcept
: b_(other.b_)
{
}
template<bool isMutable_ = isMutable, class =
typename std::enable_if<! isMutable_>::type>
readable_bytes& operator=(
readable_bytes<true> const& other) noexcept
{
b_ = other.b_;
return *this;
}
const_iterator
begin() const;
@@ -46,23 +93,34 @@ public:
end() const;
private:
friend class buffers_adapter;
friend class buffers_adaptor;
const_buffers_type(buffers_adapter const& b)
readable_bytes(buffers_adaptor const& b)
: b_(&b)
{
}
};
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
# pragma warning (pop)
#endif
//------------------------------------------------------------------------------
template<class MutableBufferSequence>
class buffers_adapter<MutableBufferSequence>::
const_buffers_type::const_iterator
template<bool isMutable>
class buffers_adaptor<MutableBufferSequence>::
readable_bytes<isMutable>::
const_iterator
{
iter_type it_;
buffers_adapter const* b_ = nullptr;
buffers_adaptor const* b_ = nullptr;
public:
using value_type = net::const_buffer;
using value_type = typename
std::conditional<isMutable,
net::mutable_buffer,
net::const_buffer>::type;
using pointer = value_type const*;
using reference = value_type;
using difference_type = std::ptrdiff_t;
@@ -70,28 +128,13 @@ public:
std::bidirectional_iterator_tag;
const_iterator() = default;
const_iterator(const_iterator&& other) = default;
const_iterator(const_iterator const& other) = default;
const_iterator& operator=(const_iterator&& other) = default;
const_iterator& operator=(const_iterator const& other) = default;
bool
operator==(const_iterator const& other) const
{
return
(b_ == nullptr) ?
(
other.b_ == nullptr ||
other.it_ == other.b_->end_impl()
):(
(other.b_ == nullptr) ?
(
it_ == b_->end_impl()
): (
b_ == other.b_ &&
it_ == other.it_
)
);
return b_ == other.b_ && it_ == other.it_;
}
bool
@@ -144,10 +187,11 @@ public:
}
private:
friend class const_buffers_type;
friend class readable_bytes;
const_iterator(buffers_adapter const& b,
iter_type iter)
const_iterator(
buffers_adaptor const& b,
iter_type iter)
: it_(iter)
, b_(&b)
{
@@ -155,18 +199,22 @@ private:
};
template<class MutableBufferSequence>
template<bool isMutable>
auto
buffers_adapter<MutableBufferSequence>::
const_buffers_type::begin() const ->
buffers_adaptor<MutableBufferSequence>::
readable_bytes<isMutable>::
begin() const ->
const_iterator
{
return const_iterator{*b_, b_->begin_};
}
template<class MutableBufferSequence>
template<bool isMutable>
auto
buffers_adapter<MutableBufferSequence>::
const_buffers_type::end() const ->
buffers_adaptor<MutableBufferSequence>::
readable_bytes<isMutable>::
readable_bytes::end() const ->
const_iterator
{
return const_iterator{*b_, b_->end_impl()};
@@ -175,10 +223,10 @@ const_buffers_type::end() const ->
//------------------------------------------------------------------------------
template<class MutableBufferSequence>
class buffers_adapter<MutableBufferSequence>::
class buffers_adaptor<MutableBufferSequence>::
mutable_buffers_type
{
buffers_adapter const* b_;
buffers_adaptor const* b_;
public:
using value_type = net::mutable_buffer;
@@ -198,21 +246,21 @@ public:
end() const;
private:
friend class buffers_adapter;
friend class buffers_adaptor;
mutable_buffers_type(
buffers_adapter const& b)
buffers_adaptor const& b)
: b_(&b)
{
}
};
template<class MutableBufferSequence>
class buffers_adapter<MutableBufferSequence>::
class buffers_adaptor<MutableBufferSequence>::
mutable_buffers_type::const_iterator
{
iter_type it_;
buffers_adapter const* b_ = nullptr;
buffers_adaptor const* b_ = nullptr;
public:
using value_type = net::mutable_buffer;
@@ -223,28 +271,13 @@ public:
std::bidirectional_iterator_tag;
const_iterator() = default;
const_iterator(const_iterator&& other) = default;
const_iterator(const_iterator const& other) = default;
const_iterator& operator=(const_iterator&& other) = default;
const_iterator& operator=(const_iterator const& other) = default;
bool
operator==(const_iterator const& other) const
{
return
(b_ == nullptr) ?
(
other.b_ == nullptr ||
other.it_ == other.b_->end_
):(
(other.b_ == nullptr) ?
(
it_ == b_->end_
): (
b_ == other.b_ &&
it_ == other.it_
)
);
return b_ == other.b_ && it_ == other.it_;
}
bool
@@ -299,7 +332,7 @@ public:
private:
friend class mutable_buffers_type;
const_iterator(buffers_adapter const& b,
const_iterator(buffers_adaptor const& b,
iter_type iter)
: it_(iter)
, b_(&b)
@@ -309,7 +342,7 @@ private:
template<class MutableBufferSequence>
auto
buffers_adapter<MutableBufferSequence>::
buffers_adaptor<MutableBufferSequence>::
mutable_buffers_type::
begin() const ->
const_iterator
@@ -319,7 +352,7 @@ begin() const ->
template<class MutableBufferSequence>
auto
buffers_adapter<MutableBufferSequence>::
buffers_adaptor<MutableBufferSequence>::
mutable_buffers_type::
end() const ->
const_iterator
@@ -331,7 +364,7 @@ end() const ->
template<class MutableBufferSequence>
auto
buffers_adapter<MutableBufferSequence>::
buffers_adaptor<MutableBufferSequence>::
end_impl() const ->
iter_type
{
@@ -339,57 +372,75 @@ end_impl() const ->
}
template<class MutableBufferSequence>
buffers_adapter<MutableBufferSequence>::
buffers_adapter(buffers_adapter&& other)
: buffers_adapter(std::move(other),
std::distance<iter_type>(net::buffer_sequence_begin(other.bs_), other.begin_),
std::distance<iter_type>(net::buffer_sequence_begin(other.bs_), other.out_),
std::distance<iter_type>(net::buffer_sequence_begin(other.bs_), other.end_))
buffers_adaptor<MutableBufferSequence>::
buffers_adaptor(
buffers_adaptor const& other,
std::size_t nbegin,
std::size_t nout,
std::size_t nend)
: bs_(other.bs_)
, begin_(std::next(bs_.begin(), nbegin))
, out_(std::next(bs_.begin(), nout))
, end_(std::next(bs_.begin(), nend))
, max_size_(other.max_size_)
, in_pos_(other.in_pos_)
, in_size_(other.in_size_)
, out_pos_(other.out_pos_)
, out_end_(other.out_end_)
{
}
template<class MutableBufferSequence>
buffers_adapter<MutableBufferSequence>::
buffers_adapter(buffers_adapter const& other)
: buffers_adapter(other,
std::distance<iter_type>(net::buffer_sequence_begin(other.bs_), other.begin_),
std::distance<iter_type>(net::buffer_sequence_begin(other.bs_), other.out_),
std::distance<iter_type>(net::buffer_sequence_begin(other.bs_), other.end_))
buffers_adaptor<MutableBufferSequence>::
buffers_adaptor(MutableBufferSequence const& bs)
: bs_(bs)
, begin_(net::buffer_sequence_begin(bs_))
, out_ (net::buffer_sequence_begin(bs_))
, end_ (net::buffer_sequence_begin(bs_))
, max_size_(
[&bs]
{
using net::buffer_size;
return buffer_size(bs);
}())
{
}
template<class MutableBufferSequence>
template<class... Args>
buffers_adaptor<MutableBufferSequence>::
buffers_adaptor(
boost::in_place_init_t, Args&&... args)
: bs_{std::forward<Args>(args)...}
, begin_(net::buffer_sequence_begin(bs_))
, out_ (net::buffer_sequence_begin(bs_))
, end_ (net::buffer_sequence_begin(bs_))
, max_size_(net::buffer_size(bs_))
{
}
template<class MutableBufferSequence>
buffers_adaptor<MutableBufferSequence>::
buffers_adaptor(buffers_adaptor const& other)
: buffers_adaptor(
other,
std::distance<iter_type>(
net::buffer_sequence_begin(other.bs_),
other.begin_),
std::distance<iter_type>(
net::buffer_sequence_begin(other.bs_),
other.out_),
std::distance<iter_type>(
net::buffer_sequence_begin(other.bs_),
other.end_))
{
}
template<class MutableBufferSequence>
auto
buffers_adapter<MutableBufferSequence>::
operator=(buffers_adapter&& other) ->
buffers_adapter&
{
auto const nbegin = std::distance<iter_type>(
net::buffer_sequence_begin(other.bs_),
other.begin_);
auto const nout = std::distance<iter_type>(
net::buffer_sequence_begin(other.bs_),
other.out_);
auto const nend = std::distance<iter_type>(
net::buffer_sequence_begin(other.bs_),
other.end_);
bs_ = std::move(other.bs_);
begin_ = std::next(net::buffer_sequence_begin(bs_), nbegin);
out_ = std::next(net::buffer_sequence_begin(bs_), nout);
end_ = std::next(net::buffer_sequence_begin(bs_), nend);
max_size_ = other.max_size_;
in_pos_ = other.in_pos_;
in_size_ = other.in_size_;
out_pos_ = other.out_pos_;
out_end_ = other.out_end_;
return *this;
}
template<class MutableBufferSequence>
auto
buffers_adapter<MutableBufferSequence>::
operator=(buffers_adapter const& other) ->
buffers_adapter&
buffers_adaptor<MutableBufferSequence>::
operator=(buffers_adaptor const& other) ->
buffers_adaptor&
{
auto const nbegin = std::distance<iter_type>(
net::buffer_sequence_begin(other.bs_),
@@ -401,9 +452,12 @@ operator=(buffers_adapter const& other) ->
net::buffer_sequence_begin(other.bs_),
other.end_);
bs_ = other.bs_;
begin_ = std::next(net::buffer_sequence_begin(bs_), nbegin);
out_ = std::next(net::buffer_sequence_begin(bs_), nout);
end_ = std::next(net::buffer_sequence_begin(bs_), nend);
begin_ = std::next(
net::buffer_sequence_begin(bs_), nbegin);
out_ = std::next(
net::buffer_sequence_begin(bs_), nout);
end_ = std::next(
net::buffer_sequence_begin(bs_), nend);
max_size_ = other.max_size_;
in_pos_ = other.in_pos_;
in_size_ = other.in_size_;
@@ -412,47 +466,43 @@ operator=(buffers_adapter const& other) ->
return *this;
}
template<class MutableBufferSequence>
buffers_adapter<MutableBufferSequence>::
buffers_adapter(MutableBufferSequence const& bs)
: bs_(bs)
, begin_(net::buffer_sequence_begin(bs_))
, out_ (net::buffer_sequence_begin(bs_))
, end_ (net::buffer_sequence_begin(bs_))
, max_size_(net::buffer_size(bs_))
{
}
//
template<class MutableBufferSequence>
template<class... Args>
buffers_adapter<MutableBufferSequence>::
buffers_adapter(boost::in_place_init_t, Args&&... args)
: bs_{std::forward<Args>(args)...}
, begin_(net::buffer_sequence_begin(bs_))
, out_ (net::buffer_sequence_begin(bs_))
, end_ (net::buffer_sequence_begin(bs_))
, max_size_(net::buffer_size(bs_))
auto
buffers_adaptor<MutableBufferSequence>::
data() const noexcept ->
const_buffers_type
{
return const_buffers_type{*this};
}
template<class MutableBufferSequence>
auto
buffers_adapter<MutableBufferSequence>::
buffers_adaptor<MutableBufferSequence>::
data() noexcept ->
mutable_data_type
{
return mutable_data_type{*this};
}
template<class MutableBufferSequence>
auto
buffers_adaptor<MutableBufferSequence>::
prepare(std::size_t n) ->
mutable_buffers_type
{
using net::buffer_size;
end_ = out_;
if(end_ != net::buffer_sequence_end(bs_))
{
auto size = buffer_size(*end_) - out_pos_;
auto size = net::buffer_size(*end_) - out_pos_;
if(n > size)
{
n -= size;
while(++end_ !=
net::buffer_sequence_end(bs_))
{
size = buffer_size(*end_);
size = net::buffer_size(*end_);
if(n < size)
{
out_end_ = n;
@@ -473,22 +523,13 @@ prepare(std::size_t n) ->
}
if(n > 0)
BOOST_THROW_EXCEPTION(std::length_error{
"buffer overflow"});
"buffers_adaptor too long"});
return mutable_buffers_type{*this};
}
template<class MutableBufferSequence>
auto
buffers_adapter<MutableBufferSequence>::
data() const noexcept ->
const_buffers_type
{
return const_buffers_type{*this};
}
template<class MutableBufferSequence>
void
buffers_adapter<MutableBufferSequence>::
buffers_adaptor<MutableBufferSequence>::
commit(std::size_t n) noexcept
{
if(out_ == end_)
@@ -524,7 +565,7 @@ commit(std::size_t n) noexcept
template<class MutableBufferSequence>
void
buffers_adapter<MutableBufferSequence>::
buffers_adaptor<MutableBufferSequence>::
consume(std::size_t n) noexcept
{
while(begin_ != out_)