summaryrefslogtreecommitdiff
path: root/boost/beast/core/impl/multi_buffer.ipp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/beast/core/impl/multi_buffer.ipp')
-rw-r--r--boost/beast/core/impl/multi_buffer.ipp1060
1 files changed, 0 insertions, 1060 deletions
diff --git a/boost/beast/core/impl/multi_buffer.ipp b/boost/beast/core/impl/multi_buffer.ipp
deleted file mode 100644
index fb48424a3a..0000000000
--- a/boost/beast/core/impl/multi_buffer.ipp
+++ /dev/null
@@ -1,1060 +0,0 @@
-//
-// 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_IMPL_MULTI_BUFFER_IPP
-#define BOOST_BEAST_IMPL_MULTI_BUFFER_IPP
-
-#include <boost/beast/core/detail/type_traits.hpp>
-#include <boost/core/exchange.hpp>
-#include <boost/assert.hpp>
-#include <boost/throw_exception.hpp>
-#include <algorithm>
-#include <exception>
-#include <sstream>
-#include <string>
-#include <utility>
-
-namespace boost {
-namespace beast {
-
-/* These diagrams illustrate the layout and state variables.
-
-1 Input and output contained entirely in one element:
-
- 0 out_
- |<-------------+------------------------------------------->|
- in_pos_ out_pos_ out_end_
-
-
-2 Output contained in first and second elements:
-
- out_
- |<------+----------+------->| |<----------+-------------->|
- in_pos_ out_pos_ out_end_
-
-
-3 Output contained in the second element:
-
- out_
- |<------------+------------>| |<----+-------------------->|
- in_pos_ out_pos_ out_end_
-
-
-4 Output contained in second and third elements:
-
- out_
- |<-----+-------->| |<-------+------>| |<--------------->|
- in_pos_ out_pos_ out_end_
-
-
-5 Input sequence is empty:
-
- out_
- |<------+------------------>| |<-----------+------------->|
- out_pos_ out_end_
- in_pos_
-
-
-6 Output sequence is empty:
-
- out_
- |<------+------------------>| |<------+------------------>|
- in_pos_ out_pos_
- out_end_
-
-
-7 The end of output can point to the end of an element.
- But out_pos_ should never point to the end:
-
- out_
- |<------+------------------>| |<------+------------------>|
- in_pos_ out_pos_ out_end_
-
-
-8 When the input sequence entirely fills the last element and
- the output sequence is empty, out_ will point to the end of
- the list of buffers, and out_pos_ and out_end_ will be 0:
-
-
- |<------+------------------>| out_ == list_.end()
- in_pos_ out_pos_ == 0
- out_end_ == 0
-*/
-
-template<class Allocator>
-class basic_multi_buffer<Allocator>::element
- : public boost::intrusive::list_base_hook<
- boost::intrusive::link_mode<
- boost::intrusive::normal_link>>
-{
- using size_type =
- typename detail::allocator_traits<Allocator>::size_type;
-
- size_type const size_;
-
-public:
- element(element const&) = delete;
- element& operator=(element const&) = delete;
-
- explicit
- element(size_type n)
- : size_(n)
- {
- }
-
- size_type
- size() const
- {
- return size_;
- }
-
- char*
- data() const
- {
- return const_cast<char*>(
- reinterpret_cast<char const*>(this + 1));
- }
-};
-
-template<class Allocator>
-class basic_multi_buffer<Allocator>::const_buffers_type
-{
- basic_multi_buffer const* b_;
-
- friend class basic_multi_buffer;
-
- explicit
- const_buffers_type(basic_multi_buffer const& b);
-
-public:
- using value_type = boost::asio::const_buffer;
-
- class const_iterator;
-
- const_buffers_type() = delete;
- const_buffers_type(const_buffers_type const&) = default;
- const_buffers_type& operator=(const_buffers_type const&) = default;
-
- const_iterator
- begin() const;
-
- const_iterator
- end() const;
-
- friend
- std::size_t
- buffer_size(const_buffers_type const& buffers)
- {
- return buffers.b_->size();
- }
-};
-
-template<class Allocator>
-class basic_multi_buffer<Allocator>::mutable_buffers_type
-{
- basic_multi_buffer const* b_;
-
- friend class basic_multi_buffer;
-
- explicit
- mutable_buffers_type(basic_multi_buffer const& b);
-
-public:
- using value_type = mutable_buffer;
-
- class const_iterator;
-
- mutable_buffers_type() = delete;
- mutable_buffers_type(mutable_buffers_type const&) = default;
- mutable_buffers_type& operator=(mutable_buffers_type const&) = default;
-
- const_iterator
- begin() const;
-
- const_iterator
- end() const;
-};
-
-//------------------------------------------------------------------------------
-
-template<class Allocator>
-class basic_multi_buffer<Allocator>::const_buffers_type::const_iterator
-{
- basic_multi_buffer const* b_ = nullptr;
- typename list_type::const_iterator it_;
-
-public:
- using value_type =
- typename const_buffers_type::value_type;
- using pointer = value_type const*;
- using reference = value_type;
- using difference_type = std::ptrdiff_t;
- using iterator_category =
- 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;
-
- const_iterator(basic_multi_buffer const& b,
- typename list_type::const_iterator const& it)
- : b_(&b)
- , it_(it)
- {
- }
-
- bool
- operator==(const_iterator const& other) const
- {
- return b_ == other.b_ && it_ == other.it_;
- }
-
- bool
- operator!=(const_iterator const& other) const
- {
- return !(*this == other);
- }
-
- reference
- operator*() const
- {
- auto const& e = *it_;
- return value_type{e.data(),
- (b_->out_ == b_->list_.end() ||
- &e != &*b_->out_) ? e.size() : b_->out_pos_} +
- (&e == &*b_->list_.begin() ? b_->in_pos_ : 0);
- }
-
- pointer
- operator->() const = delete;
-
- const_iterator&
- operator++()
- {
- ++it_;
- return *this;
- }
-
- const_iterator
- operator++(int)
- {
- auto temp = *this;
- ++(*this);
- return temp;
- }
-
- const_iterator&
- operator--()
- {
- --it_;
- return *this;
- }
-
- const_iterator
- operator--(int)
- {
- auto temp = *this;
- --(*this);
- return temp;
- }
-};
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-const_buffers_type::
-const_buffers_type(
- basic_multi_buffer const& b)
- : b_(&b)
-{
-}
-
-template<class Allocator>
-auto
-basic_multi_buffer<Allocator>::
-const_buffers_type::
-begin() const ->
- const_iterator
-{
- return const_iterator{*b_, b_->list_.begin()};
-}
-
-template<class Allocator>
-auto
-basic_multi_buffer<Allocator>::
-const_buffers_type::
-end() const ->
- const_iterator
-{
- return const_iterator{*b_, b_->out_ ==
- b_->list_.end() ? b_->list_.end() :
- std::next(b_->out_)};
-}
-
-//------------------------------------------------------------------------------
-
-template<class Allocator>
-class basic_multi_buffer<Allocator>::mutable_buffers_type::const_iterator
-{
- basic_multi_buffer const* b_ = nullptr;
- typename list_type::const_iterator it_;
-
-public:
- using value_type =
- typename mutable_buffers_type::value_type;
- using pointer = value_type const*;
- using reference = value_type;
- using difference_type = std::ptrdiff_t;
- using iterator_category =
- 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;
-
- const_iterator(basic_multi_buffer const& b,
- typename list_type::const_iterator const& it)
- : b_(&b)
- , it_(it)
- {
- }
-
- bool
- operator==(const_iterator const& other) const
- {
- return b_ == other.b_ && it_ == other.it_;
- }
-
- bool
- operator!=(const_iterator const& other) const
- {
- return !(*this == other);
- }
-
- reference
- operator*() const
- {
- auto const& e = *it_;
- return value_type{e.data(),
- &e == &*std::prev(b_->list_.end()) ?
- b_->out_end_ : e.size()} +
- (&e == &*b_->out_ ? b_->out_pos_ : 0);
- }
-
- pointer
- operator->() const = delete;
-
- const_iterator&
- operator++()
- {
- ++it_;
- return *this;
- }
-
- const_iterator
- operator++(int)
- {
- auto temp = *this;
- ++(*this);
- return temp;
- }
-
- const_iterator&
- operator--()
- {
- --it_;
- return *this;
- }
-
- const_iterator
- operator--(int)
- {
- auto temp = *this;
- --(*this);
- return temp;
- }
-};
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-mutable_buffers_type::
-mutable_buffers_type(
- basic_multi_buffer const& b)
- : b_(&b)
-{
-}
-
-template<class Allocator>
-auto
-basic_multi_buffer<Allocator>::
-mutable_buffers_type::
-begin() const ->
- const_iterator
-{
- return const_iterator{*b_, b_->out_};
-}
-
-template<class Allocator>
-auto
-basic_multi_buffer<Allocator>::
-mutable_buffers_type::
-end() const ->
- const_iterator
-{
- return const_iterator{*b_, b_->list_.end()};
-}
-
-//------------------------------------------------------------------------------
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-~basic_multi_buffer()
-{
- delete_list();
-}
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer()
- : out_(list_.end())
-{
-}
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer(std::size_t limit)
- : max_(limit)
- , out_(list_.end())
-{
-}
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer(Allocator const& alloc)
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), alloc)
- , out_(list_.end())
-{
-}
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer(std::size_t limit,
- Allocator const& alloc)
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), alloc)
- , max_(limit)
- , out_(list_.end())
-{
-}
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer(basic_multi_buffer&& other)
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), std::move(other.get()))
- , max_(other.max_)
- , in_size_(boost::exchange(other.in_size_, 0))
- , in_pos_(boost::exchange(other.in_pos_, 0))
- , out_pos_(boost::exchange(other.out_pos_, 0))
- , out_end_(boost::exchange(other.out_end_, 0))
-{
- auto const at_end =
- other.out_ == other.list_.end();
- list_ = std::move(other.list_);
- out_ = at_end ? list_.end() : other.out_;
- other.out_ = other.list_.end();
-}
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer(basic_multi_buffer&& other,
- Allocator const& alloc)
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), alloc)
- , max_(other.max_)
-{
- if(this->get() != other.get())
- {
- out_ = list_.end();
- copy_from(other);
- other.reset();
- }
- else
- {
- auto const at_end =
- other.out_ == other.list_.end();
- list_ = std::move(other.list_);
- out_ = at_end ? list_.end() : other.out_;
- in_size_ = other.in_size_;
- in_pos_ = other.in_pos_;
- out_pos_ = other.out_pos_;
- out_end_ = other.out_end_;
- other.in_size_ = 0;
- other.out_ = other.list_.end();
- other.in_pos_ = 0;
- other.out_pos_ = 0;
- other.out_end_ = 0;
- }
-}
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer(basic_multi_buffer const& other)
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), alloc_traits::
- select_on_container_copy_construction(
- other.get()))
- , max_(other.max_)
- , out_(list_.end())
-{
- copy_from(other);
-}
-
-template<class Allocator>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer(basic_multi_buffer const& other,
- Allocator const& alloc)
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), alloc)
- , max_(other.max_)
- , out_(list_.end())
-{
- copy_from(other);
-}
-
-template<class Allocator>
-template<class OtherAlloc>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer(
- basic_multi_buffer<OtherAlloc> const& other)
- : out_(list_.end())
-{
- copy_from(other);
-}
-
-template<class Allocator>
-template<class OtherAlloc>
-basic_multi_buffer<Allocator>::
-basic_multi_buffer(
- basic_multi_buffer<OtherAlloc> const& other,
- allocator_type const& alloc)
- : boost::empty_value<
- base_alloc_type>(boost::empty_init_t(), alloc)
- , max_(other.max_)
- , out_(list_.end())
-{
- copy_from(other);
-}
-
-template<class Allocator>
-auto
-basic_multi_buffer<Allocator>::
-operator=(basic_multi_buffer&& other) ->
- basic_multi_buffer&
-{
- if(this == &other)
- return *this;
- reset();
- max_ = other.max_;
- move_assign(other, std::integral_constant<bool,
- alloc_traits::propagate_on_container_move_assignment::value>{});
- return *this;
-}
-
-template<class Allocator>
-auto
-basic_multi_buffer<Allocator>::
-operator=(basic_multi_buffer const& other) ->
-basic_multi_buffer&
-{
- if(this == &other)
- return *this;
- copy_assign(other, std::integral_constant<bool,
- alloc_traits::propagate_on_container_copy_assignment::value>{});
- return *this;
-}
-
-template<class Allocator>
-template<class OtherAlloc>
-auto
-basic_multi_buffer<Allocator>::
-operator=(
- basic_multi_buffer<OtherAlloc> const& other) ->
- basic_multi_buffer&
-{
- reset();
- max_ = other.max_;
- copy_from(other);
- return *this;
-}
-
-template<class Allocator>
-std::size_t
-basic_multi_buffer<Allocator>::
-capacity() const
-{
- auto pos = out_;
- if(pos == list_.end())
- return in_size_;
- auto n = pos->size() - out_pos_;
- while(++pos != list_.end())
- n += pos->size();
- return in_size_ + n;
-}
-
-template<class Allocator>
-auto
-basic_multi_buffer<Allocator>::
-data() const ->
- const_buffers_type
-{
- return const_buffers_type(*this);
-}
-
-template<class Allocator>
-auto
-basic_multi_buffer<Allocator>::
-prepare(size_type n) ->
- mutable_buffers_type
-{
- if(in_size_ + n > max_)
- BOOST_THROW_EXCEPTION(std::length_error{
- "dynamic buffer overflow"});
- list_type reuse;
- std::size_t total = in_size_;
- // put all empty buffers on reuse list
- if(out_ != list_.end())
- {
- total += out_->size() - out_pos_;
- if(out_ != list_.iterator_to(list_.back()))
- {
- out_end_ = out_->size();
- reuse.splice(reuse.end(), list_,
- std::next(out_), list_.end());
- #if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
- #endif
- }
- auto const avail = out_->size() - out_pos_;
- if(n > avail)
- {
- out_end_ = out_->size();
- n -= avail;
- }
- else
- {
- out_end_ = out_pos_ + n;
- n = 0;
- }
- #if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
- #endif
- }
- // get space from reuse buffers
- while(n > 0 && ! reuse.empty())
- {
- auto& e = reuse.front();
- reuse.erase(reuse.iterator_to(e));
- list_.push_back(e);
- total += e.size();
- if(n > e.size())
- {
- out_end_ = e.size();
- n -= e.size();
- }
- else
- {
- out_end_ = n;
- n = 0;
- }
- #if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
- #endif
- }
- BOOST_ASSERT(total <= max_);
- if(! reuse.empty() || n > 0)
- {
- for(auto it = reuse.begin(); it != reuse.end();)
- {
- auto& e = *it++;
- reuse.erase(list_.iterator_to(e));
- auto const len = sizeof(e) + e.size();
- alloc_traits::destroy(this->get(), &e);
- alloc_traits::deallocate(this->get(),
- reinterpret_cast<char*>(&e), len);
- }
- if(n > 0)
- {
- static auto const growth_factor = 2.0f;
- auto const size =
- (std::min<std::size_t>)(
- max_ - total,
- (std::max<std::size_t>)({
- static_cast<std::size_t>(
- in_size_ * growth_factor - in_size_),
- 512,
- n}));
- auto& e = *reinterpret_cast<element*>(static_cast<
- void*>(alloc_traits::allocate(this->get(),
- sizeof(element) + size)));
- alloc_traits::construct(this->get(), &e, size);
- list_.push_back(e);
- if(out_ == list_.end())
- out_ = list_.iterator_to(e);
- out_end_ = n;
- #if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
- #endif
- }
- }
- return mutable_buffers_type(*this);
-}
-
-template<class Allocator>
-void
-basic_multi_buffer<Allocator>::
-commit(size_type n)
-{
- if(list_.empty())
- return;
- if(out_ == list_.end())
- return;
- auto const back =
- list_.iterator_to(list_.back());
- while(out_ != back)
- {
- auto const avail =
- out_->size() - out_pos_;
- if(n < avail)
- {
- out_pos_ += n;
- in_size_ += n;
- #if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
- #endif
- return;
- }
- ++out_;
- n -= avail;
- out_pos_ = 0;
- in_size_ += avail;
- #if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
- #endif
- }
-
- n = (std::min)(n, out_end_ - out_pos_);
- out_pos_ += n;
- in_size_ += n;
- if(out_pos_ == out_->size())
- {
- ++out_;
- out_pos_ = 0;
- out_end_ = 0;
- }
-#if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
-#endif
-}
-
-template<class Allocator>
-void
-basic_multi_buffer<Allocator>::
-consume(size_type n)
-{
- if(list_.empty())
- return;
- for(;;)
- {
- if(list_.begin() != out_)
- {
- auto const avail =
- list_.front().size() - in_pos_;
- if(n < avail)
- {
- in_size_ -= n;
- in_pos_ += n;
- #if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
- #endif
- break;
- }
- n -= avail;
- in_size_ -= avail;
- in_pos_ = 0;
- auto& e = list_.front();
- list_.erase(list_.iterator_to(e));
- auto const len = sizeof(e) + e.size();
- alloc_traits::destroy(this->get(), &e);
- alloc_traits::deallocate(this->get(),
- reinterpret_cast<char*>(&e), len);
- #if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
- #endif
- }
- else
- {
- auto const avail = out_pos_ - in_pos_;
- if(n < avail)
- {
- in_size_ -= n;
- in_pos_ += n;
- }
- else
- {
- in_size_ = 0;
- if(out_ != list_.iterator_to(list_.back()) ||
- out_pos_ != out_end_)
- {
- in_pos_ = out_pos_;
- }
- else
- {
- // Input and output sequences are empty, reuse buffer.
- // Alternatively we could deallocate it.
- in_pos_ = 0;
- out_pos_ = 0;
- out_end_ = 0;
- }
- }
- #if BOOST_BEAST_MULTI_BUFFER_DEBUG_CHECK
- debug_check();
- #endif
- break;
- }
- }
-}
-
-template<class Allocator>
-inline
-void
-basic_multi_buffer<Allocator>::
-delete_list()
-{
- for(auto iter = list_.begin(); iter != list_.end();)
- {
- auto& e = *iter++;
- auto const len = sizeof(e) + e.size();
- alloc_traits::destroy(this->get(), &e);
- alloc_traits::deallocate(this->get(),
- reinterpret_cast<char*>(&e), len);
- }
-}
-
-template<class Allocator>
-inline
-void
-basic_multi_buffer<Allocator>::
-reset()
-{
- delete_list();
- list_.clear();
- out_ = list_.end();
- in_size_ = 0;
- in_pos_ = 0;
- out_pos_ = 0;
- out_end_ = 0;
-}
-
-template<class Allocator>
-template<class DynamicBuffer>
-inline
-void
-basic_multi_buffer<Allocator>::
-copy_from(DynamicBuffer const& buffer)
-{
- if(buffer.size() == 0)
- return;
- using boost::asio::buffer_copy;
- commit(buffer_copy(
- prepare(buffer.size()), buffer.data()));
-}
-
-template<class Allocator>
-inline
-void
-basic_multi_buffer<Allocator>::
-move_assign(basic_multi_buffer& other, std::false_type)
-{
- if(this->get() != other.get())
- {
- copy_from(other);
- other.reset();
- }
- else
- {
- move_assign(other, std::true_type{});
- }
-}
-
-template<class Allocator>
-inline
-void
-basic_multi_buffer<Allocator>::
-move_assign(basic_multi_buffer& other, std::true_type)
-{
- this->get() = std::move(other.get());
- auto const at_end =
- other.out_ == other.list_.end();
- list_ = std::move(other.list_);
- out_ = at_end ? list_.end() : other.out_;
-
- in_size_ = other.in_size_;
- in_pos_ = other.in_pos_;
- out_pos_ = other.out_pos_;
- out_end_ = other.out_end_;
-
- other.in_size_ = 0;
- other.out_ = other.list_.end();
- other.in_pos_ = 0;
- other.out_pos_ = 0;
- other.out_end_ = 0;
-}
-
-template<class Allocator>
-inline
-void
-basic_multi_buffer<Allocator>::
-copy_assign(
- basic_multi_buffer const& other, std::false_type)
-{
- reset();
- max_ = other.max_;
- copy_from(other);
-}
-
-template<class Allocator>
-inline
-void
-basic_multi_buffer<Allocator>::
-copy_assign(
- basic_multi_buffer const& other, std::true_type)
-{
- reset();
- max_ = other.max_;
- this->get() = other.get();
- copy_from(other);
-}
-
-template<class Allocator>
-inline
-void
-basic_multi_buffer<Allocator>::
-swap(basic_multi_buffer& other)
-{
- swap(other, typename
- alloc_traits::propagate_on_container_swap{});
-}
-
-template<class Allocator>
-inline
-void
-basic_multi_buffer<Allocator>::
-swap(basic_multi_buffer& other, std::true_type)
-{
- using std::swap;
- auto const at_end0 =
- out_ == list_.end();
- auto const at_end1 =
- other.out_ == other.list_.end();
- swap(this->get(), other.get());
- swap(list_, other.list_);
- swap(out_, other.out_);
- if(at_end1)
- out_ = list_.end();
- if(at_end0)
- other.out_ = other.list_.end();
- swap(in_size_, other.in_size_);
- swap(in_pos_, other.in_pos_);
- swap(out_pos_, other.out_pos_);
- swap(out_end_, other.out_end_);
-}
-
-template<class Allocator>
-inline
-void
-basic_multi_buffer<Allocator>::
-swap(basic_multi_buffer& other, std::false_type)
-{
- BOOST_ASSERT(this->get() == other.get());
- using std::swap;
- auto const at_end0 =
- out_ == list_.end();
- auto const at_end1 =
- other.out_ == other.list_.end();
- swap(list_, other.list_);
- swap(out_, other.out_);
- if(at_end1)
- out_ = list_.end();
- if(at_end0)
- other.out_ = other.list_.end();
- swap(in_size_, other.in_size_);
- swap(in_pos_, other.in_pos_);
- swap(out_pos_, other.out_pos_);
- swap(out_end_, other.out_end_);
-}
-
-template<class Allocator>
-void
-swap(
- basic_multi_buffer<Allocator>& lhs,
- basic_multi_buffer<Allocator>& rhs)
-{
- lhs.swap(rhs);
-}
-
-template<class Allocator>
-void
-basic_multi_buffer<Allocator>::
-debug_check() const
-{
-#ifndef NDEBUG
- using boost::asio::buffer_size;
- BOOST_ASSERT(buffer_size(data()) == in_size_);
- if(list_.empty())
- {
- BOOST_ASSERT(in_pos_ == 0);
- BOOST_ASSERT(in_size_ == 0);
- BOOST_ASSERT(out_pos_ == 0);
- BOOST_ASSERT(out_end_ == 0);
- BOOST_ASSERT(out_ == list_.end());
- return;
- }
-
- auto const& front = list_.front();
-
- BOOST_ASSERT(in_pos_ < front.size());
-
- if(out_ == list_.end())
- {
- BOOST_ASSERT(out_pos_ == 0);
- BOOST_ASSERT(out_end_ == 0);
- }
- else
- {
- auto const& out = *out_;
- auto const& back = list_.back();
-
- BOOST_ASSERT(out_end_ <= back.size());
- BOOST_ASSERT(out_pos_ < out.size());
- BOOST_ASSERT(&out != &front || out_pos_ >= in_pos_);
- BOOST_ASSERT(&out != &front || out_pos_ - in_pos_ == in_size_);
- BOOST_ASSERT(&out != &back || out_pos_ <= out_end_);
- }
-#endif
-}
-
-} // beast
-} // boost
-
-#endif