mirror of
https://github.com/boostorg/beast.git
synced 2025-07-31 05:17:26 +02:00
Use mp11 in detail::variant
Reduce compilation cost for all components dependent on variant. Signed-off-by: Damian Jarek <damian.jarek93@gmail.com>
This commit is contained in:
committed by
Vinnie Falco
parent
98ff568371
commit
13322fa4bb
@ -5,6 +5,7 @@ Version 191:
|
|||||||
* Simplify some type traits
|
* Simplify some type traits
|
||||||
* Use lean_tuple in buffers_cat
|
* Use lean_tuple in buffers_cat
|
||||||
* Use lean_tuple in bind_handler, bind_front_handler
|
* Use lean_tuple in bind_handler, bind_front_handler
|
||||||
|
* Use mp11 in detail::variant
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -12,14 +12,13 @@
|
|||||||
|
|
||||||
#include <boost/beast/core/detail/type_traits.hpp>
|
#include <boost/beast/core/detail/type_traits.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <cstddef>
|
#include <boost/mp11/algorithm.hpp>
|
||||||
#include <tuple>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace beast {
|
namespace beast {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
|
||||||
// This simple variant gets the job done without
|
// This simple variant gets the job done without
|
||||||
// causing too much trouble with template depth:
|
// causing too much trouble with template depth:
|
||||||
//
|
//
|
||||||
@ -34,19 +33,115 @@ class variant
|
|||||||
detail::aligned_union_t<1, TN...> buf_;
|
detail::aligned_union_t<1, TN...> buf_;
|
||||||
unsigned char i_ = 0;
|
unsigned char i_ = 0;
|
||||||
|
|
||||||
template<std::size_t I>
|
struct destroy
|
||||||
using type = typename std::tuple_element<
|
{
|
||||||
I, std::tuple<TN...>>::type;
|
variant& self;
|
||||||
|
|
||||||
template<std::size_t I>
|
void operator()(mp11::mp_size_t<0>)
|
||||||
using C = std::integral_constant<std::size_t, I>;
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class I>
|
||||||
|
void operator()(I) noexcept
|
||||||
|
{
|
||||||
|
using T =
|
||||||
|
mp11::mp_at_c<variant, I::value - 1>;
|
||||||
|
reinterpret_cast<T&>(self.buf_).~T();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct copy
|
||||||
|
{
|
||||||
|
variant& self;
|
||||||
|
variant const& other;
|
||||||
|
|
||||||
|
void operator()(mp11::mp_size_t<0>)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class I>
|
||||||
|
void operator()(I)
|
||||||
|
{
|
||||||
|
using T =
|
||||||
|
mp11::mp_at_c<variant, I::value - 1>;
|
||||||
|
::new(&self.buf_) T(
|
||||||
|
reinterpret_cast<T const&>(other.buf_));
|
||||||
|
self.i_ = I::value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct move
|
||||||
|
{
|
||||||
|
variant& self;
|
||||||
|
variant& other;
|
||||||
|
|
||||||
|
void operator()(mp11::mp_size_t<0>)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class I>
|
||||||
|
void operator()(I)
|
||||||
|
{
|
||||||
|
using T =
|
||||||
|
mp11::mp_at_c<variant, I::value - 1>;
|
||||||
|
::new(&self.buf_) T(
|
||||||
|
reinterpret_cast<T&&>(other.buf_));
|
||||||
|
reinterpret_cast<T&>(other.buf_).~T();
|
||||||
|
self.i_ = I::value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct equals
|
||||||
|
{
|
||||||
|
variant const& self;
|
||||||
|
variant const& other;
|
||||||
|
|
||||||
|
bool operator()(mp11::mp_size_t<0>)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class I>
|
||||||
|
bool operator()(I)
|
||||||
|
{
|
||||||
|
using T =
|
||||||
|
mp11::mp_at_c<variant, I::value - 1>;
|
||||||
|
return
|
||||||
|
reinterpret_cast<T const&>(self.buf_) ==
|
||||||
|
reinterpret_cast<T const&>(other.buf_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void destruct()
|
||||||
|
{
|
||||||
|
mp11::mp_with_index<
|
||||||
|
sizeof...(TN) + 1>(
|
||||||
|
i_, destroy{*this});
|
||||||
|
i_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_construct(variant const& other)
|
||||||
|
{
|
||||||
|
mp11::mp_with_index<
|
||||||
|
sizeof...(TN) + 1>(
|
||||||
|
other.i_, copy{*this, other});
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_construct(variant& other)
|
||||||
|
{
|
||||||
|
mp11::mp_with_index<
|
||||||
|
sizeof...(TN) + 1>(
|
||||||
|
other.i_, move{*this, other});
|
||||||
|
other.i_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
variant() = default;
|
variant() = default;
|
||||||
|
|
||||||
~variant()
|
~variant()
|
||||||
{
|
{
|
||||||
destroy(C<0>{});
|
destruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -54,7 +149,9 @@ public:
|
|||||||
{
|
{
|
||||||
if(i_ != other.i_)
|
if(i_ != other.i_)
|
||||||
return false;
|
return false;
|
||||||
return equal(other, C<0>{});
|
return mp11::mp_with_index<
|
||||||
|
sizeof...(TN) + 1>(
|
||||||
|
i_, equals{*this, other});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 = empty
|
// 0 = empty
|
||||||
@ -65,15 +162,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// moved-from object becomes empty
|
// moved-from object becomes empty
|
||||||
variant(variant&& other)
|
variant(variant&& other) noexcept
|
||||||
{
|
{
|
||||||
i_ = other.move(&buf_, C<0>{});
|
move_construct(other);
|
||||||
other.i_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
variant(variant const& other)
|
variant(variant const& other)
|
||||||
{
|
{
|
||||||
i_ = other.copy(&buf_, C<0>{});
|
copy_construct(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
// moved-from object becomes empty
|
// moved-from object becomes empty
|
||||||
@ -81,182 +177,55 @@ public:
|
|||||||
{
|
{
|
||||||
if(this != &other)
|
if(this != &other)
|
||||||
{
|
{
|
||||||
destroy(C<0>{});
|
destruct();
|
||||||
i_ = other.move(&buf_, C<0>{});
|
move_construct(other);
|
||||||
other.i_ = 0;
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
variant& operator=(variant const& other)
|
variant& operator=(variant const& other)
|
||||||
{
|
{
|
||||||
if(this != &other)
|
if(this != &other)
|
||||||
{
|
{
|
||||||
destroy(C<0>{});
|
destruct();
|
||||||
i_ = other.copy(&buf_, C<0>{});
|
copy_construct(other);
|
||||||
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I, class... Args>
|
template<std::size_t I, class... Args>
|
||||||
void
|
void
|
||||||
emplace(Args&&... args)
|
emplace(Args&&... args) noexcept
|
||||||
{
|
{
|
||||||
destroy(C<0>{});
|
destruct();
|
||||||
new(&buf_) type<I-1>(
|
::new(&buf_) mp11::mp_at_c<variant, I - 1>(
|
||||||
std::forward<Args>(args)...);
|
std::forward<Args>(args)...);
|
||||||
i_ = I;
|
i_ = I;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
type<I-1>&
|
mp11::mp_at_c<variant, I - 1>&
|
||||||
get()
|
get()
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(i_ == I);
|
BOOST_ASSERT(i_ == I);
|
||||||
return *reinterpret_cast<
|
return *reinterpret_cast<
|
||||||
type<I-1>*>(&buf_);
|
mp11::mp_at_c<variant, I - 1>*>(&buf_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t I>
|
template<std::size_t I>
|
||||||
type<I-1> const&
|
mp11::mp_at_c<variant, I - 1> const&
|
||||||
get() const
|
get() const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(i_ == I);
|
BOOST_ASSERT(i_ == I);
|
||||||
return *reinterpret_cast<
|
return *reinterpret_cast<
|
||||||
type<I-1> const*>(&buf_);
|
mp11::mp_at_c<variant, I - 1> const*>(&buf_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
reset()
|
reset()
|
||||||
{
|
{
|
||||||
destroy(C<0>{});
|
destruct();
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void
|
|
||||||
destroy(C<0>)
|
|
||||||
{
|
|
||||||
auto const I = 0;
|
|
||||||
if(i_ == I)
|
|
||||||
return;
|
|
||||||
destroy(C<I+1>{});
|
|
||||||
i_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
void
|
|
||||||
destroy(C<I>)
|
|
||||||
{
|
|
||||||
if(i_ == I)
|
|
||||||
{
|
|
||||||
using T = type<I-1>;
|
|
||||||
get<I>().~T();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
destroy(C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
destroy(C<sizeof...(TN)>)
|
|
||||||
{
|
|
||||||
auto const I = sizeof...(TN);
|
|
||||||
BOOST_ASSERT(i_ == I);
|
|
||||||
using T = type<I-1>;
|
|
||||||
get<I>().~T();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char
|
|
||||||
move(void* dest, C<0>)
|
|
||||||
{
|
|
||||||
auto const I = 0;
|
|
||||||
if(i_ == I)
|
|
||||||
return I;
|
|
||||||
return move(dest, C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
unsigned char
|
|
||||||
move(void* dest, C<I>)
|
|
||||||
{
|
|
||||||
if(i_ == I)
|
|
||||||
{
|
|
||||||
using T = type<I-1>;
|
|
||||||
new(dest) T(std::move(get<I>()));
|
|
||||||
get<I>().~T();
|
|
||||||
return I;
|
|
||||||
}
|
|
||||||
return move(dest, C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char
|
|
||||||
move(void* dest, C<sizeof...(TN)>)
|
|
||||||
{
|
|
||||||
auto const I = sizeof...(TN);
|
|
||||||
BOOST_ASSERT(i_ == I);
|
|
||||||
using T = type<I-1>;
|
|
||||||
new(dest) T(std::move(get<I>()));
|
|
||||||
get<I>().~T();
|
|
||||||
return I;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char
|
|
||||||
copy(void* dest, C<0>) const
|
|
||||||
{
|
|
||||||
auto const I = 0;
|
|
||||||
if(i_ == I)
|
|
||||||
return I;
|
|
||||||
return copy(dest, C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
unsigned char
|
|
||||||
copy(void* dest, C<I>) const
|
|
||||||
{
|
|
||||||
if(i_ == I)
|
|
||||||
{
|
|
||||||
using T = type<I-1>;
|
|
||||||
auto const& t = get<I>();
|
|
||||||
new(dest) T(t);
|
|
||||||
return I;
|
|
||||||
}
|
|
||||||
return copy(dest, C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char
|
|
||||||
copy(void* dest, C<sizeof...(TN)>) const
|
|
||||||
{
|
|
||||||
auto const I = sizeof...(TN);
|
|
||||||
BOOST_ASSERT(i_ == I);
|
|
||||||
using T = type<I-1>;
|
|
||||||
auto const& t = get<I>();
|
|
||||||
new(dest) T(t);
|
|
||||||
return I;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
equal(variant const& other, C<0>) const
|
|
||||||
{
|
|
||||||
auto constexpr I = 0;
|
|
||||||
if(i_ == I)
|
|
||||||
return true;
|
|
||||||
return equal(other, C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t I>
|
|
||||||
bool
|
|
||||||
equal(variant const& other, C<I>) const
|
|
||||||
{
|
|
||||||
if(i_ == I)
|
|
||||||
return get<I>() == other.get<I>();
|
|
||||||
return equal(other, C<I+1>{});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
equal(variant const& other, C<sizeof...(TN)>) const
|
|
||||||
{
|
|
||||||
auto constexpr I = sizeof...(TN);
|
|
||||||
BOOST_ASSERT(i_ == I);
|
|
||||||
return get<I>() == other.get<I>();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user