3 #include <funcy/concepts.h> 4 #include <funcy/util/traverse.h> 13 template <
class,
int >
16 template <
class T,
class Other >
17 struct ContainsType : std::false_type
22 struct ContainsType< T, T > : std::true_type
26 template <
class T,
class Gradient >
27 struct ContainsType< T, std::tuple< T, Gradient > > : std::true_type
31 template <
class T,
class Value >
32 struct ContainsType< T, std::tuple< Value, T > > : std::true_type
38 template <
class Arg,
class Extended >
41 template <
class Arg,
class Gradient >
42 struct Assign< Arg, std::tuple< Arg, Gradient > >
44 static auto apply( Arg& t,
const std::tuple< Arg, Gradient >& x )
46 t = std::get< 0 >( x );
50 template <
class Arg,
class Value >
51 struct Assign< Arg, std::tuple< Value, Arg > >
53 static auto apply( Arg& t,
const std::tuple< Value, Arg >& x )
55 t = std::get< 1 >( x );
59 template <
class Arg >
60 struct Assign< Arg, Arg >
62 static void apply( Arg& t,
const Arg& x )
68 template <
class T,
class Other >
69 struct ExtractReturnValue;
72 struct ExtractReturnValue< T, T >
74 static const T& apply(
const T& x )
80 template <
class T,
class Gradient >
81 struct ExtractReturnValue< T, std::tuple< T, Gradient > >
83 static const T& apply(
const std::tuple< T, Gradient >& x )
85 return std::get< 0 >( x );
89 template <
class T,
class Value >
90 struct ExtractReturnValue< T, std::tuple< Value, T > >
92 static const T& apply(
const std::tuple< Value, T >& x )
94 return std::get< 1 >( x );
101 template <
class T,
class Arg >
102 static void apply( T& t,
const Arg& x )
104 Assign< T, Arg >::apply( t, x );
109 struct Update< false >
111 template <
class T,
class Arg >
112 static void apply(
const T&,
const Arg& )
120 template <
class T,
int id >
125 constexpr
explicit Variable(
const T& t_ ) : t( t_ )
129 constexpr
explicit Variable( T&& t_ ) : t( std::move( t_ ) )
134 template <
int index,
class Arg >
137 detail::Update< index == id >::apply( t, t_ );
147 template <
int index,
class Arg,
class = std::enable_if_t<
id == index > >
148 const T&
d1(
const Arg& dt )
const noexcept
150 return detail::ExtractReturnValue< T, Arg >::apply( dt );
158 template <
int id,
class T >
169 struct IsVariable : std::false_type
173 template <
class T,
int n >
174 struct IsVariable< Variable< T, n > > : std::true_type
178 template <
class,
int >
179 struct HasVariableWithId : std::false_type
183 template <
class Type,
int id0,
int id >
184 struct HasVariableWithId< funcy::Variable< Type, id0 >, id >
185 : std::integral_constant< bool, id == id0 >
192 template < Function F >
193 using Variable = meta::AnyOf< F, IsVariable >;
195 template <
class F,
int id >
201 static constexpr
bool value = HasVariableWithId< G, id >::value;
203 static constexpr
bool value = meta::AnyOf< F, HasVariable >::value;
207 constexpr
bool greater(
int a,
int b )
212 template <
class F,
class G >
214 : std::integral_constant< int, greater( F::value, G::value ) ? F::value : G::value >
218 template <
class F,
class G >
220 : std::integral_constant< int, greater( G::value, F::value ) ? F::value : G::value >
226 template <
class Type >
228 : std::integral_constant< int, std::numeric_limits< int >::lowest() >
232 template <
class T,
int id >
233 struct MaxVariableId< funcy::Variable< T, id > > : std::integral_constant< int, id >
237 template <
class T,
int id >
238 struct MaxVariableId< const funcy::Variable< T, id > >
239 : std::integral_constant< int, id >
243 template <
class Type >
244 struct MinVariableId : std::integral_constant< int, std::numeric_limits< int >::max() >
248 template <
class T,
int id >
249 struct MinVariableId< funcy::Variable< T, id > > : std::integral_constant< int, id >
253 template <
class T,
int id >
254 struct MinVariableId< const funcy::Variable< T, id > >
255 : std::integral_constant< int, id >
261 using MaxVariableId = meta::Traverse< F, detail::MaxVariableId, Max >;
264 using MinVariableId = meta::Traverse< F, detail::MinVariableId, Min >;
266 template <
class F,
int id >
272 template <
class T,
int id >
273 struct VariableType< Variable< T, id >, id >
278 template <
class T,
int id >
279 struct VariableType< const Variable< T, id >, id >
284 template <
class T,
class >
285 struct ChooseTypeImpl
291 struct ChooseTypeImpl< void, T >
297 struct ChooseTypeImpl< void, void >
302 template <
class F,
class G >
305 using type =
typename ChooseTypeImpl< typename F::type, typename G::type >::type;
308 template <
class F,
int id >
312 using Extractor = VariableType< G, id >;
314 using type =
typename meta::Traverse< std::decay_t< F >, Extractor, ChooseType >::type;
320 template <
class F,
int id >
321 using Variable_t =
typename detail::VariableT< F, id >::type;
323 namespace static_check
328 template < Function T >
331 return detail::has::Variable< std::decay_t< T > >::value;
335 template <
class T,
int id >
336 constexpr
bool variable_id()
338 return detail::has::VariableId< std::decay_t< T >,
id >::value;
343 template <
class F,
class Type,
int id >
344 constexpr
bool check_argument()
346 return ContainsType< Variable_t< F, id >, Type >::value;
typename detail::VariableT< F, id >::type Variable_t
Get underlying type of variable with index id.
Definition: variable.h:321
const T & d1(const Arg &dt) const noexcept
First directional derivative. Only available if id==index.
Definition: variable.h:148
Variable< T, id > variable(const T &t)
Generate variable from input type.
Definition: variable.h:159
Main namespace of the funcy library.
Independent variable. Can be uniquely identified by its id.
Definition: variable.h:121
constexpr const T & operator()() const noexcept
Value of the variable.
Definition: variable.h:141
void update(const Arg &t_)
Update variable if index==id.
Definition: variable.h:135