31#ifndef ETL_RANGES_MINI_VARIANT_INCLUDED
32#define ETL_RANGES_MINI_VARIANT_INCLUDED
44 namespace private_ranges
53 template <
size_t I,
typename... Ts>
56 template <
size_t I,
typename Head,
typename... Tail>
57 struct type_at_index<I, Head, Tail...> : type_at_index<I - 1, Tail...>
61 template <
typename Head,
typename... Tail>
62 struct type_at_index<0, Head, Tail...>
67 template <
size_t I,
typename... Ts>
68 using type_at_index_t =
typename type_at_index<I, Ts...>::type;
71 template <
typename... Ts>
77 static constexpr size_t value =
sizeof(T);
80 template <
typename T,
typename... Ts>
81 struct max_size<T, Ts...>
83 static constexpr size_t value = (
sizeof(T) > max_size<Ts...>::value) ?
sizeof(T) : max_size<Ts...>::value;
87 template <
typename... Ts>
93 static constexpr size_t value =
alignof(T);
96 template <
typename T,
typename... Ts>
97 struct max_align<T, Ts...>
99 static constexpr size_t value = (
alignof(T) > max_align<Ts...>::value) ?
alignof(T) : max_align<Ts...>::value;
103 inline constexpr size_t mini_variant_npos = ~size_t(0);
106 template <
typename T,
typename =
void>
111 template <
typename T>
112 struct is_equality_comparable< T, etl::void_t<decltype(etl::declval<const T&>() == etl::declval<const T&>())>> : etl::true_type
117 template <
typename... Ts>
118 struct all_equality_comparable : etl::bool_constant<(is_equality_comparable<Ts>::value && ...)>
123 template <
typename T>
124 struct is_nothrow_move_constructible
128 template <
typename U>
129 static auto test(
int) -> etl::bool_constant<noexcept(U(etl::declval<U&&>()))>;
136 static constexpr bool value =
decltype(test<T>(0))::value;
140 template <
typename... Ts>
141 struct all_nothrow_move_constructible : etl::bool_constant<(is_nothrow_move_constructible<Ts>::value && ...)>
146 template <
typename T>
147 struct is_nothrow_destructible
151 template <
typename U>
152 static auto test(
int) -> etl::bool_constant<noexcept(etl::declval<U&>().~U())>;
159 static constexpr bool value =
decltype(test<T>(0))::value;
163 template <
typename... Ts>
164 struct all_nothrow_destructible : etl::bool_constant<(is_nothrow_destructible<Ts>::value && ...)>
168 template <
typename... Ts>
171 static_assert(
sizeof...(Ts) > 0,
"mini_variant requires at least one type");
173 static constexpr size_t storage_size = max_size<Ts...>::value;
174 static constexpr size_t storage_align = max_align<Ts...>::value;
176 alignas(storage_align)
unsigned char _storage[storage_size];
180 using destroy_fn = void (*)(
void*);
183 static void destroy_impl(
void* ptr)
185 using T = type_at_index_t<I, Ts...>;
186 static_cast<T*
>(ptr)->~T();
189 template <
size_t... Is>
190 static const destroy_fn* make_destroy_table(etl::index_sequence<Is...>)
192 static const destroy_fn table[] = {&destroy_impl<Is>...};
196 static const destroy_fn* destroy_table()
198 static const destroy_fn* t = make_destroy_table(etl::make_index_sequence<
sizeof...(Ts)>{});
203 using copy_fn = void (*)(
void* ,
const void* );
206 static void copy_impl(
void* dst,
const void* src)
208 using T = type_at_index_t<I, Ts...>;
209 ::new (dst) T(*
static_cast<const T*
>(src));
212 template <
size_t... Is>
213 static const copy_fn* make_copy_table(etl::index_sequence<Is...>)
215 static const copy_fn table[] = {©_impl<Is>...};
219 static const copy_fn* copy_table()
221 static const copy_fn* t = make_copy_table(etl::make_index_sequence<
sizeof...(Ts)>{});
226 using move_fn = void (*)(
void* ,
void* );
229 static void move_impl(
void* dst,
void* src)
231 using T = type_at_index_t<I, Ts...>;
232 ::new (dst) T(etl::move(*
static_cast<T*
>(src)));
235 template <
size_t... Is>
236 static const move_fn* make_move_table(etl::index_sequence<Is...>)
238 static const move_fn table[] = {&move_impl<Is>...};
242 static const move_fn* move_table()
244 static const move_fn* t = make_move_table(etl::make_index_sequence<
sizeof...(Ts)>{});
249 using equal_fn = bool (*)(
const void* ,
const void* );
252 static bool equal_impl(
const void* lhs,
const void* rhs)
254 using T = type_at_index_t<I, Ts...>;
255 return *
static_cast<const T*
>(lhs) == *
static_cast<const T*
>(rhs);
258 template <
size_t... Is>
259 static const equal_fn* make_equal_table(etl::index_sequence<Is...>)
261 static const equal_fn table[] = {&equal_impl<Is>...};
265 static const equal_fn* equal_table()
267 static const equal_fn* t = make_equal_table(etl::make_index_sequence<
sizeof...(Ts)>{});
271 void destroy_current()
273 if (_index != mini_variant_npos)
275 destroy_table()[_index](&_storage);
276 _index = mini_variant_npos;
283 : _index{mini_variant_npos}
287 mini_variant(
const mini_variant& other)
288 : _index{mini_variant_npos}
290 if (other._index != mini_variant_npos)
292 copy_table()[other._index](&_storage, &other._storage);
293 _index = other._index;
297 mini_variant& operator=(
const mini_variant& other)
302 if (other._index != mini_variant_npos)
304 copy_table()[other._index](&_storage, &other._storage);
305 _index = other._index;
311 mini_variant(mini_variant&& other)
noexcept(all_nothrow_move_constructible<Ts...>::value && all_nothrow_destructible<Ts...>::value)
312 : _index{mini_variant_npos}
314 if (other._index != mini_variant_npos)
316 move_table()[other._index](&_storage, &other._storage);
317 _index = other._index;
318 other.destroy_current();
322 mini_variant& operator=(mini_variant&& other)
noexcept(all_nothrow_move_constructible<Ts...>::value && all_nothrow_destructible<Ts...>::value)
327 if (other._index != mini_variant_npos)
329 move_table()[other._index](&_storage, &other._storage);
330 _index = other._index;
331 other.destroy_current();
337 ~mini_variant() noexcept(all_nothrow_destructible<Ts...>::value)
342 template <
size_t I,
typename... Args>
343 void emplace(Args&&... args)
345 static_assert(I <
sizeof...(Ts),
"Index out of range");
346 using T = type_at_index_t<I, Ts...>;
348 ::new (&_storage) T(etl::forward<Args>(args)...);
352 constexpr size_t index()
const
358 type_at_index_t<I, Ts...>& get_ref()
360 static_assert(I <
sizeof...(Ts),
"Index out of range");
361 ETL_ASSERT(_index == I, ETL_ERROR_GENERIC(
"mini_variant: bad index"));
362 using T = type_at_index_t<I, Ts...>;
363 return *
reinterpret_cast<T*
>(&_storage);
367 const type_at_index_t<I, Ts...>& get_ref()
const
369 static_assert(I <
sizeof...(Ts),
"Index out of range");
370 ETL_ASSERT(_index == I, ETL_ERROR_GENERIC(
"mini_variant: bad index"));
371 using T = type_at_index_t<I, Ts...>;
372 return *
reinterpret_cast<const T*
>(&_storage);
375 template <
bool B = all_equality_comparable<Ts...>::value, etl::enable_if_t<B, int> = 0>
376 friend bool operator==(
const mini_variant& lhs,
const mini_variant& rhs)
378 if (lhs._index != rhs._index)
382 if (lhs._index == mini_variant_npos)
386 return equal_table()[lhs._index](&lhs._storage, &rhs._storage);
389 template <
bool B = all_equality_comparable<Ts...>::value, etl::enable_if_t<B, int> = 0>
390 friend bool operator!=(
const mini_variant& lhs,
const mini_variant& rhs)
392 return !(lhs == rhs);
399 template <
size_t I,
typename... Ts>
400 typename ranges::private_ranges::type_at_index_t<I, Ts...>&
get(ranges::private_ranges::mini_variant<Ts...>& v)
402 return v.template get_ref<I>();
405 template <
size_t I,
typename... Ts>
406 const typename ranges::private_ranges::type_at_index_t<I, Ts...>&
get(
const ranges::private_ranges::mini_variant<Ts...>& v)
408 return v.template get_ref<I>();
411 template <
size_t I,
typename... Ts>
412 typename ranges::private_ranges::type_at_index_t<I, Ts...>&&
get(ranges::private_ranges::mini_variant<Ts...>&& v)
414 return etl::move(v.template get_ref<I>());
417 template <
size_t I,
typename... Ts>
418 const typename ranges::private_ranges::type_at_index_t<I, Ts...>&&
get(
const ranges::private_ranges::mini_variant<Ts...>&& v)
420 return etl::move(v.template get_ref<I>());
ETL_CONSTEXPR14 bool operator!=(const etl::bitset< Active_Bits, TElement > &lhs, const etl::bitset< Active_Bits, TElement > &rhs) ETL_NOEXCEPT
Definition bitset_new.h:2529
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1081
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits.h:80
T & get(array< T, Size > &a)
Definition array.h:1161