/// /// @file eo_promise.hh /// #ifndef EFL_CXX_EO_PROMISE_HH #define EFL_CXX_EO_PROMISE_HH #include #include #include #include #include #include #include #include namespace efl { template struct shared_future; 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*/) { } Efl_Promise* _promise; }; template struct promise_progress : promise_common { void set_progress(P const& progress) { efl_promise_progress_set(this->_promise, &progress); } }; template <> struct promise_progress : promise_common { void set_progress() { efl_promise_progress_set(this->_promise, nullptr); } }; template struct promise_1_type : promise_progress { void set_value(T const& v) { typedef typename eina::alloc_to_c_traits::c_type c_type; c_type* c_value = eina::alloc_to_c_traits::copy_alloc(v); efl_promise_value_set(this->_promise, c_value, & eina::alloc_to_c_traits::free_alloc); } void set_value(T&& v) { typedef typename eina::alloc_to_c_traits::c_type c_type; c_type* c_value = eina::alloc_to_c_traits::copy_alloc(std::move(v)); efl_promise_value_set(this->_promise, c_value, & eina::alloc_to_c_traits::free_alloc); } }; template struct promise_1_type : promise_progress { void set_value() { efl_promise_value_set(this->_promise, nullptr, nullptr); } }; } template struct promise : private _impl::promise_1_type { typedef _impl::promise_1_type _base_type; using _base_type::_base_type; using _base_type::set_value; using _base_type::set_progress; using _base_type::set_exception; shared_future> get_future() { return shared_future>{ ::efl_ref( ::efl_promise_future_get(this->_promise)) }; } void swap(promise>& other) { _base_type::swap(other); } }; template void swap(promise& lhs, promise& rhs) { lhs.swap(rhs); } } #endif