1#pragma once
2
3#include <vector>
4#include <variant>
5
6namespace taichi {
7
8template <typename T, class Container = std::vector<T>>
9struct one_or_more {
10 using value_type = T;
11
12 std::variant<value_type, Container> var;
13
14 one_or_more(value_type const &value) : var(value) {
15 }
16
17 one_or_more(value_type &value) : var(value) {
18 }
19
20 one_or_more(value_type &&value) : var(std::move(value)) {
21 }
22
23 one_or_more(Container const &value) : var(value) {
24 }
25
26 one_or_more(Container &value) : var(value) {
27 }
28
29 one_or_more(Container &&value) : var(std::move(value)) {
30 }
31
32 one_or_more(one_or_more &value) : var(value.var) {
33 }
34
35 one_or_more(one_or_more &&value) : var(std::move(value.var)) {
36 }
37
38 one_or_more &operator=(one_or_more &&) = default;
39
40 value_type *begin() {
41 if (value_type *s = std::get_if<value_type>(&var)) {
42 return s;
43 } else {
44 return (std::get_if<std::vector<value_type>>(&var))->data();
45 }
46 }
47
48 value_type *end() {
49 if (value_type *s = std::get_if<value_type>(&var)) {
50 if (*s) {
51 return s + 1;
52 } else {
53 return s;
54 }
55 } else {
56 auto *vec = std::get_if<Container>(&var);
57 return vec->data() + vec->size();
58 }
59 }
60
61 size_t size() const {
62 if (const value_type *s = std::get_if<value_type>(&var)) {
63 if (*s) {
64 return 1;
65 } else {
66 return 0;
67 }
68 } else {
69 return std::get_if<Container>(&var)->size();
70 }
71 }
72
73 bool empty() const {
74 if (const value_type *s = std::get_if<value_type>(&var)) {
75 if (*s) {
76 return false;
77 } else {
78 return true;
79 }
80 } else {
81 return std::get_if<Container>(&var)->empty();
82 }
83 }
84};
85
86} // namespace taichi
87