21 #ifndef RFFGEN_VARIABLE_HH
22 #define RFFGEN_VARIABLE_HH
25 #include <type_traits>
27 #include "Util/base.hh"
28 #include "Util/chainer.hh"
35 template <
class,
int>
struct Variable;
37 namespace VariableDetail
42 template <
class T,
class Arg>
43 void operator()(T& t,
const Arg& x)
45 static_assert(std::is_same<T,Arg>::value,
"Updating variable with incompatible argument. Please check your input for the update-function.");
53 template <
class T,
class Arg>
54 void operator()(
const T&,
const Arg&) {}
59 template <
class>
struct IsVariable : std::false_type {};
61 template <
class T,
int n>
62 struct IsVariable< Variable<T,n> > : std::true_type {};
66 template <
class Type>
struct HasVariable : IsVariable<Type> {};
68 template <
template <
class,
class>
class G,
class F,
class CheckF>
69 struct HasVariable< G<F,CheckF> > : std::integral_constant< bool, HasVariable<F>::value > {};
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 > {};
75 template <
class,
int id>
struct HasVariableId : std::false_type {};
77 template <
class Type,
int id0,
int id>
78 struct HasVariableId< Variable<Type,id0> , id > : std::integral_constant<bool,id==id0> {};
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 > {};
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 > {};
87 template <
class F,
class G>
90 static constexpr
int value = F::value > G::value ? F::value : G::value;
93 template <
class F,
class G>
96 static constexpr
int value = F::value < G::value ? F::value : G::value;
101 : std::integral_constant< int , std::numeric_limits<int>::lowest()>
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 >
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 >
114 template <
class T,
int id>
115 struct MaxVariableId< Variable<T,id> > : std::integral_constant< int , id >
119 template <
class Type>
121 : std::integral_constant< int , std::numeric_limits<int>::max()>
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 >
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 >
134 template <
class T,
int id>
135 struct MinVariableId< Variable<T,id> > : std::integral_constant< int , id >
140 template <
class F,
int id>
struct VariableType {
using type = void; };
142 template <
template <
class,
class>
class G,
class F,
class CheckF,
int id>
143 struct VariableType< G<F,CheckF> , id >
145 using type =
typename VariableType<F,id>::type;
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 >
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>;
155 template <
class T,
int id>
156 struct VariableType< Variable<T,id>, id > {
using type = T; };
165 template <
class T,
int id>
174 template <
int index,
class Arg>
177 VariableDetail::Update<index==id>()(t,t_);
181 const T&
d0() const noexcept
191 template <
int index ,
class = std::enable_if_t<
id == index > >
192 const T&
d1(
const T& dt)
const noexcept
202 template <
int id,
class T>
211 template <
class F,
int id>
212 using Variable_t =
typename VariableDetail::VariableType<F,id>::type;
221 constexpr
bool isVariable() {
return VariableDetail::IsVariable<T>::value; }
228 constexpr
bool hasVariable() {
return VariableDetail::HasVariable<T>::value; }
234 template <
class T,
int id>
235 constexpr
bool hasVariableId() {
return VariableDetail::HasVariableId<T,id>::value; }
241 template <
class Type>
242 constexpr
bool hasMoreThanOneVariable()
244 return VariableDetail::MinVariableId<Type>::value < VariableDetail::MaxVariableId<Type>::value;
251 template <
class F,
class Type,
int id>
252 constexpr
bool checkArgument()
254 return std::is_same<typename VariableDetail::VariableType<F,id>::type, Type>::value;
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