2 // Copyright (c) 2016-2019 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>
15 #include <boost/mp11/algorithm.hpp>
21 // This simple variant gets the job done without
22 // causing too much trouble with template depth:
24 // * Always allows an empty state I==0
25 // * emplace() and get() support 1-based indexes only
26 // * Basic exception guarantee
32 detail::aligned_union_t<1, TN...> buf_;
39 void operator()(mp11::mp_size_t<0>)
44 void operator()(I) noexcept
47 mp11::mp_at_c<variant, I::value - 1>;
48 detail::launder_cast<T*>(&self.buf_)->~T();
57 void operator()(mp11::mp_size_t<0>)
65 mp11::mp_at_c<variant, I::value - 1>;
67 *detail::launder_cast<T const*>(&other.buf_));
77 void operator()(mp11::mp_size_t<0>)
85 mp11::mp_at_c<variant, I::value - 1>;
86 ::new(&self.buf_) T(std::move(
87 *detail::launder_cast<T*>(&other.buf_)));
88 detail::launder_cast<T*>(&other.buf_)->~T();
98 bool operator()(mp11::mp_size_t<0>)
107 mp11::mp_at_c<variant, I::value - 1>;
109 *detail::launder_cast<T const*>(&self.buf_) ==
110 *detail::launder_cast<T const*>(&other.buf_);
123 void copy_construct(variant const& other)
127 other.i_, copy{*this, other});
130 void move_construct(variant& other)
134 other.i_, move{*this, other});
147 operator==(variant const& other) const
151 return mp11::mp_with_index<
153 i_, equals{*this, other});
163 // moved-from object becomes empty
164 variant(variant&& other) noexcept
166 move_construct(other);
169 variant(variant const& other)
171 copy_construct(other);
174 // moved-from object becomes empty
175 variant& operator=(variant&& other)
180 move_construct(other);
185 variant& operator=(variant const& other)
190 copy_construct(other);
196 template<std::size_t I, class... Args>
198 emplace(Args&&... args) noexcept
201 ::new(&buf_) mp11::mp_at_c<variant, I - 1>(
202 std::forward<Args>(args)...);
206 template<std::size_t I>
207 mp11::mp_at_c<variant, I - 1>&
210 BOOST_ASSERT(i_ == I);
211 return *detail::launder_cast<
212 mp11::mp_at_c<variant, I - 1>*>(&buf_);
215 template<std::size_t I>
216 mp11::mp_at_c<variant, I - 1> const&
219 BOOST_ASSERT(i_ == I);
220 return *detail::launder_cast<
221 mp11::mp_at_c<variant, I - 1> const*>(&buf_);