diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-05 15:12:59 +0900 |
commit | b8cf34c691623e4ec329053cbbf68522a855882d (patch) | |
tree | 34da08632a99677f6b79ecb65e5b655a5b69a67f /boost/beast/core/detail/variant.hpp | |
parent | 3fdc3e5ee96dca5b11d1694975a65200787eab86 (diff) | |
download | boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.gz boost-b8cf34c691623e4ec329053cbbf68522a855882d.tar.bz2 boost-b8cf34c691623e4ec329053cbbf68522a855882d.zip |
Imported Upstream version 1.67.0upstream/1.67.0
Diffstat (limited to 'boost/beast/core/detail/variant.hpp')
-rw-r--r-- | boost/beast/core/detail/variant.hpp | 144 |
1 files changed, 108 insertions, 36 deletions
diff --git a/boost/beast/core/detail/variant.hpp b/boost/beast/core/detail/variant.hpp index cba6ba63c0..536cb7593f 100644 --- a/boost/beast/core/detail/variant.hpp +++ b/boost/beast/core/detail/variant.hpp @@ -31,15 +31,12 @@ namespace detail { template<class... TN> class variant { - typename std::aligned_storage< - max_sizeof<TN...>(), - max_alignof<TN...>() - >::type buf_; + 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; + I, std::tuple<TN...>>::type; template<std::size_t I> using C = std::integral_constant<std::size_t, I>; @@ -49,8 +46,15 @@ public: ~variant() { - if(i_) - destroy(C<0>{}); + destroy(C<0>{}); + } + + bool + operator==(variant const& other) const + { + if(i_ != other.i_) + return false; + return equal(other, C<0>{}); } // 0 = empty @@ -64,6 +68,7 @@ public: variant(variant&& other) { i_ = other.move(&buf_, C<0>{}); + other.i_ = 0; } variant(variant const& other) @@ -74,17 +79,22 @@ public: // moved-from object becomes empty variant& operator=(variant&& other) { - if(i_ != 0) + if(this != &other) + { destroy(C<0>{}); - i_ = other.move(&buf_, C<0>{}); + i_ = other.move(&buf_, C<0>{}); + other.i_ = 0; + } return *this; } variant& operator=(variant const& other) { - if(i_ != 0) + if(this != &other) + { destroy(C<0>{}); - i_ = other.copy(&buf_, C<0>{}); + i_ = other.copy(&buf_, C<0>{}); + } return *this; } @@ -92,8 +102,7 @@ public: void emplace(Args&&... args) { - if(i_ != 0) - destroy(C<0>{}); + destroy(C<0>{}); new(&buf_) type<I-1>( std::forward<Args>(args)...); i_ = I; @@ -120,72 +129,135 @@ public: void reset() { - if(i_ == 0) - return; destroy(C<0>{}); } private: void - destroy(C<sizeof...(TN)>) + destroy(C<0>) { - return; + 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+1) + if(i_ == I) { - using T = type<I>; - get<I+1>().~T(); - i_ = 0; + 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*, C<sizeof...(TN)>) + move(void* dest, C<0>) { - return 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+1) + if(i_ == I) { - using T = type<I>; - new(dest) T{std::move(get<I+1>())}; - get<I+1>().~T(); - i_ = 0; - return I+1; + 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 - copy(void*, C<sizeof...(TN)>) const + 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 { - return 0; + 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+1) + if(i_ == I) { - using T = type<I>; - auto const& t = get<I+1>(); - new(dest) T{t}; - return I+1; + 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>(); + } }; } // detail |