RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
computeChain.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_CHAIN_HH
22 #define RFFGEN_UTIL_COMPUTE_CHAIN_HH
23 
24 #include <utility>
25 #include "consistencyCheck.hh"
26 #include "indexedType.hh"
27 
28 namespace RFFGen
29 {
33  namespace Detail
34  {
35  template <class F, class IndexedX, bool allPresent,
36  class X = typename IndexedX::type,
37  int id = IndexedX::index>
38  struct ComputeChainD1Impl
39  {
40  static constexpr bool present = false;
41  ComputeChainD1Impl(const F&, const X&) {}
42  };
43 
44  template <class F, class IndexedX, class IndexedY, bool allPresent,
45  class X = typename IndexedX::type,
46  class Y = typename IndexedY::type,
47  int idx = IndexedX::index,
48  int idy = IndexedY::index>
49  struct ComputeChainD2Impl
50  {
51  static constexpr bool present = false;
52  ComputeChainD2Impl(const F&, const X&, const Y&) {}
53  };
54 
55  template <class F, class IndexedX, class IndexedY, class IndexedZ, bool allPresent,
56  class X = typename IndexedX::type,
57  class Y = typename IndexedY::type,
58  class Z = typename IndexedZ::type,
59  int idx = IndexedX::index,
60  int idy = IndexedY::index,
61  int idz = IndexedZ::index>
62  struct ComputeChainD3Impl
63  {
64  static constexpr bool present = false;
65  ComputeChainD3Impl(const F&, const X&, const Y&, const Z&) {}
66  };
67 
68 
69  template <class F, class IndexedX, class X, int id>
70  struct ComputeChainD1Impl<F,IndexedX,true,X,id>
71  {
72  static constexpr bool present = true;
73 
74  ComputeChainD1Impl(const F& f, const X& x) : value(f.template d1<id>(x()))
75  {}
76 
77  auto operator()() const
78  {
79  return value;
80  }
81 
82  decltype(std::declval<F>().template d1<id>(std::declval<X>()())) value;
83  };
84 
85  template <class F, class IndexedX, class IndexedY, class X, class Y, int idx, int idy>
86  struct ComputeChainD2Impl<F,IndexedX,IndexedY,true,X,Y,idx,idy>
87  {
88  static constexpr bool present = true;
89 
90  ComputeChainD2Impl(const F& f, const X& x, const Y& y) : value(f.template d2<idx,idy>(x(),y()))
91  {}
92 
93  auto operator()() const
94  {
95  return value;
96  }
97 
98  decltype( std::declval<F>().template d2<idx,idy>( std::declval<X>()() , std::declval<Y>()() ) ) value;
99  };
100 
101  template <class F, class IndexedX, class IndexedY, class IndexedZ, class X, class Y, class Z, int idx, int idy, int idz>
102  struct ComputeChainD3Impl<F,IndexedX,IndexedY,IndexedZ,true,X,Y,Z,idx,idy,idz>
103  {
104  static constexpr bool present = true;
105 
106  ComputeChainD3Impl(const F& f, const X& x, const Y& y, const Z& z) : value(f.template d3<idx,idy,idz>(x(),y(),z()))
107  {}
108 
109  auto operator()() const
110  {
111  return value;
112  }
113 
114  decltype( std::declval<F>().template d3<idx,idy,idz>( std::declval<X>()() , std::declval<Y>()() , std::declval<Z>()() ) ) value;
115  };
116  }
117 
118  template < class F , class X , class IndexedArg ,
119  class IndexedX = IndexedType<X,IndexedArg::index> >
120  struct ComputeChainD1 : public Detail::ComputeChainD1Impl<F,IndexedX,HasD1MemberFunction<F,IndexedArg>::value && X::present>
121  {
122  ComputeChainD1(F const& f, X const& x)
123  : Detail::ComputeChainD1Impl<F,IndexedX,HasD1MemberFunction<F,IndexedArg>::value && X::present> (f,x)
124  {}
125  };
126 
127  template < class F , class X , class Y , class IndexedArgX , class IndexedArgY ,
128  class IndexedX = IndexedType<X,IndexedArgX::index> ,
129  class IndexedY = IndexedType<Y,IndexedArgY::index> >
130  struct ComputeChainD2
131  : public Detail::ComputeChainD2Impl<F,IndexedX,IndexedY,HasD2MemberFunction<F,IndexedArgX,IndexedArgY>::value && X::present && Y::present>
132  {
133  ComputeChainD2(const F& f, const X& x, const Y& y)
134  : Detail::ComputeChainD2Impl<F,IndexedX,IndexedY,HasD2MemberFunction< F , IndexedArgX , IndexedArgY >::value && X::present && Y::present >
135  (f,x,y)
136  {}
137  };
138 
139  template < class F , class X , class Y , class Z , class IndexedArgX , class IndexedArgY , class IndexedArgZ ,
140  class IndexedX = IndexedType<X,IndexedArgX::index> ,
141  class IndexedY = IndexedType<Y,IndexedArgY::index> ,
142  class IndexedZ = IndexedType<Z,IndexedArgZ::index> >
143  struct ComputeChainD3
144  : public Detail::ComputeChainD3Impl<F,IndexedX,IndexedY,IndexedZ,HasD3MemberFunction<F,IndexedArgX,IndexedArgY,IndexedArgZ>::value && X::present && Y::present && Z::present>
145  {
146  ComputeChainD3(const F& f, const X& x, const Y& y, const Z& z)
147  : Detail::ComputeChainD3Impl<F,IndexedX,IndexedY,IndexedZ,HasD3MemberFunction<F,IndexedArgX,IndexedArgY,IndexedArgZ>::value && X::present && Y::present && Z::present> (f,x,y,z)
148  {}
149  };
153 }
154 
155 #endif // RFFGEN_UTIL_COMPUTE_CHAIN_HH