File indexing completed on 2023-10-25 09:53:58
0001 #ifndef NPSTAT_SIMPLEFUNCTORS_HH_
0002 #define NPSTAT_SIMPLEFUNCTORS_HH_
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 namespace npstat {
0016
0017 template <typename Result>
0018 struct Functor0 {
0019 typedef Result result_type;
0020
0021 inline virtual ~Functor0() {}
0022 virtual Result operator()() const = 0;
0023 };
0024
0025
0026 template <typename Result, typename Arg1>
0027 struct Functor1 {
0028 typedef Result result_type;
0029 typedef Arg1 first_argument_type;
0030
0031 inline virtual ~Functor1() {}
0032 virtual Result operator()(const Arg1&) const = 0;
0033 };
0034
0035
0036 template <typename Result, typename Arg1, typename Arg2>
0037 struct Functor2 {
0038 typedef Result result_type;
0039 typedef Arg1 first_argument_type;
0040 typedef Arg2 second_argument_type;
0041
0042 inline virtual ~Functor2() {}
0043 virtual Result operator()(const Arg1&, const Arg2&) const = 0;
0044 };
0045
0046
0047 template <typename Result, typename Arg1, typename Arg2, typename Arg3>
0048 struct Functor3 {
0049 typedef Result result_type;
0050 typedef Arg1 first_argument_type;
0051 typedef Arg2 second_argument_type;
0052 typedef Arg3 third_argument_type;
0053
0054 inline virtual ~Functor3() {}
0055 virtual Result operator()(const Arg1&, const Arg2&, const Arg3&) const = 0;
0056 };
0057
0058
0059 template <typename Result>
0060 struct Same : public Functor1<Result, Result> {
0061 inline Result operator()(const Result& a) const override { return a; }
0062 };
0063
0064
0065 template <typename Result>
0066 struct SameRef : public Functor1<const Result&, Result> {
0067 inline const Result& operator()(const Result& a) const { return a; }
0068 };
0069
0070
0071
0072
0073
0074 template <typename Result>
0075 struct DefaultConstructor0 : public Functor0<Result> {
0076 inline Result operator()() const { return Result(); }
0077 };
0078
0079
0080
0081
0082
0083 template <typename Result, typename Arg1>
0084 struct DefaultConstructor1 : public Functor1<Result, Arg1> {
0085 inline Result operator()(const Arg1&) const { return Result(); }
0086 };
0087
0088
0089
0090
0091
0092 template <typename Result, typename Arg1, typename Arg2>
0093 struct DefaultConstructor2 : public Functor2<Result, Arg1, Arg2> {
0094 inline Result operator()(const Arg1&, const Arg2&) const { return Result(); }
0095 };
0096
0097
0098
0099
0100
0101 template <typename Result, typename Arg1, typename Arg2, typename Arg3>
0102 struct DefaultConstructor3 : public Functor3<Result, Arg1, Arg2, Arg3> {
0103 inline Result operator()(const Arg1&, const Arg2&, const Arg3&) const { return Result(); }
0104 };
0105
0106
0107
0108
0109
0110 template <typename Result, typename Arg1, typename CastType>
0111 struct CastingCopyConstructor : public Functor1<Result, Arg1> {
0112 inline Result operator()(const Arg1& a) const { return Result(static_cast<CastType>(a)); }
0113 };
0114
0115
0116
0117
0118
0119 template <typename Result>
0120 struct FcnFunctor0 : public Functor0<Result> {
0121 inline explicit FcnFunctor0(Result (*fcn)()) : fcn_(fcn) {}
0122
0123 inline Result operator()() const { return fcn_(); }
0124
0125 FcnFunctor0() = delete;
0126
0127 private:
0128 Result (*fcn_)();
0129 };
0130
0131
0132
0133
0134
0135 template <typename Result, typename Arg1>
0136 struct FcnFunctor1 : public Functor1<Result, Arg1> {
0137 inline explicit FcnFunctor1(Result (*fcn)(Arg1)) : fcn_(fcn) {}
0138
0139 inline Result operator()(const Arg1& a) const { return fcn_(a); }
0140
0141 FcnFunctor1() = delete;
0142
0143 private:
0144 Result (*fcn_)(Arg1);
0145 };
0146
0147
0148
0149
0150
0151 template <typename Result, typename Arg1, typename Arg2>
0152 struct FcnFunctor2 : public Functor2<Result, Arg1, Arg2> {
0153 inline explicit FcnFunctor2(Result (*fcn)(Arg1, Arg2)) : fcn_(fcn) {}
0154
0155 inline Result operator()(const Arg1& x, const Arg2& y) const { return fcn_(x, y); }
0156
0157 FcnFunctor2() = delete;
0158
0159 private:
0160 Result (*fcn_)(Arg1, Arg2);
0161 };
0162
0163
0164
0165
0166
0167 template <typename Result, typename Arg1, typename Arg2, typename Arg3>
0168 struct FcnFunctor3 : public Functor3<Result, Arg1, Arg2, Arg3> {
0169 inline explicit FcnFunctor3(Result (*fcn)(Arg1, Arg2, Arg3)) : fcn_(fcn) {}
0170
0171 inline Result operator()(const Arg1& x, const Arg2& y, const Arg3& z) const { return fcn_(x, y, z); }
0172
0173 FcnFunctor3() = delete;
0174
0175 private:
0176 Result (*fcn_)(Arg1, Arg2, Arg3);
0177 };
0178
0179
0180
0181
0182
0183 template <class Container, class Result = typename Container::value_type>
0184 struct Element1D : public Functor1<Result, Container> {
0185 inline explicit Element1D(const unsigned long index) : idx(index) {}
0186
0187 inline Result operator()(const Container& c) const { return c[idx]; }
0188
0189 Element1D() = delete;
0190
0191 private:
0192 unsigned long idx;
0193 };
0194
0195
0196
0197
0198
0199 template <class Container, class Result = typename Container::value_type>
0200 struct Element1DAt : public Functor1<Result, Container> {
0201 inline explicit Element1DAt(const unsigned long index) : idx(index) {}
0202
0203 inline Result operator()(const Container& c) const { return c.at(idx); }
0204
0205 Element1DAt() = delete;
0206
0207 private:
0208 unsigned long idx;
0209 };
0210
0211
0212
0213
0214
0215 template <typename T1, typename T2>
0216 struct assign_left {
0217 inline T1& operator()(T1& left, const T2& right) const { return left = right; }
0218 };
0219
0220
0221
0222
0223
0224 template <typename T1, typename T2>
0225 struct assign_right {
0226 inline T2& operator()(const T1& left, T2& right) const { return right = left; }
0227 };
0228
0229
0230 template <typename T1, typename T2>
0231 struct pluseq_left {
0232 inline T1& operator()(T1& left, const T2& right) const { return left += right; }
0233 };
0234
0235
0236 template <typename T1, typename T2>
0237 struct pluseq_right {
0238 inline T2& operator()(const T1& left, T2& right) const { return right += left; }
0239 };
0240
0241
0242
0243
0244
0245 template <typename T1, typename T2>
0246 struct addmul_left {
0247 inline explicit addmul_left(const double weight) : w_(weight) {}
0248
0249 inline T1& operator()(T1& left, const T2& right) const { return left += w_ * right; }
0250
0251 addmul_left() = delete;
0252
0253 private:
0254 double w_;
0255 };
0256
0257
0258
0259
0260
0261 template <typename T1, typename T2>
0262 struct addmul_right {
0263 inline explicit addmul_right(const double weight) : w_(weight) {}
0264
0265 inline T1& operator()(T1& left, const T2& right) const { return right += w_ * left; }
0266
0267 addmul_right() = delete;
0268
0269 private:
0270 double w_;
0271 };
0272
0273
0274 template <typename T1, typename T2>
0275 struct minuseq_left {
0276 inline T1& operator()(T1& left, const T2& right) const { return left -= right; }
0277 };
0278
0279
0280 template <typename T1, typename T2>
0281 struct minuseq_right {
0282 inline T2& operator()(const T1& left, T2& right) const { return right -= left; }
0283 };
0284
0285
0286 template <typename T1, typename T2>
0287 struct multeq_left {
0288 inline T1& operator()(T1& left, const T2& right) const { return left *= right; }
0289 };
0290
0291
0292 template <typename T1, typename T2>
0293 struct multeq_right {
0294 inline T2& operator()(const T1& left, T2& right) const { return right *= left; }
0295 };
0296
0297
0298 template <typename T1, typename T2>
0299 struct diveq_left {
0300 inline T1& operator()(T1& left, const T2& right) const { return left /= right; }
0301 };
0302
0303
0304 template <typename T1, typename T2>
0305 struct diveq_right {
0306 inline T2& operator()(const T1& left, T2& right) const { return right /= left; }
0307 };
0308
0309
0310 template <typename T1, typename T2>
0311 struct diveq_left_0by0isC {
0312 inline diveq_left_0by0isC() : C(T1()), leftZero(T1()), rightZero(T2()) {}
0313 inline explicit diveq_left_0by0isC(const T1& value) : C(value), leftZero(T1()), rightZero(T2()) {}
0314
0315 inline T1& operator()(T1& left, const T2& right) const {
0316 if (right == rightZero)
0317 if (left == leftZero) {
0318 left = C;
0319 return left;
0320 }
0321 return left /= right;
0322 }
0323
0324 private:
0325 T1 C;
0326 T1 leftZero;
0327 T2 rightZero;
0328 };
0329
0330
0331 template <typename T1, typename T2>
0332 struct diveq_right_0by0isC {
0333 inline diveq_right_0by0isC() : C(T2()), leftZero(T1()), rightZero(T2()) {}
0334 inline explicit diveq_right_0by0isC(const T2& value) : C(value), leftZero(T1()), rightZero(T2()) {}
0335
0336 inline T2& operator()(const T1& left, T2& right) const {
0337 if (left == leftZero)
0338 if (right == rightZero) {
0339 right = C;
0340 return right;
0341 }
0342 return right /= left;
0343 }
0344
0345 private:
0346 T2 C;
0347 T1 leftZero;
0348 T2 rightZero;
0349 };
0350
0351
0352 template <typename T1, typename T2, typename T3 = T1>
0353 struct scast_assign_left {
0354 inline T1& operator()(T1& left, const T2& right) const { return left = static_cast<T3>(right); }
0355 };
0356
0357
0358 template <typename T1, typename T2, typename T3 = T2>
0359 struct scast_assign_right {
0360 inline T2& operator()(const T1& left, T2& right) const { return right = static_cast<T3>(left); }
0361 };
0362
0363
0364 template <typename T1, typename T2, typename T3 = T1>
0365 struct scast_pluseq_left {
0366 inline T1& operator()(T1& left, const T2& right) const { return left += static_cast<T3>(right); }
0367 };
0368
0369
0370 template <typename T1, typename T2, typename T3 = T2>
0371 struct scast_pluseq_right {
0372 inline T2& operator()(const T1& left, T2& right) const { return right += static_cast<T3>(left); }
0373 };
0374
0375
0376 template <typename T1, typename T2, typename T3 = T1>
0377 struct scast_minuseq_left {
0378 inline T1& operator()(T1& left, const T2& right) const { return left -= static_cast<T3>(right); }
0379 };
0380
0381
0382 template <typename T1, typename T2, typename T3 = T2>
0383 struct scast_minuseq_right {
0384 inline T2& operator()(const T1& left, T2& right) const { return right -= static_cast<T3>(left); }
0385 };
0386 }
0387
0388 #endif