21 #ifndef RFFGEN_FINALIZE_HH
22 #define RFFGEN_FINALIZE_HH
24 #include <type_traits>
26 #include "Util/consistencyCheck.hh"
27 #include "Util/indexedType.hh"
28 #include "variable.hh"
37 template <
class ReturnType>
40 template <
class... Args>
41 __attribute__((always_inline)) ReturnType operator()(const Args&...)
const
48 template <
int id,
class ReturnType,
bool present>
49 struct FinalizeD1 : FillDefault<ReturnType> {};
51 template <
int id,
class ReturnType>
52 struct FinalizeD1<id,ReturnType,true>
54 template <
class F,
class Arg>
55 __attribute__((always_inline)) ReturnType operator()(const F& f, const Arg& dx)
const
57 return f.template d1<id>(dx);
62 template <
int idx,
int idy,
class ReturnType,
bool present>
63 struct FinalizeD2 : FillDefault<ReturnType> {};
65 template <
int idx,
int idy,
class ReturnType>
66 struct FinalizeD2<idx,idy,ReturnType,true>
68 template <
class F,
class ArgX,
class ArgY>
69 __attribute__((always_inline)) ReturnType operator()(const F& f, const ArgX& dx, const ArgY& dy)
const
71 return f.template d2<idx,idy>(dx,dy);
76 template <
int idx,
int idy,
int idz,
class ReturnType,
bool present>
77 struct FinalizeD3 : FillDefault<ReturnType> {};
79 template <
int idx,
int idy,
int idz,
class ReturnType>
80 struct FinalizeD3<idx,idy,idz,ReturnType,true>
82 template <
class F,
class Arg>
83 __attribute__((always_inline)) ReturnType operator()(const F& f, const Arg& dx, const Arg& dy, const Arg& dz)
const {
return f.template d3<idx,idy,idz>(dx,dy,dz); }
90 template <
class F,
bool arithmeticReturnType,
bool hasVariables>
91 struct FinalizeImpl : F
93 using ReturnType = std::remove_const_t<std::remove_reference_t<decltype(std::declval<F>().d0())> >;
95 template <
class... Args>
96 FinalizeImpl(
const Args&... args) : F(args...)
99 template <
int index,
class Arg>
100 void update(
const Arg& x)
102 F::template updateVariable<index>(x);
106 ReturnType operator()()
const
111 template <
int id ,
class Arg >
112 ReturnType d1(
const Arg& dx)
const
114 static_assert( Checks::hasVariableId< F , id >() ,
"You are trying to compute the first derivative with respect to a variable that is not present" );
115 static_assert( Checks::checkArgument<F,Arg,id>() ,
"Incompatible argument in computation of first derivative." );
116 static_assert( hasConsistentFirstDerivative< F >() ,
"Inconsistent functional definition encountered.");
118 return FinalizeD1< id , ReturnType , HasD1MemberFunction< F , IndexedType<Arg,id> >::value>()(static_cast<const F&>(*
this),dx);
121 template <
int idx ,
int idy ,
class ArgX ,
class ArgY >
122 ReturnType d2(
const ArgX& dx,
const ArgY& dy)
const
124 static_assert( Checks::hasVariableId< F , idx >() && Checks::hasVariableId< F , idy>(),
125 "You are trying to compute the second derivative with respect to at least one variable that is not present" );
126 static_assert( Checks::checkArgument<F,ArgX,idx>() ,
"Incompatible first argument in computation of second derivative." );
127 static_assert( Checks::checkArgument<F,ArgY,idy>() ,
"Incompatible second argument in computation of second derivative." );
128 static_assert( hasConsistentSecondDerivative< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> >(),
"Inconsistent functional definition encountered." );
130 return FinalizeD2< idx , idy , ReturnType , HasD2MemberFunction< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> >::value>()(static_cast<const F&>(*
this),dx,dy);
133 template <
int idx ,
int idy ,
int idz ,
class ArgX ,
class ArgY ,
class ArgZ >
134 ReturnType d3(
const ArgX& dx,
const ArgY& dy,
const ArgZ& dz)
const
136 static_assert( Checks::hasVariableId< F , idx >() && Checks::hasVariableId< F , idy>() && Checks::hasVariableId< F , idz >(),
137 "You are trying to compute the third derivative with respect to at least one variable that is not present" );
138 static_assert( Checks::checkArgument<F,ArgX,idx>() ,
"Incompatible first argument in computation of third derivative." );
139 static_assert( Checks::checkArgument<F,ArgY,idy>() ,
"Incompatible second argument in computation of third derivative." );
140 static_assert( Checks::checkArgument<F,ArgZ,idz>() ,
"Incompatible third argument in computation of third derivative." );
141 static_assert(hasConsistentThirdDerivative< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> , IndexedType<ArgZ,idz> >(),
"Inconsistent functional definition encountered.");
143 return FinalizeD3< idx , idy , idz , ReturnType ,
144 HasD3MemberFunction< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> , IndexedType<ArgZ,idz> >::value>()(static_cast<const F&>(*
this),dx,dy,dz);
149 struct FinalizeImpl<F,true,true> : F
151 using ReturnType = std::remove_const_t<std::remove_reference_t<decltype(std::declval<F>().d0())> >;
153 template <
class... Args>
154 FinalizeImpl(
const Args&... args) : F(args...)
157 template <
int index,
class Arg>
158 void update(
const Arg& x)
160 F::template updateVariable<index>(x);
164 ReturnType operator()()
const
169 template <
int id ,
class Arg =
double >
170 ReturnType d1(Arg dx=1)
const
172 static_assert( Checks::hasVariableId< F , id >(),
"You are trying to compute the first derivative with respect to a variable that is not present" );
173 static_assert( Checks::checkArgument<F,Arg,id>() ,
"Incompatible argument in computation of first derivative." );
174 static_assert( hasConsistentFirstDerivative< F >(),
"Inconsistent functional definition encountered." );
175 return FinalizeD1< id , ReturnType , HasD1MemberFunction< F , IndexedType<Arg,id> >::value >()(static_cast<const F&>(*
this),dx);
178 template <
int idx ,
int idy ,
class ArgX =
double ,
class ArgY =
double >
179 ReturnType d2(ArgX dx=1, ArgY dy=1)
const
181 static_assert(Checks::hasVariableId< F , idx >() && Checks::hasVariableId< F , idy>(),
182 "You are trying to compute the second derivative with respect to at least one variable that is not present");
183 static_assert( Checks::checkArgument<F,ArgX,idx>() ,
"Incompatible first argument in computation of second derivative." );
184 static_assert( Checks::checkArgument<F,ArgY,idy>() ,
"Incompatible second argument in computation of second derivative." );
185 static_assert(hasConsistentSecondDerivative< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> >(),
"Inconsistent functional definition encountered." );
187 return FinalizeD2< idx , idy , ReturnType , HasD2MemberFunction< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> >::value >()(static_cast<const F&>(*
this),dx,dy);
190 template <
int idx ,
int idy ,
int idz ,
class ArgX =
double ,
class ArgY =
double ,
class ArgZ =
double>
191 ReturnType d3(ArgX dx=1, ArgY dy=1, ArgZ dz=1)
const
193 static_assert(Checks::hasVariableId< F , idx >() && Checks::hasVariableId< F , idy>() && Checks::hasVariableId< F , idz >(),
194 "You are trying to compute the third derivative with respect to at least one variable that is not present");
195 static_assert( Checks::checkArgument<F,ArgX,idx>() ,
"Incompatible first argument in computation of third derivative." );
196 static_assert( Checks::checkArgument<F,ArgY,idy>() ,
"Incompatible second argument in computation of third derivative." );
197 static_assert( Checks::checkArgument<F,ArgZ,idz>() ,
"Incompatible third argument in computation of third derivative." );
198 static_assert(hasConsistentThirdDerivative< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> , IndexedType<ArgZ,idz> >(),
"Inconsistent functional definition encountered.");
200 return FinalizeD3< idx , idy , idy , ReturnType ,
201 HasD3MemberFunction< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> , IndexedType<ArgZ,idz> >::value >()(static_cast<const F&>(*
this),dx,dy,dz);
206 struct FinalizeImpl<F,true,false> : F
208 using ReturnType = std::remove_const_t<std::remove_reference_t<decltype(std::declval<F>().d0())> >;
210 template <
class... Args>
211 FinalizeImpl(
const Args&... args) : F(args...)
215 ReturnType operator()(
const Arg& x)
222 ReturnType operator()()
const
227 template <
int id = 0 ,
class Arg =
double >
228 ReturnType d1(Arg dx=1)
const
230 static_assert( hasConsistentFirstDerivative< F >(),
"Inconsistent functional definition encountered." );
231 return FinalizeD1< id , ReturnType , HasD1MemberFunction< F , IndexedType<Arg,id> >::value >()(static_cast<const F&>(*
this),dx);
234 template <
int idx = 0 ,
int idy = 0 ,
class ArgX =
double ,
class ArgY =
double >
235 ReturnType d2(ArgX dx=1, ArgY dy=1)
const
237 static_assert( hasConsistentSecondDerivative< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> >(),
"Inconsistent functional definition encountered." );
238 return FinalizeD2< idx , idy , ReturnType , HasD2MemberFunction< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> >::value >()(static_cast<const F&>(*
this),dx,dy);
241 template <
int idx = 0 ,
int idy = 0 ,
int idz = 0 ,
class ArgX =
double ,
class ArgY =
double ,
class ArgZ =
double>
242 ReturnType d3(ArgX dx=1, ArgY dy=1, ArgZ dz=1)
const
244 static_assert( hasConsistentThirdDerivative< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> , IndexedType<ArgZ,idz> >(),
"Inconsistent functional definition encountered." );
245 return FinalizeD3< idx , idy , idy , ReturnType ,
246 HasD3MemberFunction< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> , IndexedType<ArgZ,idz> >::value >()(static_cast<const F&>(*
this),dx,dy,dz);
251 struct FinalizeImpl<F,false,false> : F
253 using ReturnType = std::remove_const_t<std::remove_reference_t<decltype(std::declval<F>().d0())> >;
255 template <
class... Args>
256 FinalizeImpl(
const Args&... args) : F(args...)
259 ReturnType operator()()
const
264 template <
int id = 0 ,
class Arg =
double >
265 ReturnType d1(
const Arg& dx)
const
267 static_assert( hasConsistentFirstDerivative< F >(),
"Inconsistent functional definition encountered." );
268 return FinalizeD1< id , ReturnType , HasD1MemberFunction< F , IndexedType<Arg,id> >::value >()(static_cast<const F&>(*
this),dx);
271 template <
int idx = 0 ,
int idy = 0 ,
class ArgX =
double ,
class ArgY =
double >
272 ReturnType d2(
const ArgX& dx,
const ArgY& dy)
const
274 static_assert( hasConsistentSecondDerivative< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> >(),
"Inconsistent functional definition encountered." );
275 return FinalizeD2< idx , idy , ReturnType , HasD2MemberFunction< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> >::value >()(static_cast<const F&>(*
this),dx,dy);
278 template <
int idx = 0 ,
int idy = 0 ,
int idz = 0 ,
class ArgX =
double ,
class ArgY =
double ,
class ArgZ =
double>
279 ReturnType d3(
const ArgX& dx,
const ArgY& dy,
const ArgZ& dz)
const
281 static_assert( hasConsistentThirdDerivative< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> , IndexedType<ArgZ,idz> >(),
"Inconsistent functional definition encountered." );
282 return FinalizeD3< idx , idy , idy , ReturnType ,
283 HasD3MemberFunction< F , IndexedType<ArgX,idx> , IndexedType<ArgY,idy> , IndexedType<ArgZ,idz> >::value >()(static_cast<const F&>(*
this),dx,dy,dz);
296 template <
class F,
bool arithmeticArgument = false>
297 using Finalize = Detail::FinalizeImpl< F , arithmeticArgument , Checks::hasVariable<F>() >;
322 #endif // RFFGEN_FINALIZE_HH
Detail::FinalizeImpl< F, arithmeticArgument, Checks::hasVariable< F >() > Finalize
Finish function definition.
Definition: finalize.hh:297
auto finalize(const F &f)
Finish function definition.
Definition: finalize.hh:305
auto finalize_scalar(const F &f)
Finish function definition.
Definition: finalize.hh:316