RFFGen
 All Classes Namespaces Files Functions Typedefs Enumerations Groups
variable.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_VARIABLE_HH
22 #define RFFGEN_VARIABLE_HH
23 
24 #include <limits>
25 #include <type_traits>
26 
27 #include "Util/base.hh"
28 #include "Util/chainer.hh"
29 
30 namespace RFFGen
31 {
35  template <class,int> struct Variable;
36 
37  namespace VariableDetail
38  {
39  template <bool>
40  struct Update
41  {
42  template <class T, class Arg>
43  void operator()(T& t, const Arg& x)
44  {
45  static_assert(std::is_same<T,Arg>::value,"Updating variable with incompatible argument. Please check your input for the update-function.");
46  t = x;
47  }
48  };
49 
50  template <>
51  struct Update<false>
52  {
53  template <class T, class Arg>
54  void operator()(const T&, const Arg&) {}
55  };
56 
57 
59  template <class> struct IsVariable : std::false_type {};
60 
61  template <class T, int n>
62  struct IsVariable< Variable<T,n> > : std::true_type {};
63 
64 
66  template <class Type> struct HasVariable : IsVariable<Type> {};
67 
68  template <template <class,class> class G, class F, class CheckF>
69  struct HasVariable< G<F,CheckF> > : std::integral_constant< bool, HasVariable<F>::value > {};
70 
71  template <template <class,class,class,class> class H, class F, class G, class CheckF, class CheckG>
72  struct HasVariable< H<G,F,CheckF,CheckG> > : std::integral_constant< bool , HasVariable<F>::value || HasVariable<G>::value > {};
73 
74 
75  template <class, int id> struct HasVariableId : std::false_type {};
76 
77  template <class Type, int id0, int id>
78  struct HasVariableId< Variable<Type,id0> , id > : std::integral_constant<bool,id==id0> {};
79 
80  template <template <class,class> class G, class F, int id, class CheckF>
81  struct HasVariableId< G<F,CheckF> , id > : std::integral_constant< bool, HasVariableId<F,id>::value > {};
82 
83  template <template <class,class,class,class> class H, class F, class G, int id, class CheckF, class CheckG>
84  struct HasVariableId< H<F,G,CheckF,CheckG> , id > : std::integral_constant< bool , HasVariableId<F,id>::value || HasVariableId<G,id>::value > {};
85 
86 
87  template <class F, class G>
88  struct ComputeMax
89  {
90  static constexpr int value = F::value > G::value ? F::value : G::value;
91  };
92 
93  template <class F, class G>
94  struct ComputeMin
95  {
96  static constexpr int value = F::value < G::value ? F::value : G::value;
97  };
98 
99  template <class Type>
100  struct MaxVariableId
101  : std::integral_constant< int , std::numeric_limits<int>::lowest()>
102  {};
103 
104  template <template <class,class> class G, class F, class CheckF>
105  struct MaxVariableId< G<F,CheckF> >
106  : std::integral_constant< int , MaxVariableId<F>::value >
107  {};
108 
109  template <template <class,class,class,class> class H, class F, class G, class CheckF, class CheckG>
110  struct MaxVariableId< H<F,G,CheckF,CheckG> >
111  : std::integral_constant< int , ComputeMax< MaxVariableId<F> , MaxVariableId<G> >::value >
112  {};
113 
114  template <class T, int id>
115  struct MaxVariableId< Variable<T,id> > : std::integral_constant< int , id >
116  {};
117 
118 
119  template <class Type>
120  struct MinVariableId
121  : std::integral_constant< int , std::numeric_limits<int>::max()>
122  {};
123 
124  template <template <class,class> class G, class F, class CheckF>
125  struct MinVariableId< G<F,CheckF> >
126  : std::integral_constant< int , MinVariableId<F>::value >
127  {};
128 
129  template <template <class,class,class,class> class H, class F, class G, class CheckF, class CheckG>
130  struct MinVariableId< H<F,G,CheckF,CheckG> >
131  : std::integral_constant< int , ComputeMax< MinVariableId<F> , MinVariableId<G> >::value >
132  {};
133 
134  template <class T, int id>
135  struct MinVariableId< Variable<T,id> > : std::integral_constant< int , id >
136  {};
137 
138 
139 
140  template <class F, int id> struct VariableType { using type = void; };
141 
142  template <template <class,class> class G, class F, class CheckF, int id>
143  struct VariableType< G<F,CheckF> , id >
144  {
145  using type = typename VariableType<F,id>::type;
146  };
147 
148  template <template <class,class,class,class> class H, class F, class G, class CheckF, class CheckG, int id>
149  struct VariableType< H<F,G,CheckF,CheckG> , id >
150  {
151  using type = std::conditional_t< std::is_same<void,typename VariableType<F,id>::type>::value ,
152  typename VariableType<G,id>::type, typename VariableType<F,id>::type>;
153  };
154 
155  template <class T, int id>
156  struct VariableType< Variable<T,id>, id > { using type = T; };
157  }
165  template <class T, int id>
166  struct Variable : Base , Chainer< Variable<T,id> >
167  {
168  Variable() = default;
169 
171  explicit Variable(const T& t_) : t(t_) {}
172 
174  template <int index, class Arg>
175  void updateVariable(const Arg& t_)
176  {
177  VariableDetail::Update<index==id>()(t,t_);
178  }
179 
181  const T& d0() const noexcept
182  {
183  return t;
184  }
185 
191  template < int index , class = std::enable_if_t< id == index > >
192  const T& d1(const T& dt) const noexcept
193  {
194  return dt;
195  }
196 
197  private:
198  T t;
199  };
200 
202  template <int id, class T>
204  {
205  return Variable<T,id>(t);
206  }
207 
211  template <class F, int id>
212  using Variable_t = typename VariableDetail::VariableType<F,id>::type;
213 
214  namespace Checks
215  {
220  template <class T>
221  constexpr bool isVariable() { return VariableDetail::IsVariable<T>::value; }
222 
227  template <class T>
228  constexpr bool hasVariable() { return VariableDetail::HasVariable<T>::value; }
229 
234  template <class T, int id>
235  constexpr bool hasVariableId() { return VariableDetail::HasVariableId<T,id>::value; }
236 
241  template <class Type>
242  constexpr bool hasMoreThanOneVariable()
243  {
244  return VariableDetail::MinVariableId<Type>::value < VariableDetail::MaxVariableId<Type>::value;
245  }
246 
251  template <class F, class Type, int id>
252  constexpr bool checkArgument()
253  {
254  return std::is_same<typename VariableDetail::VariableType<F,id>::type, Type>::value;
255  }
256  }
257 }
258 
259 #endif // RFFGEN_VARIABLE_HH
void updateVariable(const Arg &t_)
Update variable.
Definition: variable.hh:175
Independent variable. Can be uniquely identified by its id.
Definition: variable.hh:166
const T & d1(const T &dt) const noexcept
First directional derivative.
Definition: variable.hh:192
Base class for functions satisfying FunctionConcept. Required for enabling the operators in generate...
Definition: base.hh:27
Variable(const T &t_)
Construct variable with meaningful default value.
Definition: variable.hh:171
Variable< T, id > variable(const T &t)
Generate variable from input type.
Definition: variable.hh:203
const T & d0() const noexcept
Value of the variable.
Definition: variable.hh:181
typename VariableDetail::VariableType< F, id >::type Variable_t
Get underlying type of variable with index id.
Definition: variable.hh:212