2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
10 #ifndef BOOST_BEAST_DETAIL_VARIANT_HPP
11 #define BOOST_BEAST_DETAIL_VARIANT_HPP
13 #include <boost/beast/core/detail/type_traits.hpp>
14 #include <boost/assert.hpp>
17 #include <type_traits>
23 // This simple variant gets the job done without
24 // causing too much trouble with template depth:
26 // * Always allows an empty state I==0
27 // * emplace() and get() support 1-based indexes only
28 // * Basic exception guarantee
34 detail::aligned_union_t<1, TN...> buf_;
37 template<std::size_t I>
38 using type = typename std::tuple_element<
39 I, std::tuple<TN...>>::type;
41 template<std::size_t I>
42 using C = std::integral_constant<std::size_t, I>;
53 operator==(variant const& other) const
57 return equal(other, C<0>{});
67 // moved-from object becomes empty
68 variant(variant&& other)
70 i_ = other.move(&buf_, C<0>{});
74 variant(variant const& other)
76 i_ = other.copy(&buf_, C<0>{});
79 // moved-from object becomes empty
80 variant& operator=(variant&& other)
85 i_ = other.move(&buf_, C<0>{});
91 variant& operator=(variant const& other)
96 i_ = other.copy(&buf_, C<0>{});
101 template<std::size_t I, class... Args>
103 emplace(Args&&... args)
106 new(&buf_) type<I-1>(
107 std::forward<Args>(args)...);
111 template<std::size_t I>
115 BOOST_ASSERT(i_ == I);
116 return *reinterpret_cast<
120 template<std::size_t I>
124 BOOST_ASSERT(i_ == I);
125 return *reinterpret_cast<
126 type<I-1> const*>(&buf_);
146 template<std::size_t I>
160 destroy(C<sizeof...(TN)>)
162 auto const I = sizeof...(TN);
163 BOOST_ASSERT(i_ == I);
169 move(void* dest, C<0>)
174 return move(dest, C<I+1>{});
177 template<std::size_t I>
179 move(void* dest, C<I>)
184 new(dest) T(std::move(get<I>()));
188 return move(dest, C<I+1>{});
192 move(void* dest, C<sizeof...(TN)>)
194 auto const I = sizeof...(TN);
195 BOOST_ASSERT(i_ == I);
197 new(dest) T(std::move(get<I>()));
203 copy(void* dest, C<0>) const
208 return copy(dest, C<I+1>{});
211 template<std::size_t I>
213 copy(void* dest, C<I>) const
218 auto const& t = get<I>();
222 return copy(dest, C<I+1>{});
226 copy(void* dest, C<sizeof...(TN)>) const
228 auto const I = sizeof...(TN);
229 BOOST_ASSERT(i_ == I);
231 auto const& t = get<I>();
237 equal(variant const& other, C<0>) const
239 auto constexpr I = 0;
242 return equal(other, C<I+1>{});
245 template<std::size_t I>
247 equal(variant const& other, C<I>) const
250 return get<I>() == other.get<I>();
251 return equal(other, C<I+1>{});
255 equal(variant const& other, C<sizeof...(TN)>) const
257 auto constexpr I = sizeof...(TN);
258 BOOST_ASSERT(i_ == I);
259 return get<I>() == other.get<I>();