summaryrefslogtreecommitdiff
path: root/src/bindings/cxx/eo_cxx/eo_promise.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/bindings/cxx/eo_cxx/eo_promise.hh')
-rw-r--r--src/bindings/cxx/eo_cxx/eo_promise.hh50
1 files changed, 46 insertions, 4 deletions
diff --git a/src/bindings/cxx/eo_cxx/eo_promise.hh b/src/bindings/cxx/eo_cxx/eo_promise.hh
index 74d662b615..666cde36f0 100644
--- a/src/bindings/cxx/eo_cxx/eo_promise.hh
+++ b/src/bindings/cxx/eo_cxx/eo_promise.hh
@@ -125,6 +125,50 @@ race_impl(Futures const& ... futures)
Efl_Future* future = ::efl_future_race_internal(futures.native_handle()..., NULL);
return typename race_result_type<Futures...>::type{ ::eo_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
@@ -138,8 +182,7 @@ future_invoke(F f, Eo_Event const* event)
try
{
typename std::aligned_storage<sizeof(A0), alignof(A0)>::type storage;
- eina::copy_from_c_traits<A0>::copy_to_unitialized
- (static_cast<A0*>(static_cast<void*>(&storage)), info->value);
+ 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;
@@ -375,8 +418,7 @@ struct shared_future_1_type : private shared_future_common
Efl_Future_Event_Success* info = static_cast<Efl_Future_Event_Success*>(event->info);
std::unique_lock<std::mutex> l(wait_state->mutex);
- eina::copy_from_c_traits<T>::copy_to_unitialized
- (static_cast<T*>(static_cast<void*>(&wait_state->storage)), info->value);
+ _impl::future_copy_traits<T>::copy(static_cast<T*>(static_cast<void*>(&wait_state->storage)), info);
wait_state->available = true;
wait_state->cv.notify_one();
}