summaryrefslogtreecommitdiff
path: root/src/lib/eolian_cxx
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-08-15 14:47:00 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-09-14 00:33:22 -0300
commitdbed78ad3ba9f247e64966a8dda6491a781bd240 (patch)
tree4669f047b1e73d69106a16932c692e0954cce5a8 /src/lib/eolian_cxx
parentf9401c16f061941549463950b272a5417ed0d640 (diff)
eina-cxx: Moved variant to eina C++
Diffstat (limited to 'src/lib/eolian_cxx')
-rw-r--r--src/lib/eolian_cxx/grammar/alternative.hpp3
-rw-r--r--src/lib/eolian_cxx/grammar/klass_def.hpp3
-rw-r--r--src/lib/eolian_cxx/grammar/type_impl.hpp2
-rw-r--r--src/lib/eolian_cxx/grammar/variant.hpp276
4 files changed, 3 insertions, 281 deletions
diff --git a/src/lib/eolian_cxx/grammar/alternative.hpp b/src/lib/eolian_cxx/grammar/alternative.hpp
index 2d70052f45..3ad3e6af67 100644
--- a/src/lib/eolian_cxx/grammar/alternative.hpp
+++ b/src/lib/eolian_cxx/grammar/alternative.hpp
@@ -3,7 +3,6 @@
3 3
4#include "grammar/generator.hpp" 4#include "grammar/generator.hpp"
5#include "grammar/meta.hpp" 5#include "grammar/meta.hpp"
6#include "grammar/variant.hpp"
7 6
8namespace efl { namespace eolian { namespace grammar { 7namespace efl { namespace eolian { namespace grammar {
9 8
@@ -11,7 +10,7 @@ template <typename L, typename R>
11struct alternative_generator 10struct alternative_generator
12{ 11{
13 template <typename OutputIterator, typename...Args, typename Context> 12 template <typename OutputIterator, typename...Args, typename Context>
14 bool generate(OutputIterator /*sink*/, attributes::variant<Args...> const& /*attribute*/, Context const& /*context*/) const 13 bool generate(OutputIterator /*sink*/, eina::variant<Args...> const& /*attribute*/, Context const& /*context*/) const
15 { 14 {
16 // return grammar::alternative_sequence(left, right, sink, attribute); 15 // return grammar::alternative_sequence(left, right, sink, attribute);
17 return false; 16 return false;
diff --git a/src/lib/eolian_cxx/grammar/klass_def.hpp b/src/lib/eolian_cxx/grammar/klass_def.hpp
index cafb56d99b..d2f39d3542 100644
--- a/src/lib/eolian_cxx/grammar/klass_def.hpp
+++ b/src/lib/eolian_cxx/grammar/klass_def.hpp
@@ -2,7 +2,6 @@
2#define EOLIAN_CXX_KLASS_DEF_HH 2#define EOLIAN_CXX_KLASS_DEF_HH
3 3
4#include "grammar/type_traits.hpp" 4#include "grammar/type_traits.hpp"
5#include "grammar/variant.hpp"
6#include "grammar/attributes.hpp" 5#include "grammar/attributes.hpp"
7#include "grammar/qualifier_def.hpp" 6#include "grammar/qualifier_def.hpp"
8#include "grammar/string.hpp" 7#include "grammar/string.hpp"
@@ -201,7 +200,7 @@ inline bool operator!=(complex_type_def const& lhs, complex_type_def const& rhs)
201 200
202struct type_def 201struct type_def
203{ 202{
204 typedef attributes::variant<klass_name, regular_type_def, complex_type_def> variant_type; 203 typedef eina::variant<klass_name, regular_type_def, complex_type_def> variant_type;
205 variant_type original_type; 204 variant_type original_type;
206 std::string c_type; 205 std::string c_type;
207 206
diff --git a/src/lib/eolian_cxx/grammar/type_impl.hpp b/src/lib/eolian_cxx/grammar/type_impl.hpp
index ac1118f077..5a5049c68c 100644
--- a/src/lib/eolian_cxx/grammar/type_impl.hpp
+++ b/src/lib/eolian_cxx/grammar/type_impl.hpp
@@ -305,7 +305,7 @@ struct visitor_generate
305 if(v.empty()) 305 if(v.empty())
306 return true; 306 return true;
307 else if(attributes::complex_type_def const* complex 307 else if(attributes::complex_type_def const* complex
308 = attributes::get<attributes::complex_type_def>(&v)) 308 = eina::get<attributes::complex_type_def>(&v))
309 return default_match(*complex); 309 return default_match(*complex);
310 else 310 else
311 return v.visit(*this); 311 return v.visit(*this);
diff --git a/src/lib/eolian_cxx/grammar/variant.hpp b/src/lib/eolian_cxx/grammar/variant.hpp
deleted file mode 100644
index 195c0a484b..0000000000
--- a/src/lib/eolian_cxx/grammar/variant.hpp
+++ /dev/null
@@ -1,276 +0,0 @@
1#ifndef EOLIAN_CXX_VARIANT_HH_
2#define EOLIAN_CXX_VARIANT_HH_
3
4#include <cstddef>
5#include <algorithm>
6#include <utility>
7#include <type_traits>
8#include <tuple>
9
10#include "grammar/meta.hpp"
11
12namespace efl { namespace eolian { namespace grammar { namespace attributes {
13
14template <std::size_t N, std::size_t L, typename Tuple>
15struct call_visitor
16{
17 template <typename F>
18 static typename F::result_type call(int type, void const* buffer, F f)
19 {
20 if(type == N)
21 {
22 using std::tuple_element;
23 typedef typename tuple_element<N, Tuple>::type type;
24 type const* o = static_cast<type const*>(buffer);
25 return f(*o);
26 }
27 else
28 return call_visitor<N+1, L, Tuple>::call(type, buffer, f);
29 }
30 template <typename F>
31 static typename F::result_type call(int type, void* buffer, F f)
32 {
33 if(type == N)
34 {
35 using std::tuple_element;
36 typedef typename tuple_element<N, Tuple>::type type;
37 type* o = static_cast<type*>(buffer);
38 return f(*o);
39 }
40 else
41 return call_visitor<N+1, L, Tuple>::call(type, buffer, f);
42 }
43};
44
45template <std::size_t L, typename Tuple>
46struct call_visitor<L, L, Tuple>
47{
48 template <typename F>
49 static typename F::result_type call(int, void const*, F)
50 {
51 std::abort();
52 }
53};
54
55struct compare_equal_visitor
56{
57 void const* buffer;
58 typedef bool result_type;
59 template <typename T>
60 bool operator()(T const& other) const
61 {
62 return *static_cast<T const*>(buffer) == other;
63 }
64};
65
66struct copy_visitor
67{
68 typedef void result_type;
69 void* buffer;
70 template <typename T>
71 void operator()(T const& other) const
72 {
73 new (buffer) T(other);
74 }
75};
76
77struct move_visitor
78{
79 typedef void result_type;
80 void* buffer;
81 template <typename T>
82 void operator()(T& other) const
83 {
84 typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
85 new (buffer) type(std::move(other));
86 }
87};
88
89struct assign_visitor
90{
91 typedef void result_type;
92 void* buffer;
93 template <typename T>
94 void operator()(T const& other) const
95 {
96 typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
97 type* assigned = static_cast<type*>(buffer);
98 *assigned = other;
99 }
100};
101
102struct destroy_visitor
103{
104 typedef void result_type;
105 template <typename T>
106 void operator()(T&& other) const
107 {
108 typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type type;
109 other.~type();
110 }
111};
112
113template <typename T>
114struct get_visitor
115{
116 typedef T* result_type;
117 T* operator()(T& object) const
118 {
119 return &object;
120 }
121 template <typename U>
122 T* operator()(U&) const { return nullptr; }
123};
124
125template <typename... Args>
126struct variant
127{
128 typedef variant<Args...> _self_type; /**< Type for the optional class itself. */
129
130 constexpr variant()
131 : type(-1)
132 {}
133
134 template <typename T>
135 variant(T object,
136 typename std::enable_if<meta::is_one_of
137 <typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
138 : type(meta::find<typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value)
139 {
140 construct(object);
141 }
142
143 variant(variant const& other)
144 : type(other.type)
145 {
146 if(other.type != -1)
147 other.visit(copy_visitor{static_cast<void*>(&buffer)});
148 }
149 variant& operator=(variant const& other)
150 {
151 if(type == other.type && type != -1)
152 {
153 other.visit(assign_visitor{static_cast<void*>(&buffer)});
154 }
155 else if(type != other.type)
156 {
157 if(type != -1)
158 destroy_unsafe();
159 type = other.type;
160 other.visit(copy_visitor{static_cast<void*>(&buffer)});
161 }
162 return *this;
163 }
164 ~variant()
165 {
166 if(type != -1)
167 destroy_unsafe();
168 }
169
170 void destroy()
171 {
172 destroy_unsafe();
173 type = -1;
174 }
175
176 void destroy_unsafe()
177 {
178 visit(destroy_visitor());
179 }
180
181 bool empty() const
182 {
183 return type == -1;
184 }
185
186 template <typename F>
187 typename F::result_type visit(F f) const
188 {
189 if(type == -1)
190 {
191 throw std::runtime_error("variant is empty");
192 }
193 else
194 return call_visitor<0u, sizeof...(Args), std::tuple<Args...>>::call(type, static_cast<const void*>(&buffer), f);
195 }
196
197 template <typename F>
198 typename F::result_type visit(F f)
199 {
200 if(type == -1)
201 {
202 throw std::runtime_error("variant is empty");
203 }
204 else
205 return call_visitor<0u, sizeof...(Args), std::tuple<Args...>>::call(type, static_cast<void*>(&buffer), f);
206 }
207
208private:
209 template <typename T>
210 void construct(T object)
211 {
212 new (&buffer) T(std::move(object));
213 }
214
215 typedef typename std::aligned_storage
216 <
217 meta::max<sizeof(Args)...>::value
218 , meta::max<std::alignment_of<Args>::value...>::value
219 >::type buffer_type;
220
221 friend bool operator==(variant<Args...> const& lhs, variant<Args...> const& rhs)
222 {
223 return rhs.type == lhs.type
224 && (rhs.type == -1
225 || rhs.visit(compare_equal_visitor{&lhs.buffer}));
226 }
227
228 int type;
229 /**
230 * Member variable for holding the contained value.
231 */
232 buffer_type buffer;
233};
234
235template <typename...Args>
236inline bool operator!=(variant<Args...>const& lhs, variant<Args...> const& rhs)
237{
238 return !(lhs == rhs);
239}
240
241template <typename T, typename...Args>
242T* get(variant<Args...>* variant, typename std::enable_if<meta::is_one_of
243 <typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
244{
245 return variant->visit(get_visitor<T>{});
246}
247template <typename T, typename...Args>
248T const* get(variant<Args...>const* variant, typename std::enable_if<meta::is_one_of
249 <typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
250{
251 return variant->visit(get_visitor<T const>{});
252}
253template <typename T, typename...Args>
254T& get(variant<Args...>& variant, typename std::enable_if<meta::is_one_of
255 <typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
256{
257 T* p = variant.visit(get_visitor<T>{});
258 if(p)
259 return *p;
260 else
261 throw std::logic_error("");
262}
263template <typename T, typename...Args>
264T const& get(variant<Args...>const& variant, typename std::enable_if<meta::is_one_of
265 <typename std::remove_cv<typename std::remove_reference<T>::type>::type, Args...>::value>::type* = 0)
266{
267 T const* p = variant.visit(get_visitor<T const>{});
268 if(p)
269 return *p;
270 else
271 throw std::logic_error("");
272}
273
274} } } }
275
276#endif