felipealmeida pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=e0b444f95f2831738a307cbf64690d8f3bba63b3
commit e0b444f95f2831738a307cbf64690d8f3bba63b3 Author: Felipe Magno de Almeida <[email protected]> Date: Tue Aug 16 23:26:52 2016 -0300 eo-cxx: Add race promises through eina::variant --- src/bindings/cxx/eina_cxx/eina_copy_traits.hh | 23 +++++++++++- src/bindings/cxx/eo_cxx/eo_promise.hh | 50 ++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/bindings/cxx/eina_cxx/eina_copy_traits.hh b/src/bindings/cxx/eina_cxx/eina_copy_traits.hh index 0db8bd8..e6e0164 100644 --- a/src/bindings/cxx/eina_cxx/eina_copy_traits.hh +++ b/src/bindings/cxx/eina_cxx/eina_copy_traits.hh @@ -7,6 +7,15 @@ namespace efl { namespace eina { +namespace _impl { +template<bool...> struct bool_pack; +template <bool...Args> +struct and_ : std::is_same<bool_pack<Args..., true>, bool_pack<true, Args...>> {}; +} + +template <typename... Args> +struct variant; + template <typename T, typename Enable = void> struct copy_from_c_traits; @@ -19,6 +28,18 @@ struct copy_from_c_traits<T, typename std::enable_if<std::is_fundamental<T>::val } }; +template <typename...Args> +struct copy_from_c_traits<eina::variant<Args...>, + typename std::enable_if<_impl::and_<std::is_fundamental<Args>::value...>::value>::type> +{ + template <typename T> + static void copy_to_unitialized(eina::variant<Args...>* storage, T const* data) + { + new (storage) eina::variant<Args...>{*data}; + } +}; + + template <typename T, typename Enable = void> struct alloc_to_c_traits; @@ -37,7 +58,7 @@ struct alloc_to_c_traits<T, typename std::enable_if<std::is_fundamental<T>::valu ::free(data); } }; - + } } #endif diff --git a/src/bindings/cxx/eo_cxx/eo_promise.hh b/src/bindings/cxx/eo_cxx/eo_promise.hh index f9a3261..7c3741a 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{ ::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 @@ -138,8 +182,7 @@ future_invoke(F f, Efl_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(); } --
