4#include <sysio/vm/exceptions.hpp>
15namespace sysio {
namespace vm {
18 template <
typename... Alternatives>
24 template <
typename... Ts>
27 template <
typename... Ts>
30 template <
typename T,
typename... Alternatives>
33 template <
typename T,
typename Alternative,
typename... Alternatives>
37 template <
typename T,
typename Alternative>
40 template <std::size_t I,
typename... Alternatives>
43 template <
bool Val
id,
typename Ret>
46 template <
typename Ret>
48 template <std::
size_t I,
typename Vis,
typename Var>
49 static constexpr Ret
_case(Vis&&, Var&&) {
50 throw wasm_interpreter_exception(
"variant visit shouldn't be here");
52 template <std::
size_t I,
typename Vis,
typename Var>
53 static constexpr Ret
_switch(Vis&&, Var&&) {
54 throw wasm_interpreter_exception(
"variant visit shouldn't be here");
58 template <
typename Ret>
59 struct dispatcher<true, Ret> {
60 template <std::
size_t I,
typename Vis,
typename Var>
61 static constexpr Ret
_case(Vis&& vis, Var&& var) {
62 return std::invoke(std::forward<Vis>(vis), std::forward<Var>(var).
template get<I>());
65 template <std::
size_t I,
typename Vis,
typename Var>
66 static constexpr Ret
_switch(Vis&& vis, Var&& var) {
67 constexpr std::size_t sz = std::decay_t<Var>::variant_size();
68 switch (var.index()) {
71 std::forward<Var>(var));
75 std::forward<Var>(var));
79 std::forward<Var>(var));
83 std::forward<Var>(var));
87 std::forward<Var>(var));
95 constexpr variant_storage(T##N& arg) : _t##N(arg) {} \
96 constexpr variant_storage(T##N&& arg) : _t##N(std::move(arg)) {} \
97 constexpr variant_storage(const T##N& arg) : _t##N(arg) {} \
98 constexpr variant_storage(const T##N&& arg) : _t##N(std::move(arg)) {}
100#define V0 variant_storage() = default;
101#define V1 V0 V_ELEM(0)
102#define V2 V1 V_ELEM(1)
103#define V3 V2 V_ELEM(2)
104#define V4 V3 V_ELEM(3)
106 template<
typename...
T>
107 union variant_storage;
108 template<
typename T0,
typename T1,
typename T2,
typename T3,
typename...
T>
109 union variant_storage<T0, T1, T2, T3,
T...> {
115 template<
typename T0>
119 template<
typename T0,
typename T1>
120 union variant_storage<T0, T1> {
123 template<
typename T0,
typename T1,
typename T2>
124 union variant_storage<T0, T1, T2> {
127 template<
typename T0,
typename T1,
typename T2,
typename T3>
128 union variant_storage<T0, T1, T2, T3> {
139 template<
int I,
typename Storage>
141 if constexpr (I == 0) {
142 return (
static_cast<Storage&&
>(val)._t0);
143 }
else if constexpr (I == 1) {
144 return (
static_cast<Storage&&
>(val)._t1);
145 }
else if constexpr (I == 2) {
146 return (
static_cast<Storage&&
>(val)._t2);
147 }
else if constexpr (I == 3) {
148 return (
static_cast<Storage&&
>(val)._t3);
155 template <
class Visitor,
typename Variant>
156 constexpr auto visit(Visitor&& vis, Variant&& var) {
157 using Ret =
decltype(std::invoke(std::forward<Visitor>(vis), var.template get<0>()));
161 template <
typename... Alternatives>
163 static_assert(
sizeof...(Alternatives) <= std::numeric_limits<uint8_t>::max()+1,
164 "sysio::vm::variant can only accept 256 alternatives");
165 static_assert((... && (std::is_trivially_copy_constructible_v<Alternatives> && std::is_trivially_move_constructible_v<Alternatives> &&
166 std::is_trivially_copy_assignable_v<Alternatives> && std::is_trivially_move_assignable_v<Alternatives> &&
167 std::is_trivially_destructible_v<Alternatives>)),
"Variant requires trivial types");
177 template <
typename T,
typename = std::enable_if_t<detail::is_val
id_alternative_v<std::decay_t<T>, Alternatives...>>>
179 _which(
detail::get_alternatives_index_v<
std::decay_t<
T>, Alternatives...>),
180 _storage(static_cast<
T&&>(
alt)) {
183 template <
typename T,
184 typename = std::enable_if_t<detail::is_valid_alternative_v<std::decay_t<T>, Alternatives...>>>
186#if (defined(__GNUC__) && !defined(__clang__))
187#pragma GCC diagnostic push
188#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
189 _storage =
static_cast<T&&
>(
alt);
190#pragma GCC diagnostic pop
192 _storage =
static_cast<T&&
>(
alt);
198 static inline constexpr size_t variant_size() {
return sizeof...(Alternatives); }
201 template <
size_t Index>
207 template <
size_t Index>
208 inline constexpr const auto&
get() const & {
212 template <
typename Alt>
213 inline constexpr const Alt&
get() const & {
217 template <
size_t Index>
218 inline constexpr const auto&&
get() const && {
222 template <
typename Alt>
223 inline constexpr const Alt&&
get() const && {
227 template <
size_t Index>
228 inline constexpr auto&&
get() && {
232 template <
typename Alt>
237 template <
size_t Index>
238 inline constexpr auto&
get() & {
242 template <
typename Alt>
247 template <
typename Alt>
248 inline constexpr bool is_a()
const {
Binary< NodeType::alt > Alt
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
constexpr void clear_exiting_which()
constexpr void toggle_exiting_which()
constexpr const auto & get() const &
constexpr auto && get_check()
static constexpr size_t variant_size()
variant & operator=(const variant &other)=default
constexpr auto && get() &&
constexpr void set_exiting_which()
constexpr bool is_a() const
constexpr variant(T &&alt)
constexpr const Alt && get() const &&
constexpr uint16_t index() const
constexpr Alt && get() &&
variant(const variant &other)=default
constexpr const Alt & get() const &
variant & operator=(variant &&other)=default
constexpr variant & operator=(T &&alt)
constexpr const auto && get() const &&
variant(variant &&other)=default
std::tuple_element_t< I, std::tuple< Alternatives... > > get_alternative_t
constexpr decltype(auto) variant_storage_get(Storage &&val)
constexpr std::size_t max_layout_size_v
constexpr std::size_t max_alignof_v
constexpr std::size_t get_alternatives_index_v< T, Alternative >
constexpr bool is_valid_alternative_v
constexpr std::size_t get_alternatives_index_v
constexpr auto visit(Visitor &&vis, Variant &&var)
#define T(meth, val, expected)
static constexpr Ret _case(Vis &&, Var &&)
static constexpr Ret _switch(Vis &&, Var &&)
static constexpr Ret _switch(Vis &&vis, Var &&var)
static constexpr Ret _case(Vis &&vis, Var &&var)
V4 constexpr variant_storage(A &&arg)
variant_storage< T... > _tail