summaryrefslogtreecommitdiff
path: root/boost/beast/core/multi_buffer.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/beast/core/multi_buffer.hpp')
-rw-r--r--boost/beast/core/multi_buffer.hpp66
1 files changed, 54 insertions, 12 deletions
diff --git a/boost/beast/core/multi_buffer.hpp b/boost/beast/core/multi_buffer.hpp
index 2cf477a83b..837310c004 100644
--- a/boost/beast/core/multi_buffer.hpp
+++ b/boost/beast/core/multi_buffer.hpp
@@ -15,6 +15,7 @@
#include <boost/asio/buffer.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/intrusive/list.hpp>
+#include <boost/type_traits/type_with_alignment.hpp>
#include <iterator>
#include <limits>
#include <memory>
@@ -62,14 +63,13 @@ namespace beast {
template<class Allocator>
class basic_multi_buffer
#if ! BOOST_BEAST_DOXYGEN
- : private boost::empty_value<
- typename detail::allocator_traits<Allocator>::
- template rebind_alloc<char>>
+ : private boost::empty_value<Allocator>
#endif
{
- using base_alloc_type = typename
- detail::allocator_traits<Allocator>::
- template rebind_alloc<char>;
+ // Fancy pointers are not supported
+ static_assert(std::is_pointer<typename
+ std::allocator_traits<Allocator>::pointer>::value,
+ "Allocator must use regular pointers");
static bool constexpr default_nothrow =
std::is_nothrow_default_constructible<Allocator>::value;
@@ -77,19 +77,61 @@ class basic_multi_buffer
// Storage for the list of buffers representing the input
// and output sequences. The allocation for each element
// contains `element` followed by raw storage bytes.
- class element;
+ class 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;
+
+ explicit
+ element(size_type n) noexcept
+ : size_(n)
+ {
+ }
+
+ size_type
+ size() const noexcept
+ {
+ return size_;
+ }
+
+ char*
+ data() const noexcept
+ {
+ return const_cast<char*>(
+ reinterpret_cast<char const*>(this + 1));
+ }
+ };
template<bool>
class readable_bytes;
+ using size_type = typename
+ detail::allocator_traits<Allocator>::size_type;
+
+ using align_type = typename
+ boost::type_with_alignment<alignof(element)>::type;
+
+ using rebind_type = typename
+ beast::detail::allocator_traits<Allocator>::
+ template rebind_alloc<align_type>;
+
using alloc_traits =
- beast::detail::allocator_traits<base_alloc_type>;
- using list_type = typename boost::intrusive::make_list<element,
- boost::intrusive::constant_time_size<true>>::type;
+ beast::detail::allocator_traits<rebind_type>;
+
+ using list_type = typename boost::intrusive::make_list<
+ element, boost::intrusive::constant_time_size<true>>::type;
+
using iter = typename list_type::iterator;
- using const_iter = typename list_type::const_iterator;
- using size_type = typename alloc_traits::size_type;
+ using const_iter = typename list_type::const_iterator;
using pocma = typename
alloc_traits::propagate_on_container_move_assignment;