summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-08-17 20:48:24 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-09-14 00:33:22 -0300
commit3339f039644243952f98713a99987878a682e1db (patch)
treeebb287bc09f9d7482a54f190e2a21200be5bd9bf
parente0b444f95f2831738a307cbf64690d8f3bba63b3 (diff)
downloadefl-3339f039644243952f98713a99987878a682e1db.tar.gz
eo-cxx: Add promise type
-rw-r--r--src/bindings/cxx/eo_cxx/eo_promise.hh374
-rw-r--r--src/bindings/cxx/eo_cxx/eo_promise_meta.hh272
-rw-r--r--src/tests/eo_cxx/eo_cxx_test_promise.cc65
3 files changed, 448 insertions, 263 deletions
diff --git a/src/bindings/cxx/eo_cxx/eo_promise.hh b/src/bindings/cxx/eo_cxx/eo_promise.hh
index 7c3741adde..30acfd4f20 100644
--- a/src/bindings/cxx/eo_cxx/eo_promise.hh
+++ b/src/bindings/cxx/eo_cxx/eo_promise.hh
@@ -1,5 +1,5 @@
///
-/// @file eo_concrete.hh
+/// @file eo_promise.hh
///
#ifndef EFL_CXX_EO_PROMISE_HH
@@ -14,271 +14,13 @@
#include <condition_variable>
#include <eina_tuple.hh>
+#include <eo_promise_meta.hh>
namespace efl {
template <typename...Args>
struct shared_future;
-namespace _impl {
-
-template <typename...Futures>
-struct all_result_type;
-
-template <typename...Args>
-struct all_result_type<shared_future<Args...>>
-{
- typedef shared_future<Args...> type;
-};
-
-template <typename...Args1, typename...Args2>
-struct all_result_type<shared_future<Args1...>, shared_future<Args2...>>
-{
- typedef shared_future<Args1..., Args2...> type;
-};
-
-template <typename...Args1, typename...Args2, typename...OtherFutures>
-struct all_result_type<shared_future<Args1...>, shared_future<Args2...>, OtherFutures...>
-{
- typedef typename all_result_type<shared_future<Args1..., Args2...>, OtherFutures...>::type type;
-};
-
-template <typename...Futures>
-typename all_result_type<Futures...>::type
-all_impl(Futures const& ... futures)
-{
- Efl_Future* future = ::efl_future_all_internal(futures.native_handle()..., NULL);
- return typename all_result_type<Futures...>::type{ ::efl_ref(future)};
-}
-
-template <typename...Futures>
-struct race_result_type;
-
-template <typename...Args>
-struct race_result_type<shared_future<Args...>>
-{
- typedef shared_future<Args...> type;
-};
-
-template <typename T, typename...Args>
-struct race_compose_impl;
-
-template <typename T, typename A0, typename...Args>
-struct race_compose_impl<T, A0, Args...>
-{
- typedef typename std::conditional<eina::_mpl::tuple_contains<A0, T>::value
- , typename race_compose_impl<T, Args...>::type
- , typename race_compose_impl<typename eina::_mpl::push_back<T, A0>::type, Args...>::type
- >::type type;
-};
-
-template <typename T>
-struct race_compose_impl<T>
-{
- typedef T type;
-};
-
-template <typename T>
-struct variant_from_tuple;
-
-template <typename...Args>
-struct variant_from_tuple<std::tuple<Args...>>
-{
- typedef eina::variant<Args...> type;
-};
-
-template <typename...Args>
-struct race_variant
-{
- typedef typename variant_from_tuple<typename race_compose_impl<std::tuple<>, Args...>::type>::type type;
-};
-
-template <typename A0>
-struct race_result_type<shared_future<A0>>
-{
- typedef shared_future<A0> type;
-};
-
-template <typename A0>
-struct race_result_type<shared_future<eina::variant<A0>>>
-{
- typedef shared_future<A0> type;
-};
-
-template <typename...Args1, typename...Args2>
-struct race_result_type<shared_future<Args1...>, shared_future<Args2...>>
-{
- typedef typename race_result_type<shared_future<typename race_variant<Args1..., Args2...>::type>>::type type;
-};
-
-template <typename...Args1, typename...Args2, typename...OtherFutures>
-struct race_result_type<shared_future<Args1...>, shared_future<Args2...>, OtherFutures...>
-{
- typedef typename race_result_type<shared_future<typename race_variant<Args1..., Args2...>::type>
- , OtherFutures...>::type type;
-};
-
-template <typename...Futures>
-typename race_result_type<Futures...>::type
-race_impl(Futures const& ... futures)
-{
- Efl_Future* future = ::efl_future_race_internal(futures.native_handle()..., NULL);
- return typename race_result_type<Futures...>::type{ ::efl_ref(future)};
-}
-
-template <typename T, typename Enabler = void>
-struct future_copy_traits
-{
- static void copy(T* storage, Efl_Future_Event_Success const* info)
- {
- eina::copy_from_c_traits<T>::copy_to_unitialized
- (storage, info->value);
- }
-};
-
-template <typename...Args>
-struct future_copy_traits<eina::variant<Args...>>
-{
- template <std::size_t I>
- static void copy_impl(eina::variant<Args...>*, void const*, int, std::integral_constant<std::size_t, I>
- , std::integral_constant<std::size_t, I>)
- {
- std::abort();
- }
-
- template <std::size_t I, std::size_t N>
- static void copy_impl(eina::variant<Args...>* storage, void const* value, int index, std::integral_constant<std::size_t, I>
- , std::integral_constant<std::size_t, N> max
- , typename std::enable_if<I != N>::type* = 0)
- {
- if(I == index)
- {
- eina::copy_from_c_traits<eina::variant<Args...>>::copy_to_unitialized
- (storage, static_cast<typename std::tuple_element<I, std::tuple<Args...>>::type const*>
- (static_cast<void const*>(value)));
- }
- else
- copy_impl(storage, value, index, std::integral_constant<std::size_t, I+1>{}, max);
- }
-
- static void copy(eina::variant<Args...>* storage, Efl_Future_Event_Success const* other_info)
- {
- Efl_Future_Race_Success const* info = static_cast<Efl_Future_Race_Success const*>
- (static_cast<void const*>(other_info));
- copy_impl(storage, info->value, info->index, std::integral_constant<std::size_t, 0ul>{}
- , std::integral_constant<std::size_t, sizeof...(Args)>{});
- }
-};
-
-template <typename A0, typename F>
-typename std::enable_if
-<
- !std::is_same<A0, void>::value
- && !std::is_same<typename std::result_of<F(A0)>::type, void>::value
->::type
-future_invoke(F f, Efl_Event const* event)
-{
- Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
- try
- {
- typename std::aligned_storage<sizeof(A0), alignof(A0)>::type storage;
- future_copy_traits<A0>::copy(static_cast<A0*>(static_cast<void*>(&storage)), info);
- auto r = f(*static_cast<A0*>(static_cast<void*>(&storage)));
- typedef decltype(r) result_type;
- typedef typename eina::alloc_to_c_traits<result_type>::c_type c_type;
- c_type* c_value = eina::alloc_to_c_traits<result_type>::copy_alloc(r);
- efl_promise_value_set(info->next, c_value, & eina::alloc_to_c_traits<result_type>::free_alloc);
- }
- catch(...)
- {
- }
-}
-
-template <typename A0, typename F>
-typename std::enable_if<std::is_same<A0, void>::value>::type
-future_invoke(F f, Efl_Event const* event)
-{
- Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
- try
- {
- f();
- }
- catch(...)
- {
- }
-}
-
-template <std::size_t N, typename...Args, typename...StorageArgs>
-static void future_invoke_impl_read_accessor
- (Eina_Accessor*, std::tuple<StorageArgs...>&, std::tuple<Args...>*, std::true_type)
-{
-}
-
-template <std::size_t N, typename...Args, typename...StorageArgs>
-static void future_invoke_impl_read_accessor
- (Eina_Accessor* accessor
- , std::tuple<StorageArgs...>& storage_tuple
- , std::tuple<Args...>* args
- , std::false_type)
-{
- typedef std::tuple<Args...> tuple_type;
- typedef typename std::tuple_element<N, tuple_type>::type type;
- void* value;
- if(eina_accessor_data_get(accessor, N, &value))
- {
- eina::copy_from_c_traits<type>::copy_to_unitialized
- (static_cast<type*>(static_cast<void*>(&std::get<N>(storage_tuple))), value);
-
- _impl::future_invoke_impl_read_accessor<N+1>
- (accessor, storage_tuple, args
- , std::integral_constant<bool, (N+1 == sizeof...(Args))>());
- }
- else
- {
- std::abort();
- // some error
- }
-}
-
-template <typename F, typename...Args, std::size_t...I>
-void future_invoke_impl(F f, Efl_Event const* event, std::tuple<Args...>* arguments_dummy, eina::index_sequence<I...>)
-{
- Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
- try
- {
- typedef std::tuple<Args...> arguments;
- typedef std::tuple<typename std::aligned_storage<sizeof(Args), alignof(Args)>::type...>
- storage_tuple_type;
- storage_tuple_type storage_tuple;
-
- future_invoke_impl_read_accessor<0ul>
- (static_cast<Eina_Accessor*>(info->value)
- , storage_tuple
- , arguments_dummy, std::false_type{});
-
- auto r = f(*static_cast<typename std::tuple_element<I, arguments>::type*>
- (static_cast<void*>(&std::get<I>(storage_tuple)))...);
-
- typedef decltype(r) result_type;
- typedef typename eina::alloc_to_c_traits<result_type>::c_type c_type;
- c_type* c_value = eina::alloc_to_c_traits<result_type>::copy_alloc(r);
- efl_promise_value_set(info->next, c_value, & eina::alloc_to_c_traits<result_type>::free_alloc);
- }
- catch(...)
- {
- }
-}
-
-template <typename A0, typename A1, typename...OtherArgs, typename F>
-void
-future_invoke(F f, Efl_Event const* event)
-{
- std::tuple<A0, A1, OtherArgs...>* p = nullptr;
- _impl::future_invoke_impl(f, event, p, eina::make_index_sequence<sizeof...(OtherArgs) + 2>{});
-}
-
-}
-
template <typename T>
struct progress;
@@ -609,13 +351,119 @@ race(shared_future<Args1...> future1, shared_future<Args2...> future2, Futures..
{
return _impl::race_impl(future1, future2, futures...);
}
+
+namespace _impl {
+
+struct promise_common
+{
+ explicit promise_common(Efl_Promise* _promise) : _promise(_promise) {}
+ explicit promise_common(std::nullptr_t) : _promise(nullptr) {}
+ promise_common()
+ {
+ _promise = efl_add(EFL_PROMISE_CLASS, ecore_main_loop_get());
+ }
+ ~promise_common()
+ {
+ if(_promise)
+ ::efl_unref(_promise);
+ }
+ promise_common(promise_common const& other)
+ : _promise( ::efl_ref(other._promise))
+ {
+ }
+ promise_common(promise_common&& other)
+ : _promise(nullptr)
+ {
+ std::swap(*this, other);
+ }
+ promise_common& operator=(promise_common const& other)
+ {
+ _promise = ::efl_ref(other._promise);
+ return *this;
+ }
+ promise_common& operator=(promise_common&& other)
+ {
+ std::swap(*this, other);
+ return *this;
+ }
+ bool valid() const
+ {
+ return _promise != nullptr;
+ }
+ void swap(promise_common& other)
+ {
+ std::swap(*this, other);
+ }
+ void set_exception(std::exception_ptr /*p*/)
+ {
+ }
-template <typename...Args>
-struct promise
+ Efl_Promise* _promise;
+};
+
+template <typename T>
+struct promise_1_type : promise_common
{
+ typedef promise_common _base_type;
+ using _base_type::_base_type;
+ using _base_type::swap;
+ using _base_type::set_exception;
+ void set_value(T const& v)
+ {
+ typedef typename eina::alloc_to_c_traits<T>::c_type c_type;
+ c_type* c_value = eina::alloc_to_c_traits<T>::copy_alloc(v);
+ efl_promise_value_set(this->_promise, c_value, & eina::alloc_to_c_traits<T>::free_alloc);
+ }
+ void set_value(T&& v)
+ {
+ typedef typename eina::alloc_to_c_traits<T>::c_type c_type;
+ c_type* c_value = eina::alloc_to_c_traits<T>::copy_alloc(std::move(v));
+ efl_promise_value_set(this->_promise, c_value, & eina::alloc_to_c_traits<T>::free_alloc);
+ }
};
-
+
+template <>
+struct promise_1_type<void> : promise_common
+{
+ typedef promise_common _base_type;
+ using _base_type::_base_type;
+ using _base_type::swap;
+ using _base_type::set_exception;
+
+ void set_value()
+ {
+ efl_promise_value_set(this->_promise, nullptr, nullptr);
+ }
+};
+
+}
+
+template <typename T, typename Progress = void>
+struct promise : private _impl::promise_1_type<T>
+{
+ typedef _impl::promise_1_type<T> _base_type;
+ using _base_type::_base_type;
+ using _base_type::set_value;
+ using _base_type::set_exception;
+
+ shared_future<T> get_future()
+ {
+ return shared_future<T>{ ::efl_ref( ::efl_promise_future_get(this->_promise)) };
+ }
+
+ void swap(promise<T>& other)
+ {
+ _base_type::swap(other);
+ }
+};
+
+template <typename...Args>
+void swap(promise<Args...>& lhs, promise<Args...>& rhs)
+{
+ lhs.swap(rhs);
+}
+
}
#endif
diff --git a/src/bindings/cxx/eo_cxx/eo_promise_meta.hh b/src/bindings/cxx/eo_cxx/eo_promise_meta.hh
new file mode 100644
index 0000000000..88f4197960
--- /dev/null
+++ b/src/bindings/cxx/eo_cxx/eo_promise_meta.hh
@@ -0,0 +1,272 @@
+///
+/// @file eo_promise_meta.hh
+///
+
+#ifndef EFL_CXX_EO_PROMISE_META_HH
+#define EFL_CXX_EO_PROMISE_META_HH
+
+namespace efl {
+
+template <typename...Args>
+struct shared_future;
+
+namespace _impl {
+
+template <typename...Futures>
+struct all_result_type;
+
+template <typename...Args>
+struct all_result_type<shared_future<Args...>>
+{
+ typedef shared_future<Args...> type;
+};
+
+template <typename...Args1, typename...Args2>
+struct all_result_type<shared_future<Args1...>, shared_future<Args2...>>
+{
+ typedef shared_future<Args1..., Args2...> type;
+};
+
+template <typename...Args1, typename...Args2, typename...OtherFutures>
+struct all_result_type<shared_future<Args1...>, shared_future<Args2...>, OtherFutures...>
+{
+ typedef typename all_result_type<shared_future<Args1..., Args2...>, OtherFutures...>::type type;
+};
+
+template <typename...Futures>
+typename all_result_type<Futures...>::type
+all_impl(Futures const& ... futures)
+{
+ Efl_Future* future = ::efl_future_all_internal(futures.native_handle()..., NULL);
+ return typename all_result_type<Futures...>::type{ ::efl_ref(future)};
+}
+
+template <typename...Futures>
+struct race_result_type;
+
+template <typename...Args>
+struct race_result_type<shared_future<Args...>>
+{
+ typedef shared_future<Args...> type;
+};
+
+template <typename T, typename...Args>
+struct race_compose_impl;
+
+template <typename T, typename A0, typename...Args>
+struct race_compose_impl<T, A0, Args...>
+{
+ typedef typename std::conditional<eina::_mpl::tuple_contains<A0, T>::value
+ , typename race_compose_impl<T, Args...>::type
+ , typename race_compose_impl<typename eina::_mpl::push_back<T, A0>::type, Args...>::type
+ >::type type;
+};
+
+template <typename T>
+struct race_compose_impl<T>
+{
+ typedef T type;
+};
+
+template <typename T>
+struct variant_from_tuple;
+
+template <typename...Args>
+struct variant_from_tuple<std::tuple<Args...>>
+{
+ typedef eina::variant<Args...> type;
+};
+
+template <typename...Args>
+struct race_variant
+{
+ typedef typename variant_from_tuple<typename race_compose_impl<std::tuple<>, Args...>::type>::type type;
+};
+
+template <typename A0>
+struct race_result_type<shared_future<A0>>
+{
+ typedef shared_future<A0> type;
+};
+
+template <typename A0>
+struct race_result_type<shared_future<eina::variant<A0>>>
+{
+ typedef shared_future<A0> type;
+};
+
+template <typename...Args1, typename...Args2>
+struct race_result_type<shared_future<Args1...>, shared_future<Args2...>>
+{
+ typedef typename race_result_type<shared_future<typename race_variant<Args1..., Args2...>::type>>::type type;
+};
+
+template <typename...Args1, typename...Args2, typename...OtherFutures>
+struct race_result_type<shared_future<Args1...>, shared_future<Args2...>, OtherFutures...>
+{
+ typedef typename race_result_type<shared_future<typename race_variant<Args1..., Args2...>::type>
+ , OtherFutures...>::type type;
+};
+
+template <typename...Futures>
+typename race_result_type<Futures...>::type
+race_impl(Futures const& ... futures)
+{
+ Efl_Future* future = ::efl_future_race_internal(futures.native_handle()..., NULL);
+ return typename race_result_type<Futures...>::type{ ::efl_ref(future)};
+}
+
+template <typename T, typename Enabler = void>
+struct future_copy_traits
+{
+ static void copy(T* storage, Efl_Future_Event_Success const* info)
+ {
+ eina::copy_from_c_traits<T>::copy_to_unitialized
+ (storage, info->value);
+ }
+};
+
+template <typename...Args>
+struct future_copy_traits<eina::variant<Args...>>
+{
+ template <std::size_t I>
+ static void copy_impl(eina::variant<Args...>*, void const*, int, std::integral_constant<std::size_t, I>
+ , std::integral_constant<std::size_t, I>)
+ {
+ std::abort();
+ }
+
+ template <std::size_t I, std::size_t N>
+ static void copy_impl(eina::variant<Args...>* storage, void const* value, int index, std::integral_constant<std::size_t, I>
+ , std::integral_constant<std::size_t, N> max
+ , typename std::enable_if<I != N>::type* = 0)
+ {
+ if(I == index)
+ {
+ eina::copy_from_c_traits<eina::variant<Args...>>::copy_to_unitialized
+ (storage, static_cast<typename std::tuple_element<I, std::tuple<Args...>>::type const*>
+ (static_cast<void const*>(value)));
+ }
+ else
+ copy_impl(storage, value, index, std::integral_constant<std::size_t, I+1>{}, max);
+ }
+
+ static void copy(eina::variant<Args...>* storage, Efl_Future_Event_Success const* other_info)
+ {
+ Efl_Future_Race_Success const* info = static_cast<Efl_Future_Race_Success const*>
+ (static_cast<void const*>(other_info));
+ copy_impl(storage, info->value, info->index, std::integral_constant<std::size_t, 0ul>{}
+ , std::integral_constant<std::size_t, sizeof...(Args)>{});
+ }
+};
+
+template <typename A0, typename F>
+typename std::enable_if
+<
+ !std::is_same<A0, void>::value
+ && !std::is_same<typename std::result_of<F(A0)>::type, void>::value
+>::type
+future_invoke(F f, Efl_Event const* event)
+{
+ Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
+ try
+ {
+ typename std::aligned_storage<sizeof(A0), alignof(A0)>::type storage;
+ future_copy_traits<A0>::copy(static_cast<A0*>(static_cast<void*>(&storage)), info);
+ auto r = f(*static_cast<A0*>(static_cast<void*>(&storage)));
+ typedef decltype(r) result_type;
+ typedef typename eina::alloc_to_c_traits<result_type>::c_type c_type;
+ c_type* c_value = eina::alloc_to_c_traits<result_type>::copy_alloc(r);
+ efl_promise_value_set(info->next, c_value, & eina::alloc_to_c_traits<result_type>::free_alloc);
+ }
+ catch(...)
+ {
+ }
+}
+
+template <typename A0, typename F>
+typename std::enable_if<std::is_same<A0, void>::value>::type
+future_invoke(F f, Efl_Event const* event)
+{
+ Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
+ try
+ {
+ f();
+ }
+ catch(...)
+ {
+ }
+}
+
+template <std::size_t N, typename...Args, typename...StorageArgs>
+static void future_invoke_impl_read_accessor
+ (Eina_Accessor*, std::tuple<StorageArgs...>&, std::tuple<Args...>*, std::true_type)
+{
+}
+
+template <std::size_t N, typename...Args, typename...StorageArgs>
+static void future_invoke_impl_read_accessor
+ (Eina_Accessor* accessor
+ , std::tuple<StorageArgs...>& storage_tuple
+ , std::tuple<Args...>* args
+ , std::false_type)
+{
+ typedef std::tuple<Args...> tuple_type;
+ typedef typename std::tuple_element<N, tuple_type>::type type;
+ void* value;
+ if(eina_accessor_data_get(accessor, N, &value))
+ {
+ eina::copy_from_c_traits<type>::copy_to_unitialized
+ (static_cast<type*>(static_cast<void*>(&std::get<N>(storage_tuple))), value);
+
+ _impl::future_invoke_impl_read_accessor<N+1>
+ (accessor, storage_tuple, args
+ , std::integral_constant<bool, (N+1 == sizeof...(Args))>());
+ }
+ else
+ {
+ std::abort();
+ // some error
+ }
+}
+
+template <typename F, typename...Args, std::size_t...I>
+void future_invoke_impl(F f, Efl_Event const* event, std::tuple<Args...>* arguments_dummy, eina::index_sequence<I...>)
+{
+ Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
+ try
+ {
+ typedef std::tuple<Args...> arguments;
+ typedef std::tuple<typename std::aligned_storage<sizeof(Args), alignof(Args)>::type...>
+ storage_tuple_type;
+ storage_tuple_type storage_tuple;
+
+ future_invoke_impl_read_accessor<0ul>
+ (static_cast<Eina_Accessor*>(info->value)
+ , storage_tuple
+ , arguments_dummy, std::false_type{});
+
+ auto r = f(*static_cast<typename std::tuple_element<I, arguments>::type*>
+ (static_cast<void*>(&std::get<I>(storage_tuple)))...);
+
+ typedef decltype(r) result_type;
+ typedef typename eina::alloc_to_c_traits<result_type>::c_type c_type;
+ c_type* c_value = eina::alloc_to_c_traits<result_type>::copy_alloc(r);
+ efl_promise_value_set(info->next, c_value, & eina::alloc_to_c_traits<result_type>::free_alloc);
+ }
+ catch(...)
+ {
+ }
+}
+
+template <typename A0, typename A1, typename...OtherArgs, typename F>
+void
+future_invoke(F f, Efl_Event const* event)
+{
+ std::tuple<A0, A1, OtherArgs...>* p = nullptr;
+ _impl::future_invoke_impl(f, event, p, eina::make_index_sequence<sizeof...(OtherArgs) + 2>{});
+}
+
+} }
+
+#endif
diff --git a/src/tests/eo_cxx/eo_cxx_test_promise.cc b/src/tests/eo_cxx/eo_cxx_test_promise.cc
index 151b9376e9..4e5cf9a675 100644
--- a/src/tests/eo_cxx/eo_cxx_test_promise.cc
+++ b/src/tests/eo_cxx/eo_cxx_test_promise.cc
@@ -867,6 +867,68 @@ START_TEST(eo_cxx_future_race_variant_then_value)
}
END_TEST
+template <typename...Args>
+void eo_cxx_promise_construct_and_destroy_impl()
+{
+ ecore_init();
+
+ {
+ efl::promise<Args...> promise;
+ efl::shared_future<Args...> f = promise.get_future();
+ }
+ ecore_shutdown();
+}
+
+START_TEST(eo_cxx_promise_construct_and_destroy)
+{
+ eo_cxx_promise_construct_and_destroy_impl<int>();
+}
+END_TEST
+
+template <typename T>
+struct test_value_get;
+
+template <>
+struct test_value_get<int>
+{
+ static int get() { return 5; }
+};
+
+template <typename T>
+void eo_cxx_promise_value_set_impl()
+{
+ ecore_init();
+
+ {
+ efl::promise<T> promise;
+ efl::shared_future<T> f = promise.get_future();
+
+ std::thread thread
+ ([&] {
+ efl::ecore::main_loop_thread_safe_call_sync([]{}); // wait for ecore_main_loop_begin() call to start
+ efl::ecore::main_loop_thread_safe_call_async
+ ([&]
+ {
+ promise.set_value(test_value_get<T>::get());
+ });
+
+ T value = f.get();
+ ck_assert_int_eq(value, test_value_get<T>::get());
+ efl::ecore::main_loop_thread_safe_call_sync([] { ecore_main_loop_quit(); });
+ });
+
+ ecore_main_loop_begin();
+
+ thread.join();
+ }
+ ecore_shutdown();
+}
+
+START_TEST(eo_cxx_promise_value_set)
+{
+ eo_cxx_promise_value_set_impl<int>();
+}
+END_TEST
void
eo_cxx_test_promise(TCase* tc)
@@ -893,4 +955,7 @@ eo_cxx_test_promise(TCase* tc)
tcase_add_test(tc, eo_cxx_future_race_variant_get);
tcase_add_test(tc, eo_cxx_future_race_variant_then_value);
+
+ tcase_add_test(tc, eo_cxx_promise_construct_and_destroy);
+ tcase_add_test(tc, eo_cxx_promise_value_set);
}