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

View File

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