11 #ifndef ROOT_TSequentialExecutor
12 #define ROOT_TSequentialExecutor
14 #include "RConfigure.h"
22 class TSequentialExecutor:
public TExecutor<TSequentialExecutor> {
24 explicit TSequentialExecutor(){};
26 TSequentialExecutor(TSequentialExecutor &) =
delete;
27 TSequentialExecutor &operator=(TSequentialExecutor &) =
delete;
30 void Foreach(F func,
unsigned nTimes);
31 template<
class F,
class INTEGER>
32 void Foreach(F func, ROOT::TSeq<INTEGER> args);
34 template<
class F,
class T>
35 void Foreach(F func, std::initializer_list<T> args);
37 template<
class F,
class T>
38 void Foreach(F func, std::vector<T> &args);
40 using TExecutor<TSequentialExecutor>::Map;
41 template<
class F,
class Cond = noReferenceCond<F>>
42 auto Map(F func,
unsigned nTimes) -> std::vector<typename std::result_of<F()>::type>;
43 template<
class F,
class INTEGER,
class Cond = noReferenceCond<F, INTEGER>>
44 auto Map(F func, ROOT::TSeq<INTEGER> args) -> std::vector<typename std::result_of<F(INTEGER)>::type>;
45 template<
class F,
class T,
class Cond = noReferenceCond<F, T>>
46 auto Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type>;
52 using TExecutor<TSequentialExecutor>::MapReduce;
53 template<
class F,
class R,
class Cond = noReferenceCond<F>>
54 auto MapReduce(F func,
unsigned nTimes, R redfunc) ->
typename std::result_of<F()>::type;
55 template<
class F,
class T,
class R,
class Cond = noReferenceCond<F, T>>
56 auto MapReduce(F func, std::vector<T> &args, R redfunc) ->
typename std::result_of<F(T)>::type;
58 using TExecutor<TSequentialExecutor>::Reduce;
59 template<
class T,
class R>
auto Reduce(
const std::vector<T> &objs, R redfunc) -> decltype(redfunc(objs));
69 void TSequentialExecutor::Foreach(F func,
unsigned nTimes) {
70 for (
auto i = 0U; i < nTimes; ++i) func();
76 template<
class F,
class INTEGER>
77 void TSequentialExecutor::Foreach(F func, ROOT::TSeq<INTEGER> args) {
78 for(
auto i : args) func(i);
85 template<
class F,
class T>
86 void TSequentialExecutor::Foreach(F func, std::initializer_list<T> args) {
87 std::vector<T> vargs(std::move(args));
95 template<
class F,
class T>
96 void TSequentialExecutor::Foreach(F func, std::vector<T> &args) {
97 unsigned int nToProcess = args.size();
98 for(
auto i: ROOT::TSeqI(nToProcess)) func(args[i]);
106 template<
class F,
class Cond>
107 auto TSequentialExecutor::Map(F func,
unsigned nTimes) -> std::vector<typename std::result_of<F()>::type> {
108 using retType = decltype(func());
109 std::vector<retType> reslist(nTimes);
110 for(
auto i: ROOT::TSeqI(nTimes)) reslist[i] = func();
118 template<
class F,
class INTEGER,
class Cond>
119 auto TSequentialExecutor::Map(F func, ROOT::TSeq<INTEGER> args) -> std::vector<typename std::result_of<F(INTEGER)>::type> {
120 using retType = decltype(func(*args.begin()));
121 std::vector<retType> reslist(args.size());
122 for(
auto i: args) reslist[i] = func(i);
132 template<
class F,
class T,
class Cond>
133 auto TSequentialExecutor::Map(F func, std::vector<T> &args) -> std::vector<typename std::result_of<F(T)>::type> {
135 using retType = decltype(func(args.front()));
136 unsigned int nToProcess = args.size();
137 std::vector<retType> reslist(nToProcess);
138 for(
auto i: ROOT::TSeqI(nToProcess)) reslist[i] = func(args[i]);
142 template<
class F,
class R,
class Cond>
143 auto TSequentialExecutor::MapReduce(F func,
unsigned nTimes, R redfunc) ->
typename std::result_of<F()>::type {
144 return Reduce(Map(func, nTimes), redfunc);
147 template<
class F,
class T,
class R,
class Cond>
148 auto TSequentialExecutor::MapReduce(F func, std::vector<T> &args, R redfunc) ->
typename std::result_of<F(T)>::type {
149 return Reduce(Map(func, args), redfunc);
155 template<
class T,
class R>
156 auto TSequentialExecutor::Reduce(
const std::vector<T> &objs, R redfunc) -> decltype(redfunc(objs))
159 static_assert(std::is_same<decltype(redfunc(objs)), T>::value,
"redfunc does not have the correct signature");
160 return redfunc(objs);