summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile_Cxx.am6
-rw-r--r--src/bindings/cxx/eo_cxx/Eo.hh1
-rw-r--r--src/bindings/cxx/eo_cxx/eo_cxx_interop.hh25
-rw-r--r--src/bindings/cxx/eo_cxx/eo_future.hh505
-rw-r--r--src/bindings/cxx/eo_cxx/eo_promise.hh148
-rw-r--r--src/bindings/cxx/eo_cxx/eo_promise_meta.hh332
-rw-r--r--src/lib/eolian_cxx/grammar/blacklist.hpp54
-rw-r--r--src/lib/eolian_cxx/grammar/function_declaration.hpp4
-rw-r--r--src/lib/eolian_cxx/grammar/function_definition.hpp4
-rw-r--r--src/lib/eolian_cxx/grammar/type_impl.hpp12
-rw-r--r--src/tests/eo_cxx/eo_cxx_suite.cc1
-rw-r--r--src/tests/eo_cxx/eo_cxx_suite.h1
-rw-r--r--src/tests/eo_cxx/eo_cxx_test_promise.cc14
13 files changed, 69 insertions, 1038 deletions
diff --git a/src/Makefile_Cxx.am b/src/Makefile_Cxx.am
index fc7c825def..b13880c674 100644
--- a/src/Makefile_Cxx.am
+++ b/src/Makefile_Cxx.am
@@ -16,9 +16,6 @@ bindings/cxx/eo_cxx/Eo.hh \
16bindings/cxx/eo_cxx/eo_init.hh \ 16bindings/cxx/eo_cxx/eo_init.hh \
17bindings/cxx/eo_cxx/eo_ops.hh \ 17bindings/cxx/eo_cxx/eo_ops.hh \
18bindings/cxx/eo_cxx/eo_wref.hh \ 18bindings/cxx/eo_cxx/eo_wref.hh \
19bindings/cxx/eo_cxx/eo_future.hh \
20bindings/cxx/eo_cxx/eo_promise.hh \
21bindings/cxx/eo_cxx/eo_promise_meta.hh \
22bindings/cxx/eo_cxx/eo_private.hh \ 19bindings/cxx/eo_cxx/eo_private.hh \
23bindings/cxx/eo_cxx/efl_object_impl.hh 20bindings/cxx/eo_cxx/efl_object_impl.hh
24 21
@@ -247,8 +244,7 @@ tests_eina_cxx_eina_cxx_suite_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ @USE_EO_IN
247 244
248tests_eo_cxx_eo_cxx_suite_SOURCES = \ 245tests_eo_cxx_eo_cxx_suite_SOURCES = \
249tests/eo_cxx/eo_cxx_suite.cc \ 246tests/eo_cxx/eo_cxx_suite.cc \
250tests/eo_cxx/eo_cxx_suite.h \ 247tests/eo_cxx/eo_cxx_suite.h
251tests/eo_cxx/eo_cxx_test_promise.cc
252 248
253tests_eo_cxx_eo_cxx_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ 249tests_eo_cxx_eo_cxx_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
254-DTESTS_WD=\"`pwd`\" \ 250-DTESTS_WD=\"`pwd`\" \
diff --git a/src/bindings/cxx/eo_cxx/Eo.hh b/src/bindings/cxx/eo_cxx/Eo.hh
index bd60f69701..4a4da4c6ef 100644
--- a/src/bindings/cxx/eo_cxx/Eo.hh
+++ b/src/bindings/cxx/eo_cxx/Eo.hh
@@ -8,7 +8,6 @@
8#include <eo_wref.hh> 8#include <eo_wref.hh>
9//#include <eo_inherit.hh> 9//#include <eo_inherit.hh>
10//#include <eo_own_ptr.hh> 10//#include <eo_own_ptr.hh>
11#include <eo_promise.hh>
12#include <eo_cxx_interop.hh> 11#include <eo_cxx_interop.hh>
13#include <eo_event.hh> 12#include <eo_event.hh>
14 13
diff --git a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
index 5dac150b20..fc00db830e 100644
--- a/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
+++ b/src/bindings/cxx/eo_cxx/eo_cxx_interop.hh
@@ -7,7 +7,6 @@
7#include <utility> 7#include <utility>
8#include <type_traits> 8#include <type_traits>
9#include <initializer_list> 9#include <initializer_list>
10#include <future>
11 10
12#include <Eina.hh> 11#include <Eina.hh>
13#include <Eo.hh> 12#include <Eo.hh>
@@ -59,8 +58,6 @@ template <typename T>
59struct out_traits<eina::optional<T&>> { typedef eina::optional<T&> type; }; 58struct out_traits<eina::optional<T&>> { typedef eina::optional<T&> type; };
60template <> 59template <>
61struct out_traits<void*> { typedef void*& type; }; 60struct out_traits<void*> { typedef void*& type; };
62template <typename T>
63struct out_traits<efl::shared_future<T>> { typedef efl::shared_future<T>& type; };
64template <> 61template <>
65struct out_traits<efl::eina::strbuf> { typedef efl::eina::strbuf_wrapper& type; }; 62struct out_traits<efl::eina::strbuf> { typedef efl::eina::strbuf_wrapper& type; };
66 63
@@ -68,8 +65,6 @@ template <typename T>
68struct inout_traits { typedef T& type; }; 65struct inout_traits { typedef T& type; };
69template <> 66template <>
70struct inout_traits<void> { typedef void* type; }; 67struct inout_traits<void> { typedef void* type; };
71template <typename T>
72struct inout_traits<efl::shared_future<T>> { typedef efl::shared_future<T>& type; };
73 68
74template <typename T> 69template <typename T>
75struct return_traits { typedef T type; }; 70struct return_traits { typedef T type; };
@@ -142,10 +137,6 @@ void assign_out_impl(T& lhs, Eo const* rhs, tag<T&, Eo const*>
142{ 137{
143 lhs._reset(const_cast<Eo*>(rhs)); 138 lhs._reset(const_cast<Eo*>(rhs));
144} 139}
145template <typename T>
146void assign_out_impl(efl::shared_future<T>& /*v*/, Efl_Future*, tag<efl::shared_future<T>&, Efl_Future*>)
147{
148}
149template <typename Tag> 140template <typename Tag>
150void assign_out_impl(efl::eina::string_view& view, const char* string, Tag) 141void assign_out_impl(efl::eina::string_view& view, const char* string, Tag)
151{ 142{
@@ -277,11 +268,6 @@ Eo const* convert_inout_impl(T v, tag<T, Eo const*>
277{ 268{
278 return v._eo_ptr(); 269 return v._eo_ptr();
279} 270}
280template <typename T>
281Efl_Future* convert_inout_impl(efl::shared_future<T>& /*v*/, tag<efl::shared_future<T>, Efl_Future*>)
282{
283 return nullptr;
284}
285} 271}
286 272
287template <typename To, typename From, typename V> 273template <typename To, typename From, typename V>
@@ -545,11 +531,6 @@ inline const char* convert_to_c_impl(efl::eina::stringshare x, tag<const char*,
545{ 531{
546 return eina_stringshare_ref(x.c_str()); 532 return eina_stringshare_ref(x.c_str());
547} 533}
548template <typename T>
549Efl_Future* convert_to_c_impl(efl::shared_future<T> const&, tag<Efl_Future*, efl::shared_future<T>const&>)
550{
551 std::abort();
552}
553template <typename T, typename U, typename Deleter> 534template <typename T, typename U, typename Deleter>
554T* convert_to_c_impl(std::unique_ptr<U, Deleter>& v, tag<T*, std::unique_ptr<U, Deleter>>) 535T* convert_to_c_impl(std::unique_ptr<U, Deleter>& v, tag<T*, std::unique_ptr<U, Deleter>>)
555{ 536{
@@ -709,12 +690,6 @@ eina::accessor<T> convert_to_return(Eina_Accessor* value, tag<Eina_Accessor*, ei
709{ 690{
710 return eina::accessor<T>{ value }; 691 return eina::accessor<T>{ value };
711} 692}
712template <typename T>
713efl::shared_future<T> convert_to_return(Efl_Future* /*value*/, tag<Efl_Future*, efl::shared_future<T>>)
714{
715 std::abort();
716 return {};
717}
718// Eina_Value* 693// Eina_Value*
719inline efl::eina::value convert_to_return(Eina_Value* value, tag<Eina_Value*, efl::eina::value>) 694inline efl::eina::value convert_to_return(Eina_Value* value, tag<Eina_Value*, efl::eina::value>)
720{ 695{
diff --git a/src/bindings/cxx/eo_cxx/eo_future.hh b/src/bindings/cxx/eo_cxx/eo_future.hh
deleted file mode 100644
index 7ed77cf016..0000000000
--- a/src/bindings/cxx/eo_cxx/eo_future.hh
+++ /dev/null
@@ -1,505 +0,0 @@
1///
2/// @file eo_future.hh
3///
4
5#ifndef EFL_CXX_EO_FUTURE_HH
6#define EFL_CXX_EO_FUTURE_HH
7
8#include <Efl.h>
9
10#include <Eina.hh>
11#include <Ecore_Manual.hh>
12
13#include <mutex>
14#include <condition_variable>
15
16#include <eina_tuple.hh>
17#include <eo_promise_meta.hh>
18
19namespace efl {
20
21template <typename...Args>
22struct shared_future;
23
24namespace _impl {
25
26template <typename V = char>
27struct wait_state
28{
29 bool available = false;
30 bool has_failed = false;
31 std::mutex mutex;
32 std::condition_variable cv;
33 typename std::aligned_storage<sizeof(V), alignof(V)>::type storage;
34 Eina_Error error;
35};
36
37inline void get_error_cb(void* data, Efl_Event const* event)
38{
39 wait_state<>* wait_state_ = static_cast<wait_state<>*>(data);
40 Efl_Future_Event_Failure* info = static_cast<Efl_Future_Event_Failure*>(event->info);
41 std::unique_lock<std::mutex> l(wait_state_->mutex);
42 wait_state_->error = info->error;
43 wait_state_->has_failed = true;
44 wait_state_->available = true;
45 wait_state_->cv.notify_one();
46}
47
48struct shared_future_common
49{
50 explicit shared_future_common(Efl_Future* future)
51 : _future(future) {}
52 shared_future_common()
53 : _future(nullptr) {}
54 ~shared_future_common()
55 {
56 if(_future)
57 efl_unref(_future);
58 }
59 shared_future_common(shared_future_common const& future)
60 : _future(efl_ref(future._future))
61 {
62 }
63 shared_future_common& operator=(shared_future_common const& other)
64 {
65 _self_type tmp(other);
66 tmp.swap(*this);
67 return *this;
68 }
69 shared_future_common(shared_future_common&& future)
70 : _future(future._future)
71 {
72 future._future = nullptr;
73 }
74 shared_future_common& operator=(shared_future_common&& other)
75 {
76 other.swap(*this);
77 return *this;
78 }
79 void swap(shared_future_common& other)
80 {
81 std::swap(_future, other._future);
82 }
83 bool valid() const noexcept
84 {
85 return _future != nullptr;
86 }
87 void wait() const
88 {
89 if(eina_main_loop_is())
90 throw std::runtime_error("Deadlock");
91
92 struct wait_state<> wait_state;
93
94 efl::ecore::main_loop_thread_safe_call_async
95 ([&]
96 {
97 efl_future_then(this->_future, &wait_success, &wait_success, nullptr, &wait_state);
98 });
99
100 std::unique_lock<std::mutex> lock(wait_state.mutex);
101 while(!wait_state.available)
102 wait_state.cv.wait(lock);
103 }
104 static void wait_success(void* data, Efl_Event const*)
105 {
106 wait_state<>* wait_state_ = static_cast<wait_state<>*>(data);
107 std::unique_lock<std::mutex> l(wait_state_->mutex);
108 wait_state_->available = true;
109 wait_state_->cv.notify_one();
110 }
111
112 typedef Efl_Future* native_handle_type;
113 native_handle_type native_handle() const noexcept { return _future; }
114
115 typedef shared_future_common _self_type;
116 Efl_Future* _future;
117};
118
119template <typename T, typename Progress = void>
120struct shared_future_1_type : shared_future_common
121{
122 typedef shared_future_common _base_type;
123
124 using _base_type::_base_type;
125 shared_future_1_type() = default;
126 shared_future_1_type(shared_future_common const& other)
127 : _base_type(other) {}
128
129 T get() const
130 {
131 if(eina_main_loop_is())
132 throw std::runtime_error("Deadlock");
133
134 struct wait_state<T> wait_state;
135
136 efl::ecore::main_loop_thread_safe_call_async
137 ([&]
138 {
139 efl_future_then(this->_future, &get_success, &_impl::get_error_cb, nullptr, &wait_state);
140 });
141
142 {
143 std::unique_lock<std::mutex> lock(wait_state.mutex);
144 while(!wait_state.available)
145 wait_state.cv.wait(lock);
146 }
147 if(wait_state.has_failed)
148 EFL_CXX_THROW(eina::system_error(eina::error_code(wait_state.error, eina::eina_error_category()), "EFL Eina Error"));
149 return *static_cast<T*>(static_cast<void*>(&wait_state.storage));
150 }
151
152 static void get_success(void* data, Efl_Event const* event)
153 {
154 wait_state<T>* wait_state_ = static_cast<wait_state<T>*>(data);
155 Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
156
157 std::unique_lock<std::mutex> l(wait_state_->mutex);
158 _impl::future_copy_traits<T>::copy(static_cast<T*>(static_cast<void*>(&wait_state_->storage)), info);
159 wait_state_->available = true;
160 wait_state_->cv.notify_one();
161 }
162
163 typedef shared_future_1_type<T, Progress> _self_type;
164};
165
166template <typename T>
167struct shared_race_future_1_type : shared_future_common
168{
169 typedef shared_future_common _base_type;
170
171 using _base_type::_base_type;
172 shared_race_future_1_type(_base_type const& other)
173 : _base_type(other) {}
174
175 T get() const
176 {
177 if(eina_main_loop_is())
178 throw std::runtime_error("Deadlock");
179
180 struct wait_state<T> wait_state;
181
182 efl::ecore::main_loop_thread_safe_call_async
183 ([&]
184 {
185 efl_future_then(this->_future, &get_success, &_impl::get_error_cb, nullptr, &wait_state);
186 });
187
188 {
189 std::unique_lock<std::mutex> lock(wait_state.mutex);
190 while(!wait_state.available)
191 wait_state.cv.wait(lock);
192 }
193 if(wait_state.has_failed)
194 EFL_CXX_THROW(eina::system_error(eina::error_code(wait_state.error, eina::eina_error_category()), "EFL Eina Error"));
195 return *static_cast<T*>(static_cast<void*>(&wait_state.storage));
196 }
197
198 static void get_success(void* data, Efl_Event const* event)
199 {
200 wait_state<T>* wait_state_ = static_cast<wait_state<T>*>(data);
201 Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
202
203 std::unique_lock<std::mutex> l(wait_state_->mutex);
204 _impl::future_copy_traits<T>::copy_race(static_cast<T*>(static_cast<void*>(&wait_state_->storage)), info);
205 wait_state_->available = true;
206 wait_state_->cv.notify_one();
207 }
208
209 typedef shared_race_future_1_type<T> _self_type;
210};
211
212template <typename...Args>
213struct shared_future_varargs_type : shared_future_common
214{
215 typedef shared_future_common _base_type;
216
217 using _base_type::_base_type;
218 shared_future_varargs_type() = default;
219 shared_future_varargs_type(_base_type const& other)
220 : _base_type(other) {}
221
222 typedef std::tuple<Args...> tuple_type;
223
224 std::tuple<Args...> get() const
225 {
226 if(eina_main_loop_is())
227 throw std::runtime_error("Deadlock");
228
229 struct wait_state<tuple_type> wait_state;
230
231 efl::ecore::main_loop_thread_safe_call_async
232 ([&]
233 {
234 efl_future_then(this->_future, &get_success, &_impl::get_error_cb, nullptr, &wait_state);
235 });
236
237 {
238 std::unique_lock<std::mutex> lock(wait_state.mutex);
239 while(!wait_state.available)
240 wait_state.cv.wait(lock);
241 }
242 if(wait_state.has_failed)
243 EFL_CXX_THROW(eina::system_error(eina::error_code(wait_state.error, eina::eina_error_category()), "EFL Eina Error"));
244 return *static_cast<tuple_type*>(static_cast<void*>(&wait_state.storage));
245 }
246
247 template <std::size_t N>
248 static void read_accessor(Eina_Accessor* accessor
249 , std::tuple<typename std::aligned_storage<sizeof(Args), alignof(Args)>::type...>& storage_tuple
250 , wait_state<tuple_type>* wait_state
251 , std::false_type)
252 {
253 typedef typename std::tuple_element<N, tuple_type>::type type;
254 void* value;
255 if(eina_accessor_data_get(accessor, N, &value))
256 {
257 eina::copy_from_c_traits<type>::copy_to_unitialized
258 (static_cast<type*>(static_cast<void*>(&std::get<N>(storage_tuple))), value);
259
260 _self_type::read_accessor<N+1>(accessor, storage_tuple, wait_state
261 , std::integral_constant<bool, (N+1 == sizeof...(Args))>());
262 }
263 else
264 {
265 std::abort();
266 // some error
267 }
268 }
269
270 template <std::size_t N, std::size_t...I>
271 static void read_accessor_end(std::tuple<typename std::aligned_storage<sizeof(Args), alignof(Args)>::type...>& storage_tuple
272 , wait_state<tuple_type>* wait_state
273 , eina::index_sequence<I...>)
274 {
275 std::unique_lock<std::mutex> l(wait_state->mutex);
276
277 new (&wait_state->storage) tuple_type{(*static_cast<typename std::tuple_element<I, tuple_type>::type*>
278 (static_cast<void*>(&std::get<I>(storage_tuple))))...};
279
280 wait_state->available = true;
281 wait_state->cv.notify_one();
282 }
283
284 template <std::size_t N>
285 static void read_accessor(Eina_Accessor*
286 , std::tuple<typename std::aligned_storage<sizeof(Args), alignof(Args)>::type...>& storage_tuple
287 , wait_state<tuple_type>* wait_state
288 , std::true_type)
289 {
290 _self_type::read_accessor_end<N>(storage_tuple, wait_state, eina::make_index_sequence<sizeof...(Args)>{});
291 }
292
293 static void get_success(void* data, Efl_Event const* event)
294 {
295 wait_state<tuple_type>* wait_state_ = static_cast<wait_state<tuple_type>*>(data);
296 Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
297
298 Eina_Accessor* accessor = static_cast<Eina_Accessor*>(info->value);
299 std::tuple<typename std::aligned_storage<sizeof(Args), alignof(Args)>::type...> storage_tuple;
300
301 _self_type::read_accessor<0u>(accessor, storage_tuple, wait_state_, std::false_type());
302 }
303
304 typedef shared_future_varargs_type<Args...> _self_type;
305};
306
307}
308
309template <typename...Args>
310struct shared_future : private
311 std::conditional
312 <
313 sizeof...(Args) == 1
314 , _impl::shared_future_1_type<typename std::tuple_element<0u, std::tuple<Args...>>::type>
315 , typename std::conditional
316 <_impl::is_progress<typename std::tuple_element<sizeof...(Args) - 1, std::tuple<Args...>>::type>::value
317 , typename std::conditional
318 <sizeof...(Args) == 2
319 , _impl::shared_future_1_type<Args...>
320 , _impl::shared_future_varargs_type<Args...>
321 >::type
322 , _impl::shared_future_varargs_type<Args...>
323 >::type
324 >::type
325{
326 typedef typename
327 std::conditional
328 <
329 sizeof...(Args) == 1
330 , _impl::shared_future_1_type<Args...>
331 , typename std::conditional
332 <_impl::is_progress<typename std::tuple_element<sizeof...(Args) - 1, std::tuple<Args...>>::type>::value
333 , typename std::conditional
334 <sizeof...(Args) == 2
335 , _impl::shared_future_1_type<Args...>
336 , _impl::shared_future_varargs_type<Args...>
337 >::type
338 , _impl::shared_future_varargs_type<Args...>
339 >::type
340 >::type
341 _base_type;
342 typedef typename _impl::progress_param<Args...>::type progress_param_type;
343 typedef typename _impl::progress_type<progress_param_type>::type progress_type;
344 typedef typename _base_type::native_handle_type native_handle_type;
345 using _base_type::_base_type;
346 using _base_type::swap;
347 using _base_type::valid;
348 using _base_type::get;
349 using _base_type::wait;
350 using _base_type::native_handle;
351
352 shared_future() = default;
353 template <typename...OtherArgs>
354 shared_future(shared_future<OtherArgs...> const& other
355 , typename std::enable_if<_impl::is_progress_param_compatible
356 <progress_param_type, typename _impl::progress_param<OtherArgs...>::type>::value>::type* = nullptr)
357 : _base_type(static_cast< _impl::shared_future_common const&>(other))
358 {
359 }
360
361 template <typename...OtherArgs>
362 friend struct shared_future;
363};
364
365template <typename...Args>
366struct shared_race_future : private std::conditional<sizeof...(Args) == 1, _impl::shared_race_future_1_type<typename std::tuple_element<0u, std::tuple<Args...>>::type>, void>::type
367{
368 typedef typename std::conditional<sizeof...(Args) == 1, _impl::shared_race_future_1_type<typename std::tuple_element<0u, std::tuple<Args...>>::type>, void>::type _base_type;
369
370 using _base_type::_base_type;
371 using _base_type::swap;
372 using _base_type::valid;
373 using _base_type::get;
374 using _base_type::wait;
375 using _base_type::native_handle;
376 typedef typename _base_type::native_handle_type native_handle_type;
377};
378
379namespace _impl {
380
381template <typename T>
382struct is_race_future : std::false_type {};
383
384template <typename...Args>
385struct is_race_future<shared_race_future<Args...>> : std::true_type {};
386
387}
388
389template <template <typename...> class Future, typename...Args, typename F>
390typename std::enable_if
391<
392 !std::is_same<typename Future<Args...>::progress_type, void>::value
393>::type on_progress(Future<Args...> future, F function)
394{
395 struct private_data
396 {
397 F progress_cb;
398 Future<Args...> future;
399 };
400 private_data* pdata = new private_data
401 {std::move(function), std::move(future)};
402
403 typedef typename Future<Args...>::progress_type progress_type;
404
405 Efl_Event_Cb raw_progress_cb =
406 [] (void* data, Efl_Event const* event)
407 {
408 private_data* pdata = static_cast<private_data*>(data);
409 try
410 {
411 Efl_Future_Event_Progress const* info = static_cast<Efl_Future_Event_Progress const*>(event->info);
412 pdata->progress_cb(*static_cast<progress_type const*>(info->progress));
413 }
414 catch(...)
415 {
416 // what should happen if progress_cb fails?
417 }
418 };
419 Efl_Event_Cb raw_delete_cb =
420 [] (void* data, Efl_Event const*)
421 {
422 private_data* pdata = static_cast<private_data*>(data);
423 delete pdata;
424 };
425
426 assert(pdata->future.valid());
427 efl_future_then(pdata->future.native_handle(), raw_delete_cb, raw_delete_cb, raw_progress_cb, pdata);
428}
429
430template <template <typename...> class Future, typename...Args, typename Success, typename Error>
431shared_future
432<
433 typename std::enable_if
434 <
435 !std::is_same<void, typename std::tuple_element<0, std::tuple<Args...>>::type>::value
436 && !std::is_same<void, typename std::result_of<Success(Args...)>::type>::value
437 , typename std::result_of<Success(Args...)>::type
438 >::type
439> then(Future<Args...> future, Success success_cb, Error error_cb)
440{
441 struct private_data
442 {
443 Success success_cb;
444 Error error_cb;
445 Future<Args...> future;
446 };
447 private_data* pdata = new private_data
448 {std::move(success_cb), std::move(error_cb), std::move(future)};
449
450 Efl_Event_Cb raw_success_cb =
451 [] (void* data, Efl_Event const* event)
452 {
453 private_data* pdata = static_cast<private_data*>(data);
454 try
455 {
456 _impl::future_invoke<Args...>(pdata->success_cb, event, _impl::is_race_future<Future<Args...>>{});
457 // should value_set the next promise
458 }
459 catch(...)
460 {
461 // should fail the next promise
462 }
463 delete pdata;
464 };
465 Efl_Event_Cb raw_error_cb =
466 [] (void* data, Efl_Event const* event)
467 {
468 private_data* pdata = static_cast<private_data*>(data);
469 Efl_Future_Event_Failure* info = static_cast<Efl_Future_Event_Failure*>(event->info);
470 pdata->error_cb(eina::error_code(info->error, eina::eina_error_category()));
471 // should error the next promise (or should the promise do that for me automatically?)
472 delete pdata;
473 };
474
475 assert(pdata->future.valid());
476 Efl_Future* new_future
477 = efl_future_then(pdata->future.native_handle(), raw_success_cb, raw_error_cb, nullptr, pdata);
478 return shared_future<typename std::result_of<Success(Args...)>::type>{efl_ref(new_future)};
479}
480
481// TODO:
482template <typename...Args, typename F>
483void then(shared_future<Args...> future, F function)
484{
485 static_cast<void>(future);
486 static_cast<void>(function);
487}
488
489template <typename...Args1, typename...Args2, typename...Futures>
490typename _impl::all_result_type<shared_future<Args1...>, shared_future<Args2...>, Futures...>::type
491all(shared_future<Args1...> future1, shared_future<Args2...> future2, Futures...futures)
492{
493 return _impl::all_impl(future1, future2, futures...);
494}
495
496template <typename...Args1, typename...Args2, typename...Futures>
497typename _impl::race_result_type<shared_future<Args1...>, shared_future<Args2...>, Futures...>::type
498race(shared_future<Args1...> future1, shared_future<Args2...> future2, Futures...futures)
499{
500 return _impl::race_impl(future1, future2, futures...);
501}
502
503}
504
505#endif
diff --git a/src/bindings/cxx/eo_cxx/eo_promise.hh b/src/bindings/cxx/eo_cxx/eo_promise.hh
deleted file mode 100644
index 5e18e69986..0000000000
--- a/src/bindings/cxx/eo_cxx/eo_promise.hh
+++ /dev/null
@@ -1,148 +0,0 @@
1///
2/// @file eo_promise.hh
3///
4
5#ifndef EFL_CXX_EO_PROMISE_HH
6#define EFL_CXX_EO_PROMISE_HH
7
8#include <Efl.h>
9
10#include <Eina.hh>
11#include <Ecore_Manual.hh>
12
13#include <mutex>
14#include <condition_variable>
15
16#include <eina_tuple.hh>
17#include <eo_promise_meta.hh>
18#include <eo_future.hh>
19
20namespace efl {
21
22template <typename...Args>
23struct shared_future;
24
25namespace _impl {
26
27struct promise_common
28{
29 explicit promise_common(Efl_Promise* _promise) : _promise(_promise) {}
30 explicit promise_common(std::nullptr_t) : _promise(nullptr) {}
31 promise_common()
32 {
33 _promise = efl_add(EFL_PROMISE_CLASS, efl_main_loop_get());
34 }
35 ~promise_common()
36 {
37 if(_promise)
38 ::efl_unref(_promise);
39 }
40 promise_common(promise_common const& other)
41 : _promise( ::efl_ref(other._promise))
42 {
43 }
44 promise_common(promise_common&& other)
45 : _promise(nullptr)
46 {
47 std::swap(*this, other);
48 }
49 promise_common& operator=(promise_common const& other)
50 {
51 _promise = ::efl_ref(other._promise);
52 return *this;
53 }
54 promise_common& operator=(promise_common&& other)
55 {
56 std::swap(*this, other);
57 return *this;
58 }
59 bool valid() const
60 {
61 return _promise != nullptr;
62 }
63 void swap(promise_common& other)
64 {
65 std::swap(*this, other);
66 }
67 void set_exception(std::exception_ptr /*p*/)
68 {
69 }
70
71 Efl_Promise* _promise;
72};
73
74template <typename P>
75struct promise_progress : promise_common
76{
77 void set_progress(P const& progress)
78 {
79 efl_promise_progress_set(this->_promise, &progress);
80 }
81};
82
83template <>
84struct promise_progress<void> : promise_common
85{
86 void set_progress()
87 {
88 efl_promise_progress_set(this->_promise, nullptr);
89 }
90};
91
92template <typename T, typename Progress>
93struct promise_1_type : promise_progress<Progress>
94{
95 void set_value(T const& v)
96 {
97 typedef typename eina::alloc_to_c_traits<T>::c_type c_type;
98 c_type* c_value = eina::alloc_to_c_traits<T>::copy_alloc(v);
99 efl_promise_value_set(this->_promise, c_value, & eina::alloc_to_c_traits<T>::free_alloc);
100 }
101 void set_value(T&& v)
102 {
103 typedef typename eina::alloc_to_c_traits<T>::c_type c_type;
104 c_type* c_value = eina::alloc_to_c_traits<T>::copy_alloc(std::move(v));
105 efl_promise_value_set(this->_promise, c_value, & eina::alloc_to_c_traits<T>::free_alloc);
106 }
107};
108
109template <typename Progress>
110struct promise_1_type<void, Progress> : promise_progress<Progress>
111{
112 void set_value()
113 {
114 efl_promise_value_set(this->_promise, nullptr, nullptr);
115 }
116};
117
118}
119
120template <typename T, typename Progress = void>
121struct promise : private _impl::promise_1_type<T, Progress>
122{
123 typedef _impl::promise_1_type<T, Progress> _base_type;
124 using _base_type::_base_type;
125 using _base_type::set_value;
126 using _base_type::set_progress;
127 using _base_type::set_exception;
128
129 shared_future<T, progress<Progress>> get_future()
130 {
131 return shared_future<T, progress<Progress>>{ ::efl_ref( ::efl_promise_future_get(this->_promise)) };
132 }
133
134 void swap(promise<T, progress<Progress>>& other)
135 {
136 _base_type::swap(other);
137 }
138};
139
140template <typename...Args>
141void swap(promise<Args...>& lhs, promise<Args...>& rhs)
142{
143 lhs.swap(rhs);
144}
145
146}
147
148#endif
diff --git a/src/bindings/cxx/eo_cxx/eo_promise_meta.hh b/src/bindings/cxx/eo_cxx/eo_promise_meta.hh
deleted file mode 100644
index 4d42c20fec..0000000000
--- a/src/bindings/cxx/eo_cxx/eo_promise_meta.hh
+++ /dev/null
@@ -1,332 +0,0 @@
1///
2/// @file eo_promise_meta.hh
3///
4
5#ifndef EFL_CXX_EO_PROMISE_META_HH
6#define EFL_CXX_EO_PROMISE_META_HH
7
8namespace efl {
9
10template <typename...Args>
11struct shared_future;
12
13template <typename...Args>
14struct shared_race_future;
15
16template <typename T>
17struct progress;
18
19namespace _impl {
20
21template <typename T>
22struct is_progress : std::false_type {};
23
24template <typename T>
25struct is_progress<progress<T>> : std::true_type {};
26
27template <typename L, typename R>
28struct is_progress_param_compatible : std::false_type {};
29
30template <typename T>
31struct is_progress_param_compatible<T, T> : std::true_type {};
32
33template <>
34struct is_progress_param_compatible<void, progress<void>> : std::true_type {};
35
36template <>
37struct is_progress_param_compatible<progress<void>, void> : std::true_type {};
38
39template <typename...Args>
40struct progress_param : std::conditional
41 <is_progress<typename std::tuple_element<sizeof...(Args) - 1, std::tuple<Args...>>::type>::value
42 , typename std::tuple_element<sizeof...(Args) - 1, std::tuple<Args...>>::type
43 , void>
44{
45};
46
47template <typename T>
48struct progress_type;
49
50template <typename T>
51struct progress_type<progress<T>>
52{
53 typedef T type;
54};
55
56template <>
57struct progress_type<void>
58{
59 typedef void type;
60};
61
62template <typename...Futures>
63struct all_result_type;
64
65template <typename...Args>
66struct all_result_type<shared_future<Args...>>
67{
68 typedef shared_future<Args...> type;
69};
70
71template <typename...Args1, typename...Args2>
72struct all_result_type<shared_future<Args1...>, shared_future<Args2...>>
73{
74 typedef shared_future<Args1..., Args2...> type;
75};
76
77template <typename...Args1, typename...Args2, typename...OtherFutures>
78struct all_result_type<shared_future<Args1...>, shared_future<Args2...>, OtherFutures...>
79{
80 typedef typename all_result_type<shared_future<Args1..., Args2...>, OtherFutures...>::type type;
81};
82
83template <typename...Futures>
84typename all_result_type<Futures...>::type
85all_impl(Futures const& ... futures)
86{
87 Efl_Future* future = ::efl_future_all_internal(futures.native_handle()..., NULL);
88 return typename all_result_type<Futures...>::type{ ::efl_ref(future)};
89}
90
91template <typename...Futures>
92struct race_result_type;
93
94template <typename...Args>
95struct race_result_type<shared_future<Args...>>
96{
97 typedef shared_race_future<Args...> type;
98};
99
100template <typename T, typename...Args>
101struct race_compose_impl;
102
103template <typename T, typename A0, typename...Args>
104struct race_compose_impl<T, A0, Args...>
105{
106 typedef typename std::conditional<eina::_mpl::tuple_contains<A0, T>::value
107 , typename race_compose_impl<T, Args...>::type
108 , typename race_compose_impl<typename eina::_mpl::push_back<T, A0>::type, Args...>::type
109 >::type type;
110};
111
112template <typename T>
113struct race_compose_impl<T>
114{
115 typedef T type;
116};
117
118template <typename T>
119struct variant_from_tuple;
120
121template <typename...Args>
122struct variant_from_tuple<std::tuple<Args...>>
123{
124 typedef eina::variant<Args...> type;
125};
126
127template <typename...Args>
128struct race_variant
129{
130 typedef typename variant_from_tuple<typename race_compose_impl<std::tuple<>, Args...>::type>::type type;
131};
132
133template <typename A0>
134struct race_result_type<shared_future<A0>>
135{
136 typedef shared_race_future<A0> type;
137};
138
139template <typename A0>
140struct race_result_type<shared_future<eina::variant<A0>>>
141{
142 typedef shared_race_future<A0> type;
143};
144
145template <typename...Args1, typename...Args2>
146struct race_result_type<shared_future<Args1...>, shared_future<Args2...>>
147{
148 typedef typename race_result_type<shared_future<typename race_variant<Args1..., Args2...>::type>>::type type;
149};
150
151template <typename...Args1, typename...Args2, typename...OtherFutures>
152struct race_result_type<shared_future<Args1...>, shared_future<Args2...>, OtherFutures...>
153{
154 typedef typename race_result_type<shared_future<typename race_variant<Args1..., Args2...>::type>
155 , OtherFutures...>::type type;
156};
157
158template <typename...Futures>
159typename race_result_type<Futures...>::type
160race_impl(Futures const& ... futures)
161{
162 Efl_Future* future = ::efl_future_race_internal(futures.native_handle()..., NULL);
163 return typename race_result_type<Futures...>::type{ ::efl_ref(future)};
164}
165
166template <typename T, typename Enabler = void>
167struct future_copy_traits
168{
169 static void copy(T* storage, Efl_Future_Event_Success const* info)
170 {
171 eina::copy_from_c_traits<T>::copy_to_unitialized
172 (storage, info->value);
173 }
174 static void copy_race(T* storage, Efl_Future_Event_Success const* info)
175 {
176 Efl_Future_Race_Success const* race = static_cast<Efl_Future_Race_Success const*>(info->value);
177 eina::copy_from_c_traits<T>::copy_to_unitialized
178 (storage, race->value);
179 }
180};
181
182template <typename...Args>
183struct future_copy_traits<eina::variant<Args...>>
184{
185 template <std::size_t I>
186 static void copy_impl(eina::variant<Args...>*, void const*, int, std::integral_constant<std::size_t, I>
187 , std::integral_constant<std::size_t, I>)
188 {
189 std::abort();
190 }
191
192 template <std::size_t I, std::size_t N>
193 static void copy_impl(eina::variant<Args...>* storage, void const* value, int index, std::integral_constant<std::size_t, I>
194 , std::integral_constant<std::size_t, N> max
195 , typename std::enable_if<I != N>::type* = 0)
196 {
197 if(I == index)
198 {
199 eina::copy_from_c_traits<eina::variant<Args...>>::copy_to_unitialized
200 (storage, static_cast<typename std::tuple_element<I, std::tuple<Args...>>::type const*>
201 (static_cast<void const*>(value)));
202 }
203 else
204 copy_impl(storage, value, index, std::integral_constant<std::size_t, I+1>{}, max);
205 }
206 static void copy(eina::variant<Args...>*, Efl_Future_Event_Success const*)
207 {
208 std::abort();
209 }
210 static void copy_race(eina::variant<Args...>* storage, Efl_Future_Event_Success const* other_info)
211 {
212 Efl_Future_Race_Success const* info = static_cast<Efl_Future_Race_Success const*>
213 (static_cast<void const*>(other_info->value));
214 copy_impl(storage, info->value, info->index, std::integral_constant<std::size_t, 0ul>{}
215 , std::integral_constant<std::size_t, sizeof...(Args)>{});
216 }
217};
218
219template <typename A0, typename F, bool IsRace>
220typename std::enable_if
221<
222 !std::is_same<A0, void>::value
223 && !std::is_same<typename std::result_of<F(A0)>::type, void>::value
224>::type
225future_invoke(F f, Efl_Event const* event, std::integral_constant<bool, IsRace> /* is_race */)
226{
227 Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
228 try
229 {
230 typename std::aligned_storage<sizeof(A0), alignof(A0)>::type storage;
231 if(IsRace)
232 future_copy_traits<A0>::copy_race(static_cast<A0*>(static_cast<void*>(&storage)), info);
233 else
234 future_copy_traits<A0>::copy(static_cast<A0*>(static_cast<void*>(&storage)), info);
235 auto r = f(*static_cast<A0*>(static_cast<void*>(&storage)));
236 typedef decltype(r) result_type;
237 typedef typename eina::alloc_to_c_traits<result_type>::c_type c_type;
238 c_type* c_value = eina::alloc_to_c_traits<result_type>::copy_alloc(r);
239 efl_promise_value_set(info->next, c_value, & eina::alloc_to_c_traits<result_type>::free_alloc);
240 }
241 catch(...)
242 {
243 }
244}
245
246template <typename A0, typename F, bool IsRace>
247typename std::enable_if<std::is_same<A0, void>::value>::type
248future_invoke(F f, Efl_Event const* event, std::integral_constant<bool, IsRace>)
249{
250 Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
251 static_cast<void>(info);
252 try
253 {
254 f();
255 }
256 catch(...)
257 {
258 }
259}
260
261template <std::size_t N, typename...Args, typename...StorageArgs>
262static void future_invoke_impl_read_accessor
263 (Eina_Accessor*, std::tuple<StorageArgs...>&, std::tuple<Args...>*, std::true_type)
264{
265}
266
267template <std::size_t N, typename...Args, typename...StorageArgs>
268static void future_invoke_impl_read_accessor
269 (Eina_Accessor* accessor
270 , std::tuple<StorageArgs...>& storage_tuple
271 , std::tuple<Args...>* args
272 , std::false_type)
273{
274 typedef std::tuple<Args...> tuple_type;
275 typedef typename std::tuple_element<N, tuple_type>::type type;
276 void* value;
277 if(eina_accessor_data_get(accessor, N, &value))
278 {
279 eina::copy_from_c_traits<type>::copy_to_unitialized
280 (static_cast<type*>(static_cast<void*>(&std::get<N>(storage_tuple))), value);
281
282 _impl::future_invoke_impl_read_accessor<N+1>
283 (accessor, storage_tuple, args
284 , std::integral_constant<bool, (N+1 == sizeof...(Args))>());
285 }
286 else
287 {
288 std::abort();
289 // some error
290 }
291}
292
293template <typename F, typename...Args, std::size_t...I, bool IsRace>
294void future_invoke_impl(F f, Efl_Event const* event, std::tuple<Args...>* arguments_dummy, std::integral_constant<bool, IsRace>, eina::index_sequence<I...>)
295{
296 Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
297 try
298 {
299 typedef std::tuple<Args...> arguments;
300 typedef std::tuple<typename std::aligned_storage<sizeof(Args), alignof(Args)>::type...>
301 storage_tuple_type;
302 storage_tuple_type storage_tuple;
303
304 future_invoke_impl_read_accessor<0ul>
305 (static_cast<Eina_Accessor*>(info->value)
306 , storage_tuple
307 , arguments_dummy, std::false_type{});
308
309 auto r = f(*static_cast<typename std::tuple_element<I, arguments>::type*>
310 (static_cast<void*>(&std::get<I>(storage_tuple)))...);
311
312 typedef decltype(r) result_type;
313 typedef typename eina::alloc_to_c_traits<result_type>::c_type c_type;
314 c_type* c_value = eina::alloc_to_c_traits<result_type>::copy_alloc(r);
315 efl_promise_value_set(info->next, c_value, & eina::alloc_to_c_traits<result_type>::free_alloc);
316 }
317 catch(...)
318 {
319 }
320}
321
322template <typename A0, typename A1, typename...OtherArgs, typename F, bool IsRace>
323void
324future_invoke(F f, Efl_Event const* event, std::integral_constant<bool, IsRace> race)
325{
326 std::tuple<A0, A1, OtherArgs...>* p = nullptr;
327 _impl::future_invoke_impl(f, event, p, race, eina::make_index_sequence<sizeof...(OtherArgs) + 2>{});
328}
329
330} }
331
332#endif
diff --git a/src/lib/eolian_cxx/grammar/blacklist.hpp b/src/lib/eolian_cxx/grammar/blacklist.hpp
new file mode 100644
index 0000000000..21332b6f73
--- /dev/null
+++ b/src/lib/eolian_cxx/grammar/blacklist.hpp
@@ -0,0 +1,54 @@
1#ifndef EOLIAN_CXX_BLACKLIST_HH
2#define EOLIAN_CXX_BLACKLIST_HH
3
4#include <algorithm>
5#include "grammar/klass_def.hpp"
6
7namespace efl { namespace eolian { namespace grammar {
8
9namespace blacklist {
10
11bool is_blacklisted(attributes::type_def const& t);
12
13struct type_blacklisted_visitor
14{
15 typedef type_blacklisted_visitor visitor_type;
16 typedef bool result_type;
17
18 bool operator()(attributes::regular_type_def const&) const
19 {
20 return false;
21 }
22 bool operator()(attributes::klass_name const&) const
23 {
24 return false;
25 }
26 bool operator()(attributes::complex_type_def const& c) const
27 {
28 if (c.outer.base_type == "future")
29 return true;
30
31 return std::any_of(c.subtypes.begin(), c.subtypes.end(), is_blacklisted);
32 }
33};
34
35bool is_blacklisted(attributes::type_def const& t)
36{
37 return t.original_type.visit(type_blacklisted_visitor{});
38}
39
40bool is_blacklisted(attributes::function_def const& f)
41{
42 if (is_blacklisted(f.return_type))
43 return true;
44
45 return std::any_of(f.parameters.cbegin(), f.parameters.cend(), [](attributes::parameter_def const& p) { return is_blacklisted(p.type); });
46}
47
48
49} // namespace grammar
50} } } // namespace efl / eolian / grammar
51
52
53
54#endif
diff --git a/src/lib/eolian_cxx/grammar/function_declaration.hpp b/src/lib/eolian_cxx/grammar/function_declaration.hpp
index f30f7569dc..dc6a969a58 100644
--- a/src/lib/eolian_cxx/grammar/function_declaration.hpp
+++ b/src/lib/eolian_cxx/grammar/function_declaration.hpp
@@ -12,6 +12,7 @@
12#include "grammar/type.hpp" 12#include "grammar/type.hpp"
13#include "grammar/parameter.hpp" 13#include "grammar/parameter.hpp"
14#include "grammar/keyword.hpp" 14#include "grammar/keyword.hpp"
15#include "grammar/blacklist.hpp"
15 16
16namespace efl { namespace eolian { namespace grammar { 17namespace efl { namespace eolian { namespace grammar {
17 18
@@ -24,6 +25,9 @@ struct function_declaration_generator
24 template <typename OutputIterator, typename Context> 25 template <typename OutputIterator, typename Context>
25 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& ctx) const 26 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& ctx) const
26 { 27 {
28 if (blacklist::is_blacklisted(f))
29 return true;
30
27 std::string suffix, static_flag, const_flag; 31 std::string suffix, static_flag, const_flag;
28 switch(_klass_name.type) 32 switch(_klass_name.type)
29 { 33 {
diff --git a/src/lib/eolian_cxx/grammar/function_definition.hpp b/src/lib/eolian_cxx/grammar/function_definition.hpp
index 9b646efc9c..b3080e4c67 100644
--- a/src/lib/eolian_cxx/grammar/function_definition.hpp
+++ b/src/lib/eolian_cxx/grammar/function_definition.hpp
@@ -18,6 +18,7 @@
18#include "grammar/attribute_reorder.hpp" 18#include "grammar/attribute_reorder.hpp"
19#include "grammar/type_impl.hpp" 19#include "grammar/type_impl.hpp"
20#include "grammar/eps.hpp" 20#include "grammar/eps.hpp"
21#include "grammar/blacklist.hpp"
21 22
22namespace efl { namespace eolian { namespace grammar { 23namespace efl { namespace eolian { namespace grammar {
23 24
@@ -30,6 +31,9 @@ struct function_definition_generator
30 template <typename OutputIterator, typename Context> 31 template <typename OutputIterator, typename Context>
31 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& ctx) const 32 bool generate(OutputIterator sink, attributes::function_def const& f, Context const& ctx) const
32 { 33 {
34 if (blacklist::is_blacklisted(f))
35 return true;
36
33 std::string suffix; 37 std::string suffix;
34 switch(_klass_name.type) 38 switch(_klass_name.type)
35 { 39 {
diff --git a/src/lib/eolian_cxx/grammar/type_impl.hpp b/src/lib/eolian_cxx/grammar/type_impl.hpp
index ebe738abed..21f59c01da 100644
--- a/src/lib/eolian_cxx/grammar/type_impl.hpp
+++ b/src/lib/eolian_cxx/grammar/type_impl.hpp
@@ -311,12 +311,12 @@ struct visitor_generate
311 (complex, regular_type_def{" ::efl::promise", complex.outer.base_qualifier, {}}); 311 (complex, regular_type_def{" ::efl::promise", complex.outer.base_qualifier, {}});
312 } 312 }
313 } 313 }
314 , {"future", nullptr, nullptr, [&] 314 /* , {"future", nullptr, nullptr, [&] */
315 { 315 /* { */
316 return replace_outer 316 /* return replace_outer */
317 (complex, regular_type_def{" ::efl::shared_future", complex.outer.base_qualifier, {}}); 317 /* (complex, regular_type_def{" ::efl::shared_future", complex.outer.base_qualifier, {}}); */
318 } 318 /* } */
319 } 319 /* } */
320 , {"iterator", nullptr, nullptr, [&] 320 , {"iterator", nullptr, nullptr, [&]
321 { 321 {
322 return replace_outer 322 return replace_outer
diff --git a/src/tests/eo_cxx/eo_cxx_suite.cc b/src/tests/eo_cxx/eo_cxx_suite.cc
index f94731638d..11e014ffff 100644
--- a/src/tests/eo_cxx/eo_cxx_suite.cc
+++ b/src/tests/eo_cxx/eo_cxx_suite.cc
@@ -6,7 +6,6 @@
6#include "../efl_check.h" 6#include "../efl_check.h"
7 7
8static const Efl_Test_Case etc[] = { 8static const Efl_Test_Case etc[] = {
9 { "Promise", eo_cxx_test_promise },
10 { NULL, NULL } 9 { NULL, NULL }
11}; 10};
12 11
diff --git a/src/tests/eo_cxx/eo_cxx_suite.h b/src/tests/eo_cxx/eo_cxx_suite.h
index 094453a581..0645b878ff 100644
--- a/src/tests/eo_cxx/eo_cxx_suite.h
+++ b/src/tests/eo_cxx/eo_cxx_suite.h
@@ -6,6 +6,5 @@
6 6
7#include <check.h> 7#include <check.h>
8#include "../efl_check.h" 8#include "../efl_check.h"
9void eo_cxx_test_promise(TCase* tc);
10 9
11#endif /* _EINA_CXX_SUITE_H */ 10#endif /* _EINA_CXX_SUITE_H */
diff --git a/src/tests/eo_cxx/eo_cxx_test_promise.cc b/src/tests/eo_cxx/eo_cxx_test_promise.cc
deleted file mode 100644
index 86d1534331..0000000000
--- a/src/tests/eo_cxx/eo_cxx_test_promise.cc
+++ /dev/null
@@ -1,14 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Eina.hh>
6#include <Eo.hh>
7#include <Ecore.hh>
8
9#include "eo_cxx_suite.h"
10
11void
12eo_cxx_test_promise(TCase* tc)
13{
14}