RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
computeSum.hh
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the C++-library RFFGen. */
4 /* Copyright 2015 Lars Lubkoll */
5 /* */
6 /* RFFGen is free software: you can redistribute it and/or modify */
7 /* it under the terms of the GNU General Public License as published by */
8 /* the Free Software Foundation, either version 3 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* RFFGen is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU General Public License */
17 /* along with RFFGen. If not, see <http://www.gnu.org/licenses/>. */
18 /* */
19 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20 
21 #ifndef RFFGEN_UTIL_COMPUTE_SUM_HH
22 #define RFFGEN_UTIL_COMPUTE_SUM_HH
23 
24 #include <utility>
25 
26 namespace RFFGen
27 {
31  namespace Detail
32  {
33  template <class X, class Y, bool Xpresent, bool Ypresent>
34  struct ComputeSumImpl
35  {
36  static constexpr bool present = false;
37  ComputeSumImpl(const X&, const Y&) {}
38  };
39 
40  template <class X, class Y>
41  struct ComputeSumImpl<X,Y,true,true>
42  {
43  static constexpr bool present = true;
44 
45  ComputeSumImpl(const X& x, const Y& y) : value(x() + y())
46  {}
47 
48  auto operator()() const
49  {
50  return value;
51  }
52 
53  decltype(std::declval<X>()() + std::declval<Y>()()) value;
54  };
55 
56  template <class X, class Y>
57  struct ComputeSumImpl<X,Y,true,false>
58  {
59  static constexpr bool present = true;
60 
61  ComputeSumImpl(const X& x, const Y&) : value(x())
62  {}
63 
64  auto operator()() const
65  {
66  return value;
67  }
68 
69  decltype(std::declval<X>()()) value;
70  };
71 
72  template <class X, class Y>
73  struct ComputeSumImpl<X,Y,false,true>
74  {
75  static constexpr bool present = true;
76 
77  ComputeSumImpl(const X&, const Y& y) : value(y())
78  {}
79 
80  auto operator()() const
81  {
82  return value;
83  }
84 
85  decltype(std::declval<Y>()()) value;
86  };
87  }
88 
89  template <class...> struct ComputeSum;
90 
91  template <class X, class Y>
92  struct ComputeSum<X,Y> : public Detail::ComputeSumImpl<X,Y,X::present,Y::present>
93  {
94  ComputeSum(const X& x, const Y& y)
95  : Detail::ComputeSumImpl<X,Y,X::present,Y::present>(x,y)
96  {}
97 
98  template <class F, class G, class... Args>
99  ComputeSum(F const& f, G const& g, const Args&... args) : ComputeSum( X(f,args...), Y(g,args...) )
100  {}
101  };
102 
103  template <class X, class... Y>
104  struct ComputeSum<X,Y...> : public ComputeSum<X,ComputeSum<Y...> >
105  {
106  ComputeSum(const X& x, const Y&... y) : ComputeSum<X,ComputeSum<Y...> >(x,ComputeSum<Y...>(y...))
107  {}
108  };
112 }
113 
114 #endif // RFFGEN_UTIL_COMPUTE_SUM_HH