7 #include <execution/CommonDefs.h>
8 #include <execution/ExFuture.h>
11 #include <parallelism/Barrier.h>
14 #include <type_traits>
50 has_microthreading =
false
55 has_parallelism =
false
63 template <
class F,
class ExecutorAgent>
67 typedef std::invoke_result_t<F> TRet;
69 ex.template launch<TRet>( std::forward<F>( f ), result );
77 template <
class TArg,
class F,
class ExecutorAgent>
78 ExFuture<ExecutorAgent, std::invoke_result_t<F, TArg>>
89 typedef std::invoke_result_t<F, TArg> TRet;
92 ex.template launch<TRet>( std::forward<F>( f ),
93 std::forward<TArg>( arg ), result );
103 template <
class ExecutorAgent>
106 return launch( ex, [] {} );
113 template <
class ExecutorAgent,
class TArg,
class TRet>
114 ExFuture<ExecutorAgent,
115 typename std::remove_cv<
116 typename std::remove_reference<TRet>::type>::type>
120 !std::is_lvalue_reference<TRet>::value ||
122 typename std::remove_reference<TRet>::type>::value,
123 "execution::inmediate. Use std::ref() to pass argument as "
125 using NewType =
typename std::remove_cv<
126 typename std::remove_reference<TRet>::type>::type;
131 arg = std::forward<TRet>( arg )]( ValueType& input )
mutable
138 if ( input.isValid() )
141 fut.agent, [result, arg = std::forward<TRet>(
142 arg )]() mutable noexcept
143 { result.setValue( std::forward<TRet>( arg ) ); } );
149 [result, err = std::move(
150 input.error() )]()
mutable noexcept
151 { result.setError( std::move( err ) ); } );
163 template <
class F,
class TArg,
class ExecutorAgent>
164 ExFuture<ExecutorAgent, std::invoke_result_t<F, TArg>>
168 static_assert( std::is_invocable<F, TArg>::value,
169 "execution::next bad functor signature" );
171 typedef std::invoke_result_t<F, TArg> TRet;
177 [source, f = std::move( f ), result]( ValueType& input )
mutable
179 if ( input.isValid() )
185 source.agent.template launch<TRet>(
186 [f = std::move( f )](
187 ExFuture<ExecutorAgent, TArg>&
188 arg ) mutable noexcept( std::
189 is_nothrow_invocable<
192 -> TRet { return f( arg.getValue().value() ); },
199 [result, err = std::move(
200 input.error() )]()
mutable noexcept
201 { result.setError( std::move( err ) ); } );
208 template <
class F,
class ExecutorAgent>
209 ExFuture<ExecutorAgent, std::invoke_result_t<F>>
210 next( ExFuture<ExecutorAgent, void> source, F f )
212 typedef typename ExFuture<ExecutorAgent, void>::ValueType ValueType;
213 typedef std::invoke_result_t<F> TRet;
214 ExFuture<ExecutorAgent, TRet> result( source.agent );
215 source.subscribeCallback(
218 [source, f = std::forward<F>( f ),
219 result]( ValueType& input )
mutable
221 if ( input.isValid() )
223 if constexpr ( noexcept( f() ) )
228 source.agent.template launch<TRet>(
229 [f = std::move( f )](
230 ExFuture<ExecutorAgent, void>&
231 arg ) noexcept -> TRet { return f(); },
239 source.agent.template launch<TRet>(
240 [f = std::move( f )](
241 ExFuture<ExecutorAgent, void>& arg ) -> TRet
250 [result, err = std::move(
251 input.error() )]()
mutable noexcept
252 { result.setError( std::move( err ) ); } );
263 template <
class NewExecutorAgent,
class OldExecutorAgent,
class TRet>
264 ExFuture<NewExecutorAgent, TRet>
270 typename ExFuture<OldExecutorAgent, TRet>::ValueType ValueType;
272 [result, source]( ValueType& input )
mutable
275 result.assign( source );
288 template <
class ExecutorAgent,
class TArg,
class I,
class F>
289 ExFuture<ExecutorAgent, TArg>
291 F functor,
int increment = 1 )
296 [source, functor = std::move( functor ), result,
297 getIteratorsFunc = std::move( getIteratorsFunc ),
298 increment]( ValueType& input )
mutable
302 if ( input.isValid() )
304 std::exception_ptr* except =
305 new std::exception_ptr( nullptr );
306 ::mel::parallelism::Barrier barrier;
307 auto iterators = getIteratorsFunc( input.value() );
308 using IteratorType = decltype( iterators[0] );
310 std::is_invocable<F, IteratorType, TArg>::value,
311 "execution::loop bad functor signature" );
312 if constexpr ( std::is_nothrow_invocable<
313 F, IteratorType, TArg>::value )
315 barrier = source.agent.loop(
316 iterators[0], iterators[1],
317 [f = std::move( functor ),
318 source]( auto idx ) mutable noexcept
324 f( idx, source.getValue().value() );
330 barrier = source.agent.loop(
331 iterators[0], iterators[1],
332 [f = std::move( functor ), source,
333 except]( auto idx ) mutable
337 f( idx, source.getValue().value() );
343 std::current_exception();
348 barrier.subscribeCallback(
350 const ::mel::parallelism::BarrierData& )>(
352 except]( const ::mel::parallelism::
353 BarrierData& )
mutable
356 result.setError( *except );
364 result.assign( source );
366 return ::mel::core::ECallbackResult::
375 [result, err = std::move(
376 input.error() )]()
mutable noexcept
377 { result.setError( std::move( err ) ); } );
382 result.setError( std::current_exception() );
391 template <
class ExecutorAgent,
class I,
class F>
392 ExFuture<ExecutorAgent, void>
393 loop( ExFuture<ExecutorAgent, void> source, I getIteratorsFunc,
394 F functor,
int increment = 1 )
396 static_assert( std::is_invocable<F, int>::value,
397 "execution::loop bad functor signature" );
398 ExFuture<ExecutorAgent, void> result( source.agent );
399 typedef typename ExFuture<ExecutorAgent, void>::ValueType ValueType;
400 source.subscribeCallback(
401 [source, functor = std::move( functor ), result,
402 getIteratorsFunc = std::move( getIteratorsFunc ),
403 increment]( ValueType& input )
mutable
407 if ( input.isValid() )
409 auto iterators = getIteratorsFunc();
410 std::exception_ptr* except =
411 new std::exception_ptr( nullptr );
412 ::mel::parallelism::Barrier barrier;
413 if constexpr ( std::is_nothrow_invocable<
414 F, decltype( iterators[0] )>::
417 barrier = source.agent.loop(
418 iterators[0], iterators[1],
419 [f = std::move( functor ),
420 source]( auto idx ) mutable noexcept
426 barrier = source.agent.loop(
427 iterators[0], iterators[1],
428 [f = std::move( functor ), source,
429 except]( auto idx ) mutable
439 std::current_exception();
445 barrier.subscribeCallback(
447 const ::mel::parallelism::BarrierData& )>(
449 except]( const ::mel::parallelism::
450 BarrierData& )
mutable
453 result.setError( *except );
461 result.assign( source );
463 return ::mel::core::ECallbackResult::
472 [result, err = std::move(
473 input.error() )]()
mutable noexcept
474 { result.setError( std::move( err ) ); } );
480 result.setError( std::current_exception() );
497 template <
class ExecutorAgent,
class TArg,
class... FTypes>
498 ExFuture<ExecutorAgent, TArg>
510 fs = std::make_tuple( std::move( functions )... )](
511 ValueType& input )
mutable
513 if ( input.isValid() )
515 std::exception_ptr* except =
516 new std::exception_ptr( nullptr );
519 auto barrier = source.agent.parallel(
521 std::move( std::get<FTypes>( fs ) )... );
522 barrier.subscribeCallback(
523 std::function<::mel::core::ECallbackResult(
524 const ::mel::parallelism::BarrierData& )>(
526 except]( const ::mel::parallelism::
527 BarrierData& ) mutable
530 result.setError( *except );
532 result.assign( source );
534 return ::mel::core::ECallbackResult::
542 [result, err = std::move(
543 input.error() )]()
mutable noexcept
544 { result.setError( std::move( err ) ); } );
557 template <
class F,
class TArg,
class ExecutorAgent>
558 ExFuture<ExecutorAgent, TArg>
566 [source, f = std::forward<F>( f ),
567 result]( ValueType& input )
mutable
569 if ( !input.isValid() )
574 f = std::forward<F>( f )]() mutable noexcept
576 if constexpr ( std::is_nothrow_invocable<
578 std::exception_ptr>::value )
580 f( source.getValue().error() ) );
586 f( source.getValue().error() ) );
591 std::current_exception() );
597 result.assign( source );
604 using ::mel::execution::VoidType;
605 template <
class F,
class TArg>
struct inv_res
607 using _realtype = std::invoke_result_t<F, TArg>;
611 typename mel::execution::WrapperType<_realtype>::type;
613 template <
class F>
struct inv_res<F, void>
615 using _realtype = std::invoke_result_t<F>;
617 typename mel::execution::WrapperType<_realtype>::type;
620 template <
class TArg,
class F1 = void,
class F2 = void,
621 class F3 = void,
class F4 = void,
class F5 = void,
622 class F6 = void,
class F7 = void,
class F8 = void,
626 using type = std::tuple<typename inv_res<F1, TArg>::type,
627 typename inv_res<F2, TArg>::type,
628 typename inv_res<F3, TArg>::type,
629 typename inv_res<F4, TArg>::type,
630 typename inv_res<F5, TArg>::type,
631 typename inv_res<F6, TArg>::type,
632 typename inv_res<F7, TArg>::type,
633 typename inv_res<F8, TArg>::type,
634 typename inv_res<F9, TArg>::type>;
636 template <
class TArg,
class F1,
class F2,
class F3,
class F4,
637 class F5,
class F6,
class F7,
class F8>
638 struct GetReturn<TArg, F1, F2, F3, F4, F5, F6, F7, F8, void>
640 using type = std::tuple<typename inv_res<F1, TArg>::type,
641 typename inv_res<F2, TArg>::type,
642 typename inv_res<F3, TArg>::type,
643 typename inv_res<F4, TArg>::type,
644 typename inv_res<F5, TArg>::type,
645 typename inv_res<F6, TArg>::type,
646 typename inv_res<F7, TArg>::type,
647 typename inv_res<F8, TArg>::type>;
649 template <
class TArg,
class F1,
class F2,
class F3,
class F4,
650 class F5,
class F6,
class F7>
651 struct GetReturn<TArg, F1, F2, F3, F4, F5, F6, F7, void, void>
653 using type = std::tuple<typename inv_res<F1, TArg>::type,
654 typename inv_res<F2, TArg>::type,
655 typename inv_res<F3, TArg>::type,
656 typename inv_res<F4, TArg>::type,
657 typename inv_res<F5, TArg>::type,
658 typename inv_res<F6, TArg>::type,
659 typename inv_res<F7, TArg>::type>;
661 template <
class TArg,
class F1,
class F2,
class F3,
class F4,
663 struct GetReturn<TArg, F1, F2, F3, F4, F5, F6, void, void, void>
665 using type = std::tuple<typename inv_res<F1, TArg>::type,
666 typename inv_res<F2, TArg>::type,
667 typename inv_res<F3, TArg>::type,
668 typename inv_res<F4, TArg>::type,
669 typename inv_res<F5, TArg>::type,
670 typename inv_res<F6, TArg>::type>;
672 template <
class TArg,
class F1,
class F2,
class F3,
class F4,
674 struct GetReturn<TArg, F1, F2, F3, F4, F5, void, void, void, void>
676 using type = std::tuple<typename inv_res<F1, TArg>::type,
677 typename inv_res<F2, TArg>::type,
678 typename inv_res<F3, TArg>::type,
679 typename inv_res<F4, TArg>::type,
680 typename inv_res<F5, TArg>::type>;
682 template <
class TArg,
class F1,
class F2,
class F3,
class F4>
683 struct GetReturn<TArg, F1, F2, F3, F4, void, void, void, void, void>
685 using type = std::tuple<typename inv_res<F1, TArg>::type,
686 typename inv_res<F2, TArg>::type,
687 typename inv_res<F3, TArg>::type,
688 typename inv_res<F4, TArg>::type>;
690 template <
class TArg,
class F1,
class F2,
class F3>
691 struct GetReturn<TArg, F1, F2, F3, void, void, void, void, void,
694 using type = std::tuple<typename inv_res<F1, TArg>::type,
695 typename inv_res<F2, TArg>::type,
696 typename inv_res<F3, TArg>::type>;
698 template <
class TArg,
class F1,
class F2>
699 struct GetReturn<TArg, F1, F2, void, void, void, void, void, void,
702 using type = std::tuple<typename inv_res<F1, TArg>::type,
703 typename inv_res<F2, TArg>::type>;
705 template <
class TArg,
class F1>
706 struct GetReturn<TArg, F1, void, void, void, void, void, void, void,
709 using type = std::tuple<typename inv_res<F1, TArg>::type>;
723 template <
class TArg,
class ExecutorAgent,
class... FTypes>
724 ExFuture<ExecutorAgent, typename ::mel::execution::_private::GetReturn<
725 TArg, FTypes...>::type>
727 FTypes... functions )
729 typedef typename ::mel::execution::_private::GetReturn<
730 TArg, FTypes...>::type ResultTuple;
731 static_assert( std::is_default_constructible<ResultTuple>::value,
732 "All types returned by the input ExFutures must be "
733 "DefaultConstructible" );
738 fs = std::make_tuple( std::move( functions )... )](
739 ValueType& input )
mutable
741 if ( input.isValid() )
743 std::exception_ptr* except =
744 new std::exception_ptr( nullptr );
745 ResultTuple* output = new ResultTuple;
748 auto barrier = source.agent.parallel_convert(
749 source, *except, *output,
750 std::move( std::get<FTypes>( fs ) )... );
751 barrier.subscribeCallback(
752 std::function<::mel::core::ECallbackResult(
753 const ::mel::parallelism::BarrierData& )>(
755 except]( const ::mel::parallelism::
756 BarrierData& ) mutable
759 result.setError( *except );
761 result.setValue( std::move( *output ) );
764 return ::mel::core::ECallbackResult::
772 [result, err = std::move(
773 input.error() )]()
mutable noexcept
774 { result.setError( std::move( err ) ); } );
787 template <
class F,
class TArg,
class ExecutorAgent>
788 ExFuture<ExecutorAgent,
789 std::invoke_result_t<F, Executor<ExecutorAgent>, TArg>>
793 typedef std::invoke_result_t<F, Executor<ExecutorAgent>, TArg> TRet;
798 [source, f = std::move( f ), result]( ValueType& input )
mutable
800 if ( input.isValid() )
806 source.agent.template launch<TRet>(
807 [f = std::move( f )](
808 ExFuture<ExecutorAgent, TArg>&
809 arg ) mutable noexcept( std::
810 is_nothrow_invocable<
814 { return f( arg.agent, arg.getValue().value() ); },
821 [result, err = std::move(
822 input.error() )]()
mutable noexcept
823 { result.setError( std::move( err ) ); } );
831 template <
class F,
class ExecutorAgent>
832 ExFuture<ExecutorAgent,
833 std::invoke_result_t<F, Executor<ExecutorAgent>>>
834 getExecutor( ExFuture<ExecutorAgent, void> source, F f )
836 typedef typename ExFuture<ExecutorAgent, void>::ValueType ValueType;
837 typedef std::invoke_result_t<F, Executor<ExecutorAgent>> TRet;
838 ExFuture<ExecutorAgent, TRet> result( source.agent );
839 source.subscribeCallback(
842 [source, f = std::move( f ), result]( ValueType& input )
mutable
844 if ( input.isValid() )
850 source.agent.template launch<TRet>(
851 [f = std::move( f )](
852 ExFuture<ExecutorAgent, void>&
853 arg ) mutable noexcept( std::
854 is_nothrow_invocable<
857 -> TRet { return f( arg.agent ); },
864 [result, err = std::move(
865 input.error() )]()
mutable noexcept
866 { result.setError( std::move( err ) ); } );
876 template <
class TRet>
struct ApplyInmediate
879 ApplyInmediate( T&& a ) : arg( std::forward<T>( a ) )
883 template <
class TArg,
class ExecutorAgent>
884 auto operator()( ExFuture<ExecutorAgent, TArg> fut )
886 return inmediate( fut, std::forward<TRet>( arg ) );
889 template <
class NewExecutionAgent>
struct ApplyTransfer
891 ApplyTransfer( Executor<NewExecutionAgent>&& a )
892 : newAgent( std::move( a ) )
895 ApplyTransfer(
const Executor<NewExecutionAgent>& a )
899 Executor<NewExecutionAgent> newAgent;
900 template <
class TRet,
class OldExecutionAgent>
901 ExFuture<NewExecutionAgent, TRet>
902 operator()( ExFuture<OldExecutionAgent, TRet> fut )
907 template <
class F>
struct ApplyNext
910 ApplyNext( T&& f ) : mFunc( std::forward<T>( f ) )
914 template <
class TArg,
class ExecutorAgent>
915 auto operator()(
const ExFuture<ExecutorAgent, TArg>& inputFut )
917 return next( inputFut, std::forward<F>( mFunc ) );
919 template <
class TArg,
class ExecutorAgent>
920 auto operator()( ExFuture<ExecutorAgent, TArg>&& inputFut )
922 return next( std::move( inputFut ),
923 std::forward<F>( mFunc ) );
926 template <
class I,
class F>
struct ApplyLoop
928 template <
class U,
class T>
929 ApplyLoop( U&& its, T&& f,
int inc )
930 : mGetIts( std::forward<U>( its ) ),
931 mFunc( std::forward<T>( f ) ), increment( inc )
937 template <
class TArg,
class ExecutorAgent>
938 auto operator()( ExFuture<ExecutorAgent, TArg> inputFut )
940 return loop( inputFut, std::forward<I>( mGetIts ),
941 std::forward<F>( mFunc ), increment );
945 template <
class... FTypes>
struct ApplyBulk
947 template <
class... Fs>
948 ApplyBulk( Fs&&... fs )
949 : mFuncs( std::forward<FTypes>( fs )... )
952 std::tuple<FTypes...> mFuncs;
953 template <
class TArg,
class ExecutorAgent>
954 auto operator()( ExFuture<ExecutorAgent, TArg> inputFut )
958 std::forward<FTypes>( std::get<FTypes>( mFuncs ) )... );
961 template <
class F>
struct ApplyError
964 ApplyError( T&& f ) : mFunc( std::forward<T>( f ) )
968 template <
class TArg,
class ExecutorAgent>
969 auto operator()( ExFuture<ExecutorAgent, TArg> inputFut )
971 return catchError( inputFut, std::forward<F>( mFunc ) );
975 template <
class F>
struct ApplyGetExecutor
978 ApplyGetExecutor( T&& f ) : mFunc( std::forward<T>( f ) )
982 template <
class TArg,
class ExecutorAgent>
983 auto operator()( ExFuture<ExecutorAgent, TArg> inputFut )
985 return getExecutor( inputFut, std::forward<F>( mFunc ) );
988 template <
int n,
class TupleType,
class FType>
992 fut.subscribeCallback(
993 [tup, barrier](
typename FType::ValueType& input )
mutable
995 std::get<n>( *tup ) = std::move( input );
1000 template <
int n,
class TupleType,
class FType,
class... FTypes>
1002 FType fut, FTypes... rest )
1004 _on_all<n>( tup, barrier, fut );
1005 _on_all<n + 1>( tup, barrier, rest... );
1007 template <
int n,
class SourceTuple,
class TargetTuple>
1008 std::optional<std::pair<int, std::exception_ptr>>
1009 _moveValue( SourceTuple& st, TargetTuple& tt )
1011 if constexpr ( n != std::tuple_size<SourceTuple>::value )
1013 auto&& val = std::get<n>( st );
1014 if ( val.isValid() )
1016 using ValType = std::remove_reference_t<
1019 if constexpr ( !std::is_same<
typename ValType::Type,
1021 std::get<n>( tt ) = std::move( val.value() );
1022 return _moveValue<n + 1>( st, tt );
1025 return std::make_pair( n, std::move( val.error() ) );
1027 return std::nullopt;
1029 template <
class... FTypes>
struct ApplyParallelConvert
1031 template <
class... Fs>
1032 ApplyParallelConvert( Fs&&... fs )
1033 : mFuncs( std::forward<FTypes>( fs )... )
1036 std::tuple<FTypes...> mFuncs;
1037 template <
class ExecutorAgent,
class TArg>
1038 auto operator()( ExFuture<ExecutorAgent, TArg> inputFut )
1042 std::forward<FTypes>( std::get<FTypes>( mFuncs ) )... );
1049 template <
class TRet>
1050 _private::ApplyInmediate<TRet>
inmediate( TRet&& arg )
1052 return _private::ApplyInmediate<TRet>( std::forward<TRet>( arg ) );
1057 template <
class NewExecutionAgent>
1058 _private::ApplyTransfer<NewExecutionAgent>
1061 return _private::ApplyTransfer<NewExecutionAgent>( newAgent );
1065 template <
class F> _private::ApplyNext<F>
next( F&& f )
1067 return _private::ApplyNext<F>( std::forward<F>( f ) );
1070 template <
class I,
class F>
1071 _private::ApplyLoop<I, F>
loop( I&& getItFunc, F&& functor,
1074 return _private::ApplyLoop<I, F>( std::forward<I>( getItFunc ),
1075 std::forward<F>( functor ),
1079 template <
class... FTypes>
1080 _private::ApplyBulk<FTypes...>
parallel( FTypes&&... functions )
1082 return _private::ApplyBulk<FTypes...>(
1083 std::forward<FTypes>( functions )... );
1088 return _private::ApplyError<F>( std::forward<F>( f ) );
1092 template <
class... FTypes>
1093 _private::ApplyParallelConvert<FTypes...>
1096 return _private::ApplyParallelConvert<FTypes...>(
1097 std::forward<FTypes>( functions )... );
1103 return _private::ApplyGetExecutor<F>( std::forward<F>( f ) );
1110 template <
class ExecutorAgent,
class TRet1,
class U>
1115 template <
class ExecutorAgent,
class TRet1,
class U>
1116 auto operator|( ExFuture<ExecutorAgent, TRet1>&& input, U&& u )
1118 return u( std::move( input ) );
1132 const std::string& msg )
1133 : mElementIdx( idx ),
1134 mSource( source ), std::runtime_error( msg )
1139 : mElementIdx( idx ),
1140 mSource( source ), std::runtime_error( std::move( msg ) )
1143 inline int getWrongElement()
const noexcept {
return mElementIdx; }
1144 std::exception_ptr getCause() noexcept {
return mSource; }
1148 std::exception_ptr mSource;
1160 template <
class ExecutorAgent,
class... FTypes>
1164 typename FTypes::ValueType::Type>::type...>
1166 static_assert( std::is_default_constructible<ReturnType>::value,
1167 "All types returned by the input ExFutures must be "
1168 "DefaultConstructible" );
1171 typedef std::tuple<
typename FTypes::ValueType...> _ttype;
1172 _ttype* tupleRes =
new _ttype;
1174 barrier.subscribeCallback(
1176 const ::mel::parallelism::BarrierData& )>(
1178 tupleRes]( const ::mel::parallelism::BarrierData& )
mutable
1180 ReturnType resultVal;
1181 auto r = ::mel::execution::_private::_moveValue<0>(
1182 *tupleRes, resultVal );
1183 if ( r == std::nullopt )
1185 result.setValue( std::move( resultVal ) );
1189 result.setError( std::make_exception_ptr(
1192 "OnAllException: error in "
1193 "tuple element" ) ) );
1196 return ::mel::core::ECallbackResult::UNSUBSCRIBE;
1198 ::mel::execution::_private::_on_all<0, _ttype>(
int subscribeCallback(F &&f) const
Subscribe callback to be executed when future is ready (valid or error)
Definition: Future.h:681
Extension of mel::core::Future to apply to executors.
Definition: ExFuture.h:21
Executor< ExecutorAgent > agent
execution agent associated with this instance
Definition: ExFuture.h:54
Definition: Executor.h:26
Excepcion thrown by on_all when some of the futures raise error.
Definition: Executor.h:1129
Multithread barrier.
Definition: Barrier.h:43
void set()
Definition: Barrier.h:59
ECallbackResult
Type resturned by callbacks subscribed to CallbackSubscriptors.
Definition: CallbackSubscriptor.h:32
ExFuture< ExecutorAgent, typename std::remove_cv< typename std::remove_reference< TRet >::type >::type > inmediate(ExFuture< ExecutorAgent, TArg > fut, TRet &&arg)
Produces an inmediate value in the context of the given ExFuture executor as a response to input fut ...
Definition: Executor.h:117
ExFuture< ExecutorAgent, std::invoke_result_t< F > > launch(Executor< ExecutorAgent > ex, F &&f)
Launch given functor in given executor.
Definition: Executor.h:65
ExFuture< NewExecutorAgent, TRet > transfer(ExFuture< OldExecutorAgent, TRet > source, Executor< NewExecutorAgent > newAgent)
Transfer given ExFuture to a different executor This way, continuations can be chained but executed i...
Definition: Executor.h:265
ExFuture< ExecutorAgent, TArg > catchError(ExFuture< ExecutorAgent, TArg > source, F &&f)
Capture previous error, if any, and execute the function.
Definition: Executor.h:559
ExFuture< ExecutorAgent, TArg > parallel(ExFuture< ExecutorAgent, TArg > source, FTypes... functions)
Execute given functions in a (possibly, depending on concrete executor) parallel way If an exception ...
Definition: Executor.h:499
ExFuture< ExecutorAgent, TArg > loop(ExFuture< ExecutorAgent, TArg > source, I getIteratorsFunc, F functor, int increment=1)
parallel (possibly, depending on executor capabilities) loop
Definition: Executor.h:290
ExFuture< ExecutorAgent, std::invoke_result_t< F, Executor< ExecutorAgent >, TArg > > getExecutor(ExFuture< ExecutorAgent, TArg > source, F f)
Get the Executor used in the chain of execution.
Definition: Executor.h:790
auto on_all(Executor< ExecutorAgent > ex, FTypes... futs)
return ExFuture which will be executed, in the context of the given executor ex, when all the given E...
Definition: Executor.h:1161
ExFuture< ExecutorAgent, typename ::mel::execution::_private::GetReturn< TArg, FTypes... >::type > parallel_convert(ExFuture< ExecutorAgent, TArg > source, FTypes... functions)
Same as parallel but returning a tuple with the values for each functor.
Definition: Executor.h:726
ExFuture< ExecutorAgent, std::invoke_result_t< F, TArg > > next(ExFuture< ExecutorAgent, TArg > source, F f)
Attach a functor to execute when input fut is complete Given functor will be executed inf the input E...
Definition: Executor.h:166
ExFuture< ExecutorAgent, void > start(Executor< ExecutorAgent > ex)
Start a chain of execution in given executor.
Definition: Executor.h:104
auto operator|(const ExFuture< ExecutorAgent, TRet1 > &input, U &&u)
overload operator | for chaining
Definition: Executor.h:1111
Definition: Callback_Impl.h:11
Default traits for any executor.
Definition: Executor.h:46
Definition: CommonDefs.h:21