Make buffers_view a public interface

This commit is contained in:
Vinnie Falco
2017-07-20 08:12:17 -07:00
parent 7c19f72b07
commit 9e16e24ec4
8 changed files with 189 additions and 146 deletions
+66 -12
View File
@@ -9,17 +9,67 @@
#define BEAST_BUFFER_CAT_HPP
#include <beast/config.hpp>
#include <beast/core/detail/buffer_cat.hpp>
#include <boost/asio/buffer.hpp>
#include <cstdint>
#include <iterator>
#include <new>
#include <stdexcept>
#include <beast/core/detail/type_traits.hpp>
#include <tuple>
#include <utility>
namespace beast {
/** A buffer sequence representing a concatenation of buffer sequences.
@see @ref buffer_cat
*/
template<class... Buffers>
class buffers_view
{
std::tuple<Buffers...> bn_;
public:
/** The type of buffer returned when dereferencing an iterator.
If every buffer sequence in the view is a @b MutableBufferSequence,
then `value_type` will be `boost::asio::mutable_buffer`.
Otherwise, `value_type` will be `boost::asio::const_buffer`.
*/
using value_type =
#if BEAST_DOXYGEN
implementation_defined;
#else
typename detail::common_buffers_type<Buffers...>::type;
#endif
/// The type of iterator used by the concatenated sequence
class const_iterator;
/// Move constructor
buffers_view(buffers_view&&) = default;
/// Copy constructor
buffers_view(buffers_view const&) = default;
/// Move assignment
buffers_view& operator=(buffers_view&&) = default;
// Copy assignment
buffers_view& operator=(buffers_view const&) = default;
/** Constructor
@param buffers The list of buffer sequences to concatenate.
Copies of the arguments will be made; however, the ownership
of memory is not transferred.
*/
explicit
buffers_view(Buffers const&... buffers);
/// Return an iterator to the beginning of the concatenated sequence.
const_iterator
begin() const;
/// Return an iterator to the end of the concatenated sequence.
const_iterator
end() const;
};
/** Concatenate 2 or more buffer sequences.
This function returns a constant or mutable buffer sequence which,
@@ -36,24 +86,28 @@ namespace beast {
@b MutableBufferSequence if each of the passed buffer sequences is
also a @b MutableBufferSequence; otherwise the returned buffer
sequence will be a @b ConstBufferSequence.
@see @ref buffers_view
*/
#if BEAST_DOXYGEN
template<class... BufferSequence>
implementation_defined
buffers_view<BufferSequence...>
buffer_cat(BufferSequence const&... buffers)
#else
template<class B1, class B2, class... Bn>
detail::buffer_cat_helper<B1, B2, Bn...>
inline
buffers_view<B1, B2, Bn...>
buffer_cat(B1 const& b1, B2 const& b2, Bn const&... bn)
#endif
{
static_assert(
detail::is_all_ConstBufferSequence<B1, B2, Bn...>::value,
detail::is_all_const_buffer_sequence<B1, B2, Bn...>::value,
"BufferSequence requirements not met");
return detail::buffer_cat_helper<
B1, B2, Bn...>{b1, b2, bn...};
return buffers_view<B1, B2, Bn...>{b1, b2, bn...};
}
} // beast
#include <beast/core/impl/buffer_cat.ipp>
#endif
+27 -14
View File
@@ -244,20 +244,6 @@ public:
type3::value && type4::value>;
};
template<class B1, class... Bn>
struct is_all_ConstBufferSequence
: std::integral_constant<bool,
is_buffer_sequence<B1, boost::asio::const_buffer>::type::value &&
is_all_ConstBufferSequence<Bn...>::value>
{
};
template<class B1>
struct is_all_ConstBufferSequence<B1>
: is_buffer_sequence<B1, boost::asio::const_buffer>::type
{
};
template<class T>
class is_dynamic_buffer
{
@@ -335,6 +321,33 @@ public:
//------------------------------------------------------------------------------
template<class B1, class... Bn>
struct is_all_const_buffer_sequence
: std::integral_constant<bool,
is_buffer_sequence<B1, boost::asio::const_buffer>::type::value &&
is_all_const_buffer_sequence<Bn...>::value>
{
};
template<class B1>
struct is_all_const_buffer_sequence<B1>
: is_buffer_sequence<B1, boost::asio::const_buffer>::type
{
};
template<class... Bn>
struct common_buffers_type
{
using type = typename std::conditional<
std::is_convertible<std::tuple<Bn...>,
typename repeat_tuple<sizeof...(Bn),
boost::asio::mutable_buffer>::type>::value,
boost::asio::mutable_buffer,
boost::asio::const_buffer>::type;
};
//------------------------------------------------------------------------------
//
// stream concepts
//
@@ -5,10 +5,10 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BEAST_DETAIL_BUFFER_CAT_HPP
#define BEAST_DETAIL_BUFFER_CAT_HPP
#ifndef BEAST_IMPL_BUFFER_CAT_IPP
#define BEAST_IMPL_BUFFER_CAT_IPP
#include <beast/core/type_traits.hpp>
#include <beast/core/detail/type_traits.hpp>
#include <boost/asio/buffer.hpp>
#include <cstdint>
#include <iterator>
@@ -18,57 +18,16 @@
#include <utility>
namespace beast {
namespace detail {
template<class... Bn>
struct common_buffers_type
{
using type = typename std::conditional<
std::is_convertible<std::tuple<Bn...>,
typename repeat_tuple<sizeof...(Bn),
boost::asio::mutable_buffer>::type>::value,
boost::asio::mutable_buffer,
boost::asio::const_buffer>::type;
};
template<class... Bn>
class buffer_cat_helper
{
std::tuple<Bn...> bn_;
public:
using value_type = typename
common_buffers_type<Bn...>::type;
class const_iterator;
buffer_cat_helper(buffer_cat_helper&&) = default;
buffer_cat_helper(buffer_cat_helper const&) = default;
buffer_cat_helper& operator=(buffer_cat_helper&&) = delete;
buffer_cat_helper& operator=(buffer_cat_helper const&) = delete;
explicit
buffer_cat_helper(Bn const&... bn)
: bn_(bn...)
{
}
const_iterator
begin() const;
const_iterator
end() const;
};
template<class... Bn>
class buffer_cat_helper<Bn...>::const_iterator
class buffers_view<Bn...>::const_iterator
{
std::size_t n_;
std::tuple<Bn...> const* bn_;
std::array<std::uint8_t,
max_sizeof<typename Bn::const_iterator...>()> buf_;
char buf_[detail::max_sizeof<
typename Bn::const_iterator...>()];
friend class buffer_cat_helper<Bn...>;
friend class buffers_view<Bn...>;
template<std::size_t I>
using C = std::integral_constant<std::size_t, I>;
@@ -83,8 +42,7 @@ class buffer_cat_helper<Bn...>::const_iterator
{
// type-pun
return *reinterpret_cast<
iter_t<I>*>(static_cast<void*>(
buf_.data()));
iter_t<I>*>(static_cast<void*>(buf_));
}
template<std::size_t I>
@@ -94,12 +52,12 @@ class buffer_cat_helper<Bn...>::const_iterator
// type-pun
return *reinterpret_cast<
iter_t<I> const*>(static_cast<
void const*>(buf_.data()));
void const*>(buf_));
}
public:
using value_type = typename
common_buffers_type<Bn...>::type;
detail::common_buffers_type<Bn...>::type;
using pointer = value_type const*;
using reference = value_type;
using difference_type = std::ptrdiff_t;
@@ -119,7 +77,7 @@ public:
bool
operator!=(const_iterator const& other) const
{
return !(*this == other);
return ! (*this == other);
}
reference
@@ -169,7 +127,7 @@ private:
std::get<I>(*bn_).end())
{
n_ = I;
new(buf_.data()) iter_t<I>{
new(buf_) iter_t<I>{
std::get<I>(*bn_).begin()};
return;
}
@@ -208,7 +166,7 @@ private:
{
if(n_ == I)
{
new(buf_.data()) iter_t<I>{
new(buf_) iter_t<I>{
std::move(other.iter<I>())};
return;
}
@@ -228,7 +186,7 @@ private:
{
if(n_ == I)
{
new(buf_.data()) iter_t<I>{
new(buf_) iter_t<I>{
other.iter<I>()};
return;
}
@@ -300,7 +258,7 @@ private:
if(n_ == I)
{
--n_;
new(buf_.data()) iter_t<I-1>{
new(buf_) iter_t<I-1>{
std::get<I-1>(*bn_).end()};
}
decrement(C<I-1>{});
@@ -333,7 +291,7 @@ private:
--n_;
using Iter = iter_t<I>;
iter<I>().~Iter();
new(buf_.data()) iter_t<I-1>{
new(buf_) iter_t<I-1>{
std::get<I-1>(*bn_).end()};
}
decrement(C<I-1>{});
@@ -343,14 +301,14 @@ private:
//------------------------------------------------------------------------------
template<class... Bn>
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::~const_iterator()
{
destroy(C<0>{});
}
template<class... Bn>
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::const_iterator()
: n_(sizeof...(Bn))
, bn_(nullptr)
@@ -358,7 +316,7 @@ const_iterator::const_iterator()
}
template<class... Bn>
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::const_iterator(
std::tuple<Bn...> const& bn, bool at_end)
: bn_(&bn)
@@ -370,7 +328,7 @@ const_iterator::const_iterator(
}
template<class... Bn>
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::const_iterator(const_iterator&& other)
: n_(other.n_)
, bn_(other.bn_)
@@ -379,7 +337,7 @@ const_iterator::const_iterator(const_iterator&& other)
}
template<class... Bn>
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::const_iterator(const_iterator const& other)
: n_(other.n_)
, bn_(other.bn_)
@@ -389,7 +347,7 @@ const_iterator::const_iterator(const_iterator const& other)
template<class... Bn>
auto
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::operator=(const_iterator&& other) ->
const_iterator&
{
@@ -404,7 +362,7 @@ const_iterator::operator=(const_iterator&& other) ->
template<class... Bn>
auto
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::operator=(const_iterator const& other) ->
const_iterator&
{
@@ -419,7 +377,7 @@ const_iterator&
template<class... Bn>
bool
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::operator==(const_iterator const& other) const
{
if(bn_ != other.bn_)
@@ -431,7 +389,7 @@ const_iterator::operator==(const_iterator const& other) const
template<class... Bn>
auto
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::operator*() const ->
reference
{
@@ -440,7 +398,7 @@ const_iterator::operator*() const ->
template<class... Bn>
auto
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::operator++() ->
const_iterator&
{
@@ -450,7 +408,7 @@ const_iterator::operator++() ->
template<class... Bn>
auto
buffer_cat_helper<Bn...>::
buffers_view<Bn...>::
const_iterator::operator--() ->
const_iterator&
{
@@ -458,10 +416,20 @@ const_iterator::operator--() ->
return *this;
}
//------------------------------------------------------------------------------
template<class... Bn>
buffers_view<Bn...>::
buffers_view(Bn const&... bn)
: bn_(bn...)
{
}
template<class... Bn>
inline
auto
buffer_cat_helper<Bn...>::begin() const ->
buffers_view<Bn...>::begin() const ->
const_iterator
{
return const_iterator{bn_, false};
@@ -470,13 +438,12 @@ buffer_cat_helper<Bn...>::begin() const ->
template<class... Bn>
inline
auto
buffer_cat_helper<Bn...>::end() const ->
buffers_view<Bn...>::end() const ->
const_iterator
{
return const_iterator{bn_, true};
}
} // detail
} // beast
#endif
+1 -1
View File
@@ -39,7 +39,7 @@ template<class ConstBufferSequence>
#if BEAST_DOXYGEN
implementation_defined
#else
beast::detail::buffer_cat_helper<
beast::buffers_view<
detail::chunk_encode_delim,
ConstBufferSequence,
boost::asio::const_buffers_1>