File indexing completed on 2025-01-30 10:22:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef ROOT_TSequentialExecutor
0012 #define ROOT_TSequentialExecutor
0013
0014 #include "ROOT/EExecutionPolicy.hxx"
0015 #include "ROOT/TExecutorCRTP.hxx"
0016 #include "ROOT/TSeq.hxx"
0017
0018 #include <initializer_list>
0019 #include <numeric> //std::accumulate
0020 #include <utility> //std::move
0021 #include <vector>
0022
0023 namespace ROOT {
0024
0025 class TSequentialExecutor: public TExecutorCRTP<TSequentialExecutor> {
0026 friend TExecutorCRTP;
0027
0028 public:
0029
0030 TSequentialExecutor() = default;
0031 TSequentialExecutor(const TSequentialExecutor &) = delete;
0032 TSequentialExecutor &operator=(const TSequentialExecutor &) = delete;
0033
0034
0035
0036 template<class F>
0037 void Foreach(F func, unsigned nTimes);
0038 template<class F, class INTEGER>
0039 void Foreach(F func, ROOT::TSeq<INTEGER> args);
0040 template<class F, class T>
0041 void Foreach(F func, std::initializer_list<T> args);
0042 template<class F, class T>
0043 void Foreach(F func, std::vector<T> &args);
0044 template<class F, class T>
0045 void Foreach(F func, const std::vector<T> &args);
0046
0047
0048
0049 using TExecutorCRTP<TSequentialExecutor>::Map;
0050
0051
0052
0053
0054
0055 using TExecutorCRTP<TSequentialExecutor>::MapReduce;
0056
0057
0058
0059 using TExecutorCRTP<TSequentialExecutor>::Reduce;
0060
0061
0062
0063
0064
0065 unsigned GetPoolSize() const { return 1u; }
0066
0067 private:
0068
0069
0070 template<class F, class Cond = validMapReturnCond<F>>
0071 auto MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>>;
0072 template<class F, class INTEGER, class Cond = validMapReturnCond<F, INTEGER>>
0073 auto MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>>;
0074 template<class F, class T, class Cond = validMapReturnCond<F, T>>
0075 auto MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
0076 template<class F, class T, class Cond = validMapReturnCond<F, T>>
0077 auto MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>>;
0078 };
0079
0080
0081
0082
0083
0084
0085
0086
0087 template<class F>
0088 void TSequentialExecutor::Foreach(F func, unsigned nTimes) {
0089 for (auto i = 0U; i < nTimes; ++i) func();
0090 }
0091
0092
0093
0094
0095
0096
0097 template<class F, class INTEGER>
0098 void TSequentialExecutor::Foreach(F func, ROOT::TSeq<INTEGER> args) {
0099 for(auto i : args) func(i);
0100 }
0101
0102
0103
0104
0105
0106
0107 template<class F, class T>
0108 void TSequentialExecutor::Foreach(F func, std::initializer_list<T> args) {
0109 std::vector<T> vargs(std::move(args));
0110 Foreach(func, vargs);
0111 }
0112
0113
0114
0115
0116
0117
0118 template<class F, class T>
0119 void TSequentialExecutor::Foreach(F func, std::vector<T> &args) {
0120 for(auto &&arg: args) {
0121 func(arg);
0122 }
0123 }
0124
0125
0126
0127
0128
0129
0130 template<class F, class T>
0131 void TSequentialExecutor::Foreach(F func, const std::vector<T> &args) {
0132 for(auto &&arg: args) {
0133 func(arg);
0134 }
0135 }
0136
0137
0138
0139
0140
0141
0142 template<class F, class Cond>
0143 auto TSequentialExecutor::MapImpl(F func, unsigned nTimes) -> std::vector<InvokeResult_t<F>> {
0144 using retType = decltype(func());
0145 std::vector<retType> reslist;
0146 reslist.reserve(nTimes);
0147 while(reslist.size() < nTimes) {
0148 reslist.emplace_back(func());
0149 }
0150 return reslist;
0151 }
0152
0153
0154
0155
0156
0157
0158 template<class F, class INTEGER, class Cond>
0159 auto TSequentialExecutor::MapImpl(F func, ROOT::TSeq<INTEGER> args) -> std::vector<InvokeResult_t<F, INTEGER>> {
0160 using retType = decltype(func(*args.begin()));
0161 std::vector<retType> reslist;
0162 reslist.reserve(args.size());
0163 for(auto i: args)
0164 reslist.emplace_back(func(i));
0165 return reslist;
0166 }
0167
0168
0169
0170
0171
0172
0173 template<class F, class T, class Cond>
0174 auto TSequentialExecutor::MapImpl(F func, std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>> {
0175
0176 using retType = decltype(func(args.front()));
0177 std::vector<retType> reslist;
0178 reslist.reserve(args.size());
0179 for(auto &&arg: args) {
0180 reslist.emplace_back(func(arg));
0181 }
0182 return reslist;
0183 }
0184
0185
0186
0187
0188
0189
0190 template<class F, class T, class Cond>
0191 auto TSequentialExecutor::MapImpl(F func, const std::vector<T> &args) -> std::vector<InvokeResult_t<F, T>> {
0192
0193 using retType = decltype(func(args.front()));
0194 std::vector<retType> reslist;
0195 reslist.reserve(args.size());
0196 for(auto &&arg: args) {
0197 reslist.emplace_back(func(arg));
0198 }
0199 return reslist;
0200 }
0201
0202 }
0203 #endif