mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +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
|
||||
* Use lean_tuple in buffers_cat
|
||||
* 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/assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <boost/mp11/algorithm.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace beast {
|
||||
namespace detail {
|
||||
|
||||
|
||||
// This simple variant gets the job done without
|
||||
// causing too much trouble with template depth:
|
||||
//
|
||||
@ -34,19 +33,115 @@ class variant
|
||||
detail::aligned_union_t<1, TN...> buf_;
|
||||
unsigned char i_ = 0;
|
||||
|
||||
template<std::size_t I>
|
||||
using type = typename std::tuple_element<
|
||||
I, std::tuple<TN...>>::type;
|
||||
struct destroy
|
||||
{
|
||||
variant& self;
|
||||
|
||||
template<std::size_t I>
|
||||
using C = std::integral_constant<std::size_t, I>;
|
||||
void operator()(mp11::mp_size_t<0>)
|
||||
{
|
||||
}
|
||||
|
||||
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:
|
||||
variant() = default;
|
||||
|
||||
~variant()
|
||||
{
|
||||
destroy(C<0>{});
|
||||
destruct();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -54,7 +149,9 @@ public:
|
||||
{
|
||||
if(i_ != other.i_)
|
||||
return false;
|
||||
return equal(other, C<0>{});
|
||||
return mp11::mp_with_index<
|
||||
sizeof...(TN) + 1>(
|
||||
i_, equals{*this, other});
|
||||
}
|
||||
|
||||
// 0 = empty
|
||||
@ -65,15 +162,14 @@ public:
|
||||
}
|
||||
|
||||
// moved-from object becomes empty
|
||||
variant(variant&& other)
|
||||
variant(variant&& other) noexcept
|
||||
{
|
||||
i_ = other.move(&buf_, C<0>{});
|
||||
other.i_ = 0;
|
||||
move_construct(other);
|
||||
}
|
||||
|
||||
variant(variant const& other)
|
||||
{
|
||||
i_ = other.copy(&buf_, C<0>{});
|
||||
copy_construct(other);
|
||||
}
|
||||
|
||||
// moved-from object becomes empty
|
||||
@ -81,182 +177,55 @@ public:
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
destroy(C<0>{});
|
||||
i_ = other.move(&buf_, C<0>{});
|
||||
other.i_ = 0;
|
||||
destruct();
|
||||
move_construct(other);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
variant& operator=(variant const& other)
|
||||
{
|
||||
if(this != &other)
|
||||
{
|
||||
destroy(C<0>{});
|
||||
i_ = other.copy(&buf_, C<0>{});
|
||||
destruct();
|
||||
copy_construct(other);
|
||||
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<std::size_t I, class... Args>
|
||||
void
|
||||
emplace(Args&&... args)
|
||||
emplace(Args&&... args) noexcept
|
||||
{
|
||||
destroy(C<0>{});
|
||||
new(&buf_) type<I-1>(
|
||||
destruct();
|
||||
::new(&buf_) mp11::mp_at_c<variant, I - 1>(
|
||||
std::forward<Args>(args)...);
|
||||
i_ = I;
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
type<I-1>&
|
||||
mp11::mp_at_c<variant, I - 1>&
|
||||
get()
|
||||
{
|
||||
BOOST_ASSERT(i_ == I);
|
||||
return *reinterpret_cast<
|
||||
type<I-1>*>(&buf_);
|
||||
mp11::mp_at_c<variant, I - 1>*>(&buf_);
|
||||
}
|
||||
|
||||
template<std::size_t I>
|
||||
type<I-1> const&
|
||||
mp11::mp_at_c<variant, I - 1> const&
|
||||
get() const
|
||||
{
|
||||
BOOST_ASSERT(i_ == I);
|
||||
return *reinterpret_cast<
|
||||
type<I-1> const*>(&buf_);
|
||||
mp11::mp_at_c<variant, I - 1> const*>(&buf_);
|
||||
}
|
||||
|
||||
void
|
||||
reset()
|
||||
{
|
||||
destroy(C<0>{});
|
||||
}
|
||||
|
||||
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>();
|
||||
destruct();
|
||||
}
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user