multi_buffer is type-check friendly

This commit is contained in:
Vinnie Falco
2017-07-17 18:16:50 -07:00
parent ed7c095df9
commit 5e4a5592f3
3 changed files with 34 additions and 40 deletions

View File

@@ -2,6 +2,7 @@ Version 84:
* Tidy up buffer_front
* static_buffer::consume improvement
* multi_buffer is type-check friendly
--------------------------------------------------------------------------------

View File

@@ -436,9 +436,8 @@ basic_multi_buffer(std::size_t limit)
template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(Allocator const& alloc)
: detail::empty_base_optimization<
allocator_type>(alloc)
, out_(list_.end())
: out_(list_.end())
, alloc_(alloc)
{
}
@@ -446,23 +445,21 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(std::size_t limit,
Allocator const& alloc)
: detail::empty_base_optimization<
allocator_type>(alloc)
, max_(limit)
: max_(limit)
, out_(list_.end())
, alloc_(alloc)
{
}
template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(basic_multi_buffer&& other)
: detail::empty_base_optimization<allocator_type>(
std::move(other.member()))
, max_(other.max_)
: max_(other.max_)
, in_size_(other.in_size_)
, in_pos_(other.in_pos_)
, out_pos_(other.out_pos_)
, out_end_(other.out_end_)
, alloc_(std::move(other.alloc_))
{
auto const at_end =
other.out_ == other.list_.end();
@@ -479,10 +476,10 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(basic_multi_buffer&& other,
Allocator const& alloc)
: detail::empty_base_optimization<allocator_type>(alloc)
, max_(other.max_)
: max_(other.max_)
, alloc_(alloc)
{
if(this->member() != other.member())
if(alloc_ != other.alloc_)
{
out_ = list_.end();
copy_from(other);
@@ -509,10 +506,11 @@ basic_multi_buffer(basic_multi_buffer&& other,
template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(basic_multi_buffer const& other)
: detail::empty_base_optimization<allocator_type>(
alloc_traits::select_on_container_copy_construction(other.member()))
, max_(other.max_)
: max_(other.max_)
, out_(list_.end())
, alloc_(alloc_traits::
select_on_container_copy_construction(
other.alloc_))
{
copy_from(other);
}
@@ -521,9 +519,9 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(basic_multi_buffer const& other,
Allocator const& alloc)
: detail::empty_base_optimization<allocator_type>(alloc)
, max_(other.max_)
: max_(other.max_)
, out_(list_.end())
, alloc_(alloc)
{
copy_from(other);
}
@@ -544,9 +542,9 @@ basic_multi_buffer<Allocator>::
basic_multi_buffer(
basic_multi_buffer<OtherAlloc> const& other,
allocator_type const& alloc)
: detail::empty_base_optimization<allocator_type>(alloc)
, max_(other.max_)
: max_(other.max_)
, out_(list_.end())
, alloc_(alloc)
{
copy_from(other);
}
@@ -695,9 +693,9 @@ prepare(size_type n) ->
512,
n}));
auto& e = *reinterpret_cast<element*>(static_cast<
void*>(alloc_traits::allocate(this->member(),
void*>(alloc_traits::allocate(alloc_,
sizeof(element) + size)));
alloc_traits::construct(this->member(), &e, size);
alloc_traits::construct(alloc_, &e, size);
list_.push_back(e);
if(out_ == list_.end())
out_ = list_.iterator_to(e);
@@ -828,8 +826,8 @@ basic_multi_buffer<Allocator>::
delete_element(element& e)
{
auto const len = sizeof(e) + e.size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
alloc_traits::destroy(alloc_, &e);
alloc_traits::deallocate(alloc_,
reinterpret_cast<char*>(&e), len);
}
@@ -878,7 +876,7 @@ void
basic_multi_buffer<Allocator>::
move_assign(basic_multi_buffer& other, std::false_type)
{
if(this->member() != other.member())
if(alloc_ != other.alloc_)
{
copy_from(other);
other.reset();
@@ -895,7 +893,7 @@ void
basic_multi_buffer<Allocator>::
move_assign(basic_multi_buffer& other, std::true_type)
{
this->member() = std::move(other.member());
alloc_ = std::move(alloc_);
auto const at_end =
other.out_ == other.list_.end();
list_ = std::move(other.list_);
@@ -934,7 +932,7 @@ copy_assign(
{
reset();
max_ = other.max_;
this->member() = other.member();
alloc_ = other.alloc_;
copy_from(other);
}
@@ -959,7 +957,7 @@ swap(basic_multi_buffer& other, std::true_type)
out_ == list_.end();
auto const at_end1 =
other.out_ == other.list_.end();
swap(this->member(), other.member());
swap(alloc_, other.alloc_);
swap(list_, other.list_);
swap(out_, other.out_);
if(at_end1)
@@ -978,7 +976,7 @@ void
basic_multi_buffer<Allocator>::
swap(basic_multi_buffer& other, std::false_type)
{
BOOST_ASSERT(this->member() == other.member());
BOOST_ASSERT(alloc_ == other.alloc_);
using std::swap;
auto const at_end0 =
out_ == list_.end();

View File

@@ -9,7 +9,6 @@
#define BEAST_MULTI_BUFFER_HPP
#include <beast/config.hpp>
#include <beast/core/detail/empty_base_optimization.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/intrusive/list.hpp>
#include <iterator>
@@ -32,11 +31,6 @@ namespace beast {
*/
template<class Allocator>
class basic_multi_buffer
#if ! BEAST_DOXYGEN
: private detail::empty_base_optimization<
typename std::allocator_traits<Allocator>::
template rebind_alloc<char>>
#endif
{
public:
#if BEAST_DOXYGEN
@@ -57,29 +51,30 @@ private:
using alloc_traits = std::allocator_traits<allocator_type>;
using list_type = typename boost::intrusive::make_list<element,
boost::intrusive::constant_time_size<true>>::type;
using iterator = typename list_type::iterator;
using const_iterator = typename list_type::const_iterator;
using iter = typename list_type::iterator;
using const_iter = typename list_type::const_iterator;
using size_type = typename std::allocator_traits<Allocator>::size_type;
using const_buffer = boost::asio::const_buffer;
using mutable_buffer = boost::asio::mutable_buffer;
static_assert(std::is_base_of<std::bidirectional_iterator_tag,
typename std::iterator_traits<iterator>::iterator_category>::value,
typename std::iterator_traits<iter>::iterator_category>::value,
"BidirectionalIterator requirements not met");
static_assert(std::is_base_of<std::bidirectional_iterator_tag,
typename std::iterator_traits<const_iterator>::iterator_category>::value,
typename std::iterator_traits<const_iter>::iterator_category>::value,
"BidirectionalIterator requirements not met");
std::size_t max_ =
(std::numeric_limits<std::size_t>::max)();
list_type list_; // list of allocated buffers
iterator out_; // element that contains out_pos_
iter out_; // element that contains out_pos_
size_type in_size_ = 0; // size of the input sequence
size_type in_pos_ = 0; // input offset in list_.front()
size_type out_pos_ = 0; // output offset in *out_
size_type out_end_ = 0; // output end offset in list_.back()
allocator_type alloc_; // the allocator
public:
#if BEAST_DOXYGEN
@@ -217,7 +212,7 @@ public:
allocator_type
get_allocator() const
{
return this->member();
return alloc_;
}
/// Returns the size of the input sequence.