5#ifndef CUDA_BATTERY_VARIANT_HPP
6#define CUDA_BATTERY_VARIANT_HPP
16template<
size_t n,
typename... Ts>
17struct variant_helper_rec;
19template<
size_t n,
typename F,
typename... Ts>
20struct variant_helper_rec<n, F, Ts...>
22 CUDA inline static void destroy(
size_t id,
void* data)
25 reinterpret_cast<F*
>(data)->~F();
27 variant_helper_rec<n + 1, Ts...>::destroy(
id, data);
31 CUDA inline static void move(
size_t id,
void* from,
void* to)
34 new (to) F(std::move(*
reinterpret_cast<F*
>(from)));
36 variant_helper_rec<n + 1, Ts...>::move(
id, from, to);
40 CUDA inline static void copy(
size_t id,
const void* from,
void* to)
43 new (to) F(*
reinterpret_cast<const F*
>(from));
45 variant_helper_rec<n + 1, Ts...>::copy(
id, from, to);
49 CUDA inline static bool equals(
size_t id,
const void* a,
const void* b)
52 return *
reinterpret_cast<const F*
>(a) == *
reinterpret_cast<const F*
>(b);
54 return variant_helper_rec<n + 1, Ts...>::equals(
id, a, b);
58 CUDA inline static void print(
size_t id,
const void* a)
63 variant_helper_rec<n + 1, Ts...>::print(
id, a);
68template<
size_t n>
struct variant_helper_rec<n> {
69 CUDA inline static void destroy(
size_t id,
void* data) { }
70 CUDA inline static void move(
size_t old_t,
void* from,
void* to) { }
71 CUDA inline static void copy(
size_t old_t,
const void* from,
void* to) { }
72 CUDA inline static bool equals(
size_t id,
const void* a,
const void* b) {
return false; }
73 CUDA inline static void print(
size_t id,
const void* a) {}
76template<
typename... Ts>
77struct variant_helper {
78 CUDA inline static void destroy(
size_t id,
void* data) {
79 variant_helper_rec<0, Ts...>::destroy(
id, data);
82 CUDA inline static void move(
size_t id,
void* from,
void* to) {
83 variant_helper_rec<0, Ts...>::move(
id, from, to);
86 CUDA inline static void copy(
size_t id,
const void* from,
void* to) {
87 variant_helper_rec<0, Ts...>::copy(
id, from, to);
90 CUDA inline static bool equals(
size_t id,
const void* a,
const void* b) {
91 return variant_helper_rec<0, Ts...>::equals(
id, a, b);
94 CUDA inline static void print(
size_t id,
const void* a) {
95 return variant_helper_rec<0, Ts...>::print(
id, a);
99template<>
struct variant_helper<> {
100 CUDA inline static void destroy(
size_t id,
void* data) { }
101 CUDA inline static void move(
size_t old_t,
void* from,
void* to) { }
102 CUDA inline static void copy(
size_t old_t,
const void* from,
void* to) { }
103 CUDA inline static bool equals(
size_t id,
const void* a,
const void* b) {
return false; }
104 CUDA inline static void print(
size_t id,
const void* a) { }
108struct variant_helper_static;
111struct variant_helper_static {
112 CUDA inline static void move(
void* from,
void* to) {
113 new (to) F(std::move(*
reinterpret_cast<F*
>(from)));
116 CUDA inline static void copy(
const void* from,
void* to) {
117 new (to) F(*
reinterpret_cast<const F*
>(from));
122template<
size_t i,
typename... Items>
123struct variant_alternative;
125template<
typename HeadItem,
typename... TailItems>
126struct variant_alternative<0, HeadItem, TailItems...>
128 using type = HeadItem;
131template<
size_t i,
typename HeadItem,
typename... TailItems>
132struct variant_alternative<i, HeadItem, TailItems...>
134 using type =
typename variant_alternative<i - 1, TailItems...>::type;
139template<
typename... Ts>
142 using data_t =
typename std::aligned_union<1, Ts...>::type;
143 using helper_t = impl::variant_helper<Ts...>;
146 using alternative =
typename impl::variant_alternative<i, Ts...>::type;
154 CUDA alternative<i>& get()
156 assert(variant_id == i);
157 return *
reinterpret_cast<alternative<i>*
>(&data);
161 CUDA const alternative<i>& get()
const
163 assert(variant_id == i);
164 return *
reinterpret_cast<const alternative<i>*
>(&data);
169 new(&data) alternative<0>{};
176 impl::variant_helper_static<alternative<i>>::copy(&value, &ret.data);
183 impl::variant_helper_static<alternative<i>>::move(&value, &ret.data);
189 helper_t::copy(from.variant_id, &from.data, &data);
194 helper_t::move(from.variant_id, &from.data, &data);
199 helper_t::destroy(variant_id, &data);
200 variant_id = rhs.variant_id;
201 helper_t::copy(rhs.variant_id, &rhs.data, &data);
207 helper_t::destroy(variant_id, &data);
208 variant_id = rhs.variant_id;
209 helper_t::move(rhs.variant_id, &rhs.data, &data);
220 helper_t::destroy(variant_id, &data);
222 impl::variant_helper_static<alternative<i>>::copy(&value, &data);
228 helper_t::destroy(variant_id, &data);
230 impl::variant_helper_static<alternative<i>>::move(&value, &data);
234 helper_t::destroy(variant_id, &data);
238 helper_t::print(variant_id, &data);
241 template<
typename... Us>
243 template<
size_t i,
typename... Us>
245 template<
size_t i,
typename... Us>
249template<
size_t i,
typename... Ts>
252 return v.template
get<i>();
255template<
size_t i,
typename... Ts>
258 return v.template
get<i>();
261template<
typename... Ts>
264 return impl::variant_helper<Ts...>::equals(lhs.
index(), &lhs.data, &rhs.data);
271template<
typename... Ts>
272CUDA bool operator!=(
const variant<Ts...>& lhs,
const variant<Ts...>& rhs) {
273 return !(lhs == rhs);
Definition algorithm.hpp:10
CUDA NI void print(const T &t)
Definition utility.hpp:707
CUDA impl::variant_alternative< i, Ts... >::type & get(variant< Ts... > &v)
Definition variant.hpp:250
CUDA bool operator==(const string< Alloc1 > &lhs, const string< Alloc2 > &rhs)
Definition string.hpp:110
Definition variant.hpp:140
CUDA variant()
Definition variant.hpp:168
CUDA friend impl::variant_alternative< i, Us... >::type & get(variant< Us... > &v)
CUDA static NI variant create(const alternative< i > &value)
Definition variant.hpp:173
CUDA NI void set(alternative< i > &&value)
Definition variant.hpp:226
CUDA static NI variant create(alternative< i > &&value)
Definition variant.hpp:181
CUDA friend const impl::variant_alternative< i, Us... >::type & get(const variant< Us... > &v)
CUDA NI variant(variant< Ts... > &&from)
Definition variant.hpp:192
CUDA NI ~variant()
Definition variant.hpp:233
CUDA NI variant< Ts... > & operator=(variant< Ts... > &rhs)
Definition variant.hpp:197
CUDA NI variant(const variant< Ts... > &from)
Definition variant.hpp:187
CUDA size_t index() const
Definition variant.hpp:213
CUDA NI void set(alternative< i > &value)
Definition variant.hpp:218
CUDA NI void print() const
Definition variant.hpp:237
CUDA friend bool operator==(const variant< Us... > &lhs, const variant< Us... > &rhs)
#define CUDA
Definition utility.hpp:59
#define NI
Definition utility.hpp:62