Use boost::empty_value

fix #1233
This commit is contained in:
Glen Fernandes
2018-08-24 22:12:39 -04:00
committed by Vinnie Falco
parent 4643b0565e
commit 5e98c78951
16 changed files with 113 additions and 309 deletions

View File

@@ -2,6 +2,7 @@ Version 183:
* Fix a rare case of failed UTF8 validation
* Verify certificates in client examples
* Use boost::empty_value
--------------------------------------------------------------------------------

View File

@@ -9,6 +9,8 @@
[section Release Notes]
[heading Boost 1.69]
[*Fixes]
@@ -17,6 +19,10 @@
* ([issue 1237]) Verify certificates in client examples
* ([issue 1233]) Use [@boost:/doc/html/core/empty_value.html `boost::empty_value`]
[heading Boost 1.68]
This version fixes a missing executor work guard in all composed operations

View File

@@ -1,100 +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_DETAIL_EMPTY_BASE_OPTIMIZATION_HPP
#define BOOST_BEAST_DETAIL_EMPTY_BASE_OPTIMIZATION_HPP
#include <boost/type_traits/is_final.hpp>
#include <type_traits>
#include <utility>
namespace boost {
namespace beast {
namespace detail {
template<class T>
struct is_empty_base_optimization_derived
: std::integral_constant<bool,
std::is_empty<T>::value &&
! boost::is_final<T>::value>
{
};
template<class T, int UniqueID = 0,
bool isDerived =
is_empty_base_optimization_derived<T>::value>
class empty_base_optimization : private T
{
public:
empty_base_optimization() = default;
empty_base_optimization(empty_base_optimization&&) = default;
empty_base_optimization(empty_base_optimization const&) = default;
empty_base_optimization& operator=(empty_base_optimization&&) = default;
empty_base_optimization& operator=(empty_base_optimization const&) = default;
template<class Arg1, class... ArgN>
explicit
empty_base_optimization(Arg1&& arg1, ArgN&&... argn)
: T(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
}
T& member() noexcept
{
return *this;
}
T const& member() const noexcept
{
return *this;
}
};
//------------------------------------------------------------------------------
template<
class T,
int UniqueID
>
class empty_base_optimization <T, UniqueID, false>
{
T t_;
public:
empty_base_optimization() = default;
empty_base_optimization(empty_base_optimization&&) = default;
empty_base_optimization(empty_base_optimization const&) = default;
empty_base_optimization& operator=(empty_base_optimization&&) = default;
empty_base_optimization& operator=(empty_base_optimization const&) = default;
template<class Arg1, class... ArgN>
explicit
empty_base_optimization(Arg1&& arg1, ArgN&&... argn)
: t_(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
}
T& member() noexcept
{
return t_;
}
T const& member() const noexcept
{
return t_;
}
};
} // detail
} // beast
} // boost
#endif

View File

@@ -12,8 +12,8 @@
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/detail/allocator.hpp>
#include <boost/beast/core/detail/empty_base_optimization.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/core/empty_value.hpp>
#include <limits>
#include <memory>
@@ -44,7 +44,7 @@ namespace beast {
template<class Allocator>
class basic_flat_buffer
#if ! BOOST_BEAST_DOXYGEN
: private detail::empty_base_optimization<
: private boost::empty_value<
typename detail::allocator_traits<Allocator>::
template rebind_alloc<char>>
#endif
@@ -218,7 +218,7 @@ public:
allocator_type
get_allocator() const
{
return this->member();
return this->get();
}
/// Returns the size of the input sequence.

View File

@@ -29,7 +29,7 @@ basic_flat_buffer<Allocator>::
{
if(begin_)
alloc_traits::deallocate(
this->member(), begin_, dist(begin_, end_));
this->get(), begin_, dist(begin_, end_));
}
template<class Allocator>
@@ -59,7 +59,7 @@ basic_flat_buffer(std::size_t limit)
template<class Allocator>
basic_flat_buffer<Allocator>::
basic_flat_buffer(Allocator const& alloc)
: detail::empty_base_optimization<base_alloc_type>(alloc)
: boost::empty_value<base_alloc_type>(boost::empty_init_t(), alloc)
, begin_(nullptr)
, in_(nullptr)
, out_(nullptr)
@@ -72,7 +72,7 @@ basic_flat_buffer(Allocator const& alloc)
template<class Allocator>
basic_flat_buffer<Allocator>::
basic_flat_buffer(std::size_t limit, Allocator const& alloc)
: detail::empty_base_optimization<base_alloc_type>(alloc)
: boost::empty_value<base_alloc_type>(boost::empty_init_t(), alloc)
, begin_(nullptr)
, in_(nullptr)
, out_(nullptr)
@@ -85,8 +85,8 @@ basic_flat_buffer(std::size_t limit, Allocator const& alloc)
template<class Allocator>
basic_flat_buffer<Allocator>::
basic_flat_buffer(basic_flat_buffer&& other)
: detail::empty_base_optimization<base_alloc_type>(
std::move(other.member()))
: boost::empty_value<base_alloc_type>(boost::empty_init_t(),
std::move(other.get()))
, begin_(boost::exchange(other.begin_, nullptr))
, in_(boost::exchange(other.in_, nullptr))
, out_(boost::exchange(other.out_, nullptr))
@@ -101,9 +101,9 @@ template<class Allocator>
basic_flat_buffer<Allocator>::
basic_flat_buffer(basic_flat_buffer&& other,
Allocator const& alloc)
: detail::empty_base_optimization<base_alloc_type>(alloc)
: boost::empty_value<base_alloc_type>(boost::empty_init_t(), alloc)
{
if(this->member() != other.member())
if(this->get() != other.get())
{
begin_ = nullptr;
in_ = nullptr;
@@ -133,9 +133,9 @@ basic_flat_buffer(basic_flat_buffer&& other,
template<class Allocator>
basic_flat_buffer<Allocator>::
basic_flat_buffer(basic_flat_buffer const& other)
: detail::empty_base_optimization<base_alloc_type>(
: boost::empty_value<base_alloc_type>(boost::empty_init_t(),
alloc_traits::select_on_container_copy_construction(
other.member()))
other.get()))
, begin_(nullptr)
, in_(nullptr)
, out_(nullptr)
@@ -150,7 +150,7 @@ template<class Allocator>
basic_flat_buffer<Allocator>::
basic_flat_buffer(basic_flat_buffer const& other,
Allocator const& alloc)
: detail::empty_base_optimization<base_alloc_type>(alloc)
: boost::empty_value<base_alloc_type>(boost::empty_init_t(), alloc)
, begin_(nullptr)
, in_(nullptr)
, out_(nullptr)
@@ -181,7 +181,7 @@ template<class OtherAlloc>
basic_flat_buffer<Allocator>::
basic_flat_buffer(basic_flat_buffer<OtherAlloc> const& other,
Allocator const& alloc)
: detail::empty_base_optimization<base_alloc_type>(alloc)
: boost::empty_value<base_alloc_type>(boost::empty_init_t(), alloc)
, begin_(nullptr)
, in_(nullptr)
, out_(nullptr)
@@ -264,14 +264,14 @@ prepare(std::size_t n) ->
max_,
(std::max<std::size_t>)(2 * len, len + n));
auto const p = alloc_traits::allocate(
this->member(), new_size);
this->get(), new_size);
if(begin_)
{
BOOST_ASSERT(p);
BOOST_ASSERT(in_);
std::memcpy(p, in_, len);
alloc_traits::deallocate(
this->member(), begin_, capacity());
this->get(), begin_, capacity());
}
begin_ = p;
in_ = begin_;
@@ -309,7 +309,7 @@ shrink_to_fit()
BOOST_ASSERT(begin_);
BOOST_ASSERT(in_);
p = alloc_traits::allocate(
this->member(), len);
this->get(), len);
std::memcpy(p, in_, len);
}
else
@@ -317,7 +317,7 @@ shrink_to_fit()
p = nullptr;
}
alloc_traits::deallocate(
this->member(), begin_, dist(begin_, end_));
this->get(), begin_, dist(begin_, end_));
begin_ = p;
in_ = begin_;
out_ = begin_ + len;
@@ -358,7 +358,7 @@ basic_flat_buffer<Allocator>::
move_assign(basic_flat_buffer& other, std::true_type)
{
reset();
this->member() = std::move(other.member());
this->get() = std::move(other.get());
begin_ = other.begin_;
in_ = other.in_;
out_ = other.out_;
@@ -379,7 +379,7 @@ basic_flat_buffer<Allocator>::
move_assign(basic_flat_buffer& other, std::false_type)
{
reset();
if(this->member() != other.member())
if(this->get() != other.get())
{
copy_from(other);
other.reset();
@@ -398,7 +398,7 @@ copy_assign(basic_flat_buffer const& other, std::true_type)
{
reset();
max_ = other.max_;
this->member() = other.member();
this->get() = other.get();
copy_from(other);
}
@@ -430,7 +430,7 @@ basic_flat_buffer<Allocator>::
swap(basic_flat_buffer& other, std::true_type)
{
using std::swap;
swap(this->member(), other.member());
swap(this->get(), other.get());
swap(max_, other.max_);
swap(begin_, other.begin_);
swap(in_, other.in_);
@@ -446,7 +446,7 @@ void
basic_flat_buffer<Allocator>::
swap(basic_flat_buffer& other, std::false_type)
{
BOOST_ASSERT(this->member() == other.member());
BOOST_ASSERT(this->get() == other.get());
using std::swap;
swap(max_, other.max_);
swap(begin_, other.begin_);

View File

@@ -440,8 +440,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<
base_alloc_type>(alloc)
: boost::empty_value<
base_alloc_type>(boost::empty_init_t(), alloc)
, out_(list_.end())
{
}
@@ -450,8 +450,8 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(std::size_t limit,
Allocator const& alloc)
: detail::empty_base_optimization<
base_alloc_type>(alloc)
: boost::empty_value<
base_alloc_type>(boost::empty_init_t(), alloc)
, max_(limit)
, out_(list_.end())
{
@@ -460,8 +460,8 @@ basic_multi_buffer(std::size_t limit,
template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(basic_multi_buffer&& other)
: detail::empty_base_optimization<
base_alloc_type>(std::move(other.member()))
: 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))
@@ -479,11 +479,11 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(basic_multi_buffer&& other,
Allocator const& alloc)
: detail::empty_base_optimization<
base_alloc_type>(alloc)
: boost::empty_value<
base_alloc_type>(boost::empty_init_t(), alloc)
, max_(other.max_)
{
if(this->member() != other.member())
if(this->get() != other.get())
{
out_ = list_.end();
copy_from(other);
@@ -510,10 +510,10 @@ 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<
base_alloc_type>(alloc_traits::
: boost::empty_value<
base_alloc_type>(boost::empty_init_t(), alloc_traits::
select_on_container_copy_construction(
other.member()))
other.get()))
, max_(other.max_)
, out_(list_.end())
{
@@ -524,8 +524,8 @@ template<class Allocator>
basic_multi_buffer<Allocator>::
basic_multi_buffer(basic_multi_buffer const& other,
Allocator const& alloc)
: detail::empty_base_optimization<
base_alloc_type>(alloc)
: boost::empty_value<
base_alloc_type>(boost::empty_init_t(), alloc)
, max_(other.max_)
, out_(list_.end())
{
@@ -548,8 +548,8 @@ basic_multi_buffer<Allocator>::
basic_multi_buffer(
basic_multi_buffer<OtherAlloc> const& other,
allocator_type const& alloc)
: detail::empty_base_optimization<
base_alloc_type>(alloc)
: boost::empty_value<
base_alloc_type>(boost::empty_init_t(), alloc)
, max_(other.max_)
, out_(list_.end())
{
@@ -689,8 +689,8 @@ prepare(size_type n) ->
auto& e = *it++;
reuse.erase(list_.iterator_to(e));
auto const len = sizeof(e) + e.size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
alloc_traits::destroy(this->get(), &e);
alloc_traits::deallocate(this->get(),
reinterpret_cast<char*>(&e), len);
}
if(n > 0)
@@ -705,9 +705,9 @@ prepare(size_type n) ->
512,
n}));
auto& e = *reinterpret_cast<element*>(static_cast<
void*>(alloc_traits::allocate(this->member(),
void*>(alloc_traits::allocate(this->get(),
sizeof(element) + size)));
alloc_traits::construct(this->member(), &e, size);
alloc_traits::construct(this->get(), &e, size);
list_.push_back(e);
if(out_ == list_.end())
out_ = list_.iterator_to(e);
@@ -795,8 +795,8 @@ consume(size_type n)
auto& e = list_.front();
list_.erase(list_.iterator_to(e));
auto const len = sizeof(e) + e.size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
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();
@@ -845,8 +845,8 @@ delete_list()
{
auto& e = *iter++;
auto const len = sizeof(e) + e.size();
alloc_traits::destroy(this->member(), &e);
alloc_traits::deallocate(this->member(),
alloc_traits::destroy(this->get(), &e);
alloc_traits::deallocate(this->get(),
reinterpret_cast<char*>(&e), len);
}
}
@@ -886,7 +886,7 @@ void
basic_multi_buffer<Allocator>::
move_assign(basic_multi_buffer& other, std::false_type)
{
if(this->member() != other.member())
if(this->get() != other.get())
{
copy_from(other);
other.reset();
@@ -903,7 +903,7 @@ void
basic_multi_buffer<Allocator>::
move_assign(basic_multi_buffer& other, std::true_type)
{
this->member() = std::move(other.member());
this->get() = std::move(other.get());
auto const at_end =
other.out_ == other.list_.end();
list_ = std::move(other.list_);
@@ -942,7 +942,7 @@ copy_assign(
{
reset();
max_ = other.max_;
this->member() = other.member();
this->get() = other.get();
copy_from(other);
}
@@ -967,7 +967,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(this->get(), other.get());
swap(list_, other.list_);
swap(out_, other.out_);
if(at_end1)
@@ -986,7 +986,7 @@ void
basic_multi_buffer<Allocator>::
swap(basic_multi_buffer& other, std::false_type)
{
BOOST_ASSERT(this->member() == other.member());
BOOST_ASSERT(this->get() == other.get());
using std::swap;
auto const at_end0 =
out_ == list_.end();

View File

@@ -12,8 +12,8 @@
#include <boost/beast/core/detail/config.hpp>
#include <boost/beast/core/detail/allocator.hpp>
#include <boost/beast/core/detail/empty_base_optimization.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/intrusive/list.hpp>
#include <iterator>
#include <limits>
@@ -37,7 +37,7 @@ namespace beast {
template<class Allocator>
class basic_multi_buffer
#if ! BOOST_BEAST_DOXYGEN
: private detail::empty_base_optimization<
: private boost::empty_value<
typename detail::allocator_traits<Allocator>::
template rebind_alloc<char>>
#endif
@@ -217,7 +217,7 @@ public:
allocator_type
get_allocator() const
{
return this->member();
return this->get();
}
/// Returns the size of the input sequence.

View File

@@ -11,7 +11,7 @@
#define BOOST_BEAST_HTTP_DETAIL_BASIC_PARSED_LIST_HPP
#include <boost/beast/core/string.hpp>
#include <boost/beast/core/detail/empty_base_optimization.hpp>
#include <boost/core/empty_value.hpp>
#include <cstddef>
#include <iterator>
@@ -42,8 +42,7 @@ public:
#endif
class const_iterator
: private beast::detail::
empty_base_optimization<Policy>
: private boost::empty_value<Policy>
{
basic_parsed_list const* list_ = nullptr;
char const* it_ = nullptr;
@@ -120,7 +119,7 @@ public:
void
increment()
{
if(! this->member()(
if(! this->get()(
v_, it_, list_->s_))
{
it_ = nullptr;

View File

@@ -14,9 +14,9 @@
#include <boost/beast/core/string_param.hpp>
#include <boost/beast/core/string.hpp>
#include <boost/beast/core/detail/allocator.hpp>
#include <boost/beast/core/detail/empty_base_optimization.hpp>
#include <boost/beast/http/field.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/optional.hpp>
@@ -53,7 +53,7 @@ namespace http {
template<class Allocator>
class basic_fields
#if ! BOOST_BEAST_DOXYGEN
: private beast::detail::empty_base_optimization<Allocator>
: private boost::empty_value<Allocator>
#endif
{
// Fancy pointers are not supported
@@ -283,7 +283,7 @@ public:
allocator_type
get_allocator() const
{
return this->member();
return this->get();
}
//--------------------------------------------------------------------------

View File

@@ -353,15 +353,15 @@ basic_fields<Allocator>::
template<class Allocator>
basic_fields<Allocator>::
basic_fields(Allocator const& alloc) noexcept
: beast::detail::empty_base_optimization<Allocator>(alloc)
: boost::empty_value<Allocator>(boost::empty_init_t(), alloc)
{
}
template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields&& other) noexcept
: beast::detail::empty_base_optimization<Allocator>(
std::move(other.member()))
: boost::empty_value<Allocator>(boost::empty_init_t(),
std::move(other.get()))
, set_(std::move(other.set_))
, list_(std::move(other.list_))
, method_(boost::exchange(other.method_, {}))
@@ -372,9 +372,9 @@ basic_fields(basic_fields&& other) noexcept
template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields&& other, Allocator const& alloc)
: beast::detail::empty_base_optimization<Allocator>(alloc)
: boost::empty_value<Allocator>(boost::empty_init_t(), alloc)
{
if(this->member() != other.member())
if(this->get() != other.get())
{
copy_all(other);
other.clear_all();
@@ -391,8 +391,8 @@ basic_fields(basic_fields&& other, Allocator const& alloc)
template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields const& other)
: beast::detail::empty_base_optimization<Allocator>(alloc_traits::
select_on_container_copy_construction(other.member()))
: boost::empty_value<Allocator>(boost::empty_init_t(), alloc_traits::
select_on_container_copy_construction(other.get()))
{
copy_all(other);
}
@@ -401,7 +401,7 @@ template<class Allocator>
basic_fields<Allocator>::
basic_fields(basic_fields const& other,
Allocator const& alloc)
: beast::detail::empty_base_optimization<Allocator>(alloc)
: boost::empty_value<Allocator>(boost::empty_init_t(), alloc)
{
copy_all(other);
}
@@ -419,7 +419,7 @@ template<class OtherAlloc>
basic_fields<Allocator>::
basic_fields(basic_fields<OtherAlloc> const& other,
Allocator const& alloc)
: beast::detail::empty_base_optimization<Allocator>(alloc)
: boost::empty_value<Allocator>(boost::empty_init_t(), alloc)
{
copy_all(other);
}
@@ -1025,7 +1025,7 @@ set_chunked_impl(bool value)
std::basic_string<
char,
std::char_traits<char>,
A> s{A{this->member()}};
A> s{A{this->get()}};
#endif
s.reserve(it->value().size() + 9);
s.append(it->value().data(), it->value().size());
@@ -1062,7 +1062,7 @@ set_chunked_impl(bool value)
std::basic_string<
char,
std::char_traits<char>,
A> s{A{this->member()}};
A> s{A{this->get()}};
#endif
s.reserve(it->value().size());
detail::filter_token_list_last(s, it->value(),
@@ -1119,7 +1119,7 @@ set_keep_alive_impl(
std::basic_string<
char,
std::char_traits<char>,
A> s{A{this->member()}};
A> s{A{this->get()}};
#endif
s.reserve(value.size());
detail::keep_alive_impl(
@@ -1153,7 +1153,7 @@ new_element(field name,
static_cast<off_t>(sname.size() + 2);
std::uint16_t const len =
static_cast<off_t>(value.size());
auto a = rebind_type{this->member()};
auto a = rebind_type{this->get()};
auto const p = alloc_traits::allocate(a,
(sizeof(value_type) + off + len + 2 + sizeof(align_type) - 1) /
sizeof(align_type));
@@ -1168,7 +1168,7 @@ void
basic_fields<Allocator>::
delete_element(value_type& e)
{
auto a = rebind_type{this->member()};
auto a = rebind_type{this->get()};
auto const n =
(sizeof(value_type) + e.off_ + e.len_ + 2 + sizeof(align_type) - 1) /
sizeof(align_type);
@@ -1217,7 +1217,7 @@ realloc_string(string_view& dest, string_view s)
return;
auto a = typename beast::detail::allocator_traits<
Allocator>::template rebind_alloc<
char>(this->member());
char>(this->get());
char* p = nullptr;
if(! s.empty())
{
@@ -1246,7 +1246,7 @@ realloc_target(
return;
auto a = typename beast::detail::allocator_traits<
Allocator>::template rebind_alloc<
char>(this->member());
char>(this->get());
char* p = nullptr;
if(! s.empty())
{
@@ -1310,7 +1310,7 @@ move_assign(basic_fields& other, std::true_type)
target_or_reason_ = other.target_or_reason_;
other.method_ = {};
other.target_or_reason_ = {};
this->member() = other.member();
this->get() = other.get();
}
template<class Allocator>
@@ -1320,7 +1320,7 @@ basic_fields<Allocator>::
move_assign(basic_fields& other, std::false_type)
{
clear_all();
if(this->member() != other.member())
if(this->get() != other.get())
{
copy_all(other);
other.clear_all();
@@ -1343,7 +1343,7 @@ basic_fields<Allocator>::
copy_assign(basic_fields const& other, std::true_type)
{
clear_all();
this->member() = other.member();
this->get() = other.get();
copy_all(other);
}
@@ -1364,7 +1364,7 @@ basic_fields<Allocator>::
swap(basic_fields& other, std::true_type)
{
using std::swap;
swap(this->member(), other.member());
swap(this->get(), other.get());
swap(set_, other.set_);
swap(list_, other.list_);
swap(method_, other.method_);
@@ -1377,7 +1377,7 @@ void
basic_fields<Allocator>::
swap(basic_fields& other, std::false_type)
{
BOOST_ASSERT(this->member() == other.member());
BOOST_ASSERT(this->get() == other.get());
using std::swap;
swap(set_, other.set_);
swap(list_, other.list_);

View File

@@ -197,8 +197,8 @@ template<class... BodyArgs>
message<isRequest, Body, Fields>::
message(header_type&& h, BodyArgs&&... body_args)
: header_type(std::move(h))
, beast::detail::empty_base_optimization<
typename Body::value_type>(
, boost::empty_value<
typename Body::value_type>(boost::empty_init_t(),
std::forward<BodyArgs>(body_args)...)
{
}
@@ -208,8 +208,8 @@ template<class... BodyArgs>
message<isRequest, Body, Fields>::
message(header_type const& h, BodyArgs&&... body_args)
: header_type(h)
, beast::detail::empty_base_optimization<
typename Body::value_type>(
, boost::empty_value<
typename Body::value_type>(boost::empty_init_t(),
std::forward<BodyArgs>(body_args)...)
{
}
@@ -228,8 +228,8 @@ message<isRequest, Body, Fields>::
message(verb method, string_view target,
Version version, BodyArg&& body_arg)
: header_type(method, target, version)
, beast::detail::empty_base_optimization<
typename Body::value_type>(
, boost::empty_value<
typename Body::value_type>(boost::empty_init_t(),
std::forward<BodyArg>(body_arg))
{
}
@@ -243,8 +243,8 @@ message(
FieldsArg&& fields_arg)
: header_type(method, target, version,
std::forward<FieldsArg>(fields_arg))
, beast::detail::empty_base_optimization<
typename Body::value_type>(
, boost::empty_value<
typename Body::value_type>(boost::empty_init_t(),
std::forward<BodyArg>(body_arg))
{
}
@@ -263,8 +263,8 @@ message<isRequest, Body, Fields>::
message(status result, Version version,
BodyArg&& body_arg)
: header_type(result, version)
, beast::detail::empty_base_optimization<
typename Body::value_type>(
, boost::empty_value<
typename Body::value_type>(boost::empty_init_t(),
std::forward<BodyArg>(body_arg))
{
}
@@ -276,8 +276,8 @@ message(status result, Version version,
BodyArg&& body_arg, FieldsArg&& fields_arg)
: header_type(result, version,
std::forward<FieldsArg>(fields_arg))
, beast::detail::empty_base_optimization<
typename Body::value_type>(
, boost::empty_value<
typename Body::value_type>(boost::empty_init_t(),
std::forward<BodyArg>(body_arg))
{
}

View File

@@ -16,8 +16,8 @@
#include <boost/beast/http/status.hpp>
#include <boost/beast/http/type_traits.hpp>
#include <boost/beast/core/string.hpp>
#include <boost/beast/core/detail/empty_base_optimization.hpp>
#include <boost/beast/core/detail/integer_sequence.hpp>
#include <boost/core/empty_value.hpp>
#include <boost/assert.hpp>
#include <boost/optional.hpp>
#include <boost/throw_exception.hpp>
@@ -490,7 +490,7 @@ template<bool isRequest, class Body, class Fields = fields>
struct message
: header<isRequest, Fields>
#if ! BOOST_BEAST_DOXYGEN
, beast::detail::empty_base_optimization<
, boost::empty_value<
typename Body::value_type>
#endif
{
@@ -862,8 +862,8 @@ struct message
#endif
body()& noexcept
{
return this->beast::detail::empty_base_optimization<
typename Body::value_type>::member();
return this->boost::empty_value<
typename Body::value_type>::get();
}
/// Returns the body
@@ -875,8 +875,8 @@ struct message
body()&& noexcept
{
return std::move(
this->beast::detail::empty_base_optimization<
typename Body::value_type>::member());
this->boost::empty_value<
typename Body::value_type>::get());
}
/// Returns the body
@@ -887,8 +887,8 @@ struct message
#endif
body() const& noexcept
{
return this->beast::detail::empty_base_optimization<
typename Body::value_type>::member();
return this->boost::empty_value<
typename Body::value_type>::get();
}
private:
@@ -902,8 +902,8 @@ private:
std::piecewise_construct_t,
std::tuple<BodyArgs...>& body_args,
beast::detail::index_sequence<IBodyArgs...>)
: beast::detail::empty_base_optimization<
typename Body::value_type>(
: boost::empty_value<
typename Body::value_type>(boost::empty_init_t(),
std::forward<BodyArgs>(
std::get<IBodyArgs>(body_args))...)
{
@@ -923,8 +923,8 @@ private:
beast::detail::index_sequence<IFieldsArgs...>)
: header_type(std::forward<FieldsArgs>(
std::get<IFieldsArgs>(fields_args))...)
, beast::detail::empty_base_optimization<
typename Body::value_type>(
, boost::empty_value<
typename Body::value_type>(boost::empty_init_t(),
std::forward<BodyArgs>(
std::get<IBodyArgs>(body_args))...)
{

View File

@@ -45,7 +45,6 @@ add_executable (tests-beast-core
type_traits.cpp
detail/base64.cpp
detail/clamp.cpp
detail/empty_base_optimization.cpp
detail/sha1.cpp
detail/variant.cpp
detail/varint.cpp

View File

@@ -34,7 +34,6 @@ local SOURCES =
type_traits.cpp
detail/base64.cpp
detail/clamp.cpp
detail/empty_base_optimization.cpp
detail/sha1.cpp
detail/variant.cpp
detail/varint.cpp

View File

@@ -1,98 +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
//
// Test that header file is self-contained.
#include <boost/beast/core/detail/empty_base_optimization.hpp>
#include <boost/beast/unit_test/suite.hpp>
namespace boost {
namespace beast {
namespace detail {
class empty_base_optimization_test
: public beast::unit_test::suite
{
public:
template<class T>
class test1
: private empty_base_optimization<T>
{
using Base = empty_base_optimization<T>;
void* m_p;
public:
explicit test1 (T const& t)
: Base (t)
{}
T& member() {return Base::member();}
T const& member() const {return Base::member();}
};
template<class T>
class test2
{
void* m_p;
T m_t;
public:
explicit test2 (T const& t)
: m_t (t)
{}
T& member() {return m_t;}
T const& member() const {return m_t;}
};
struct Empty
{
operator bool() {return true;}
};
static
bool
test_one()
{
test1<int> t1(1);
test2<int> t2(2);
static_assert(sizeof(t1) == sizeof(t2), "don't optimize for int");
if(t1.member() != 1)
return false;
if(t2.member() != 2)
return false;
return true;
}
static
bool
test_two()
{
test1<Empty> t1((Empty()));
test2<Empty> t2((Empty()));
static_assert(sizeof(t1) < sizeof(t2), "do optimize for Empty");
if(t1.member() != true)
return false;
if(t2.member() != true)
return false;
return true;
}
void
run()
{
BEAST_EXPECT(test_one());
BEAST_EXPECT(test_two());
pass();
}
};
BEAST_DEFINE_TESTSUITE(beast,core,empty_base_optimization);
} // detail
} // beast
} // boost

View File

@@ -15,8 +15,6 @@
#include <string>
#include <vector>
#include <boost/beast/core/detail/empty_base_optimization.hpp>
namespace boost {
namespace beast {
namespace http {