11#ifndef EIGEN_SYMBOLIC_INDEX_H
12#define EIGEN_SYMBOLIC_INDEX_H
15#include "../InternalHeaderCheck.h"
46template <
typename Tag,
typename Type>
48template <
typename Arg0>
50template <
typename Arg1,
typename Arg2>
52template <
typename Arg1,
typename Arg2>
54template <
typename Arg1,
typename Arg2>
56template <
typename IndexType = Index>
63template <
typename Derived_>
66 using Derived = Derived_;
67 constexpr const Derived& derived()
const {
return *
static_cast<const Derived*
>(
this); }
74 template <
typename... Tags,
typename... Types>
76 return derived().eval_impl(values...);
84 template <
typename... Tags,
typename... Types>
89 constexpr NegateExpr<Derived> operator-()
const {
return NegateExpr<Derived>(derived()); }
91 constexpr AddExpr<Derived, ValueExpr<>> operator+(Index b)
const {
92 return AddExpr<Derived, ValueExpr<>>(derived(), b);
94 constexpr AddExpr<Derived, ValueExpr<>> operator-(Index a)
const {
95 return AddExpr<Derived, ValueExpr<>>(derived(), -a);
97 constexpr ProductExpr<Derived, ValueExpr<>> operator*(Index a)
const {
98 return ProductExpr<Derived, ValueExpr<>>(derived(), a);
100 constexpr QuotientExpr<Derived, ValueExpr<>> operator/(Index a)
const {
101 return QuotientExpr<Derived, ValueExpr<>>(derived(), a);
104 friend constexpr AddExpr<Derived, ValueExpr<>> operator+(Index a,
const BaseExpr& b) {
105 return AddExpr<Derived, ValueExpr<>>(b.derived(), a);
107 friend constexpr AddExpr<NegateExpr<Derived>, ValueExpr<>> operator-(Index a,
const BaseExpr& b) {
108 return AddExpr<NegateExpr<Derived>, ValueExpr<>>(-b.derived(), a);
110 friend constexpr ProductExpr<ValueExpr<>, Derived> operator*(Index a,
const BaseExpr& b) {
111 return ProductExpr<ValueExpr<>, Derived>(a, b.derived());
113 friend constexpr QuotientExpr<ValueExpr<>, Derived> operator/(Index a,
const BaseExpr& b) {
114 return QuotientExpr<ValueExpr<>, Derived>(a, b.derived());
118 constexpr AddExpr<Derived, ValueExpr<internal::FixedInt<N>>> operator+(internal::FixedInt<N>)
const {
119 return AddExpr<Derived, ValueExpr<internal::FixedInt<N>>>(derived(), ValueExpr<internal::FixedInt<N>>());
122 constexpr AddExpr<Derived, ValueExpr<internal::FixedInt<-N>>> operator-(internal::FixedInt<N>)
const {
123 return AddExpr<Derived, ValueExpr<internal::FixedInt<-N>>>(derived(), ValueExpr<internal::FixedInt<-N>>());
126 constexpr ProductExpr<Derived, ValueExpr<internal::FixedInt<N>>> operator*(internal::FixedInt<N>)
const {
127 return ProductExpr<Derived, ValueExpr<internal::FixedInt<N>>>(derived(), ValueExpr<internal::FixedInt<N>>());
130 constexpr QuotientExpr<Derived, ValueExpr<internal::FixedInt<N>>> operator/(internal::FixedInt<N>)
const {
131 return QuotientExpr<Derived, ValueExpr<internal::FixedInt<N>>>(derived(), ValueExpr<internal::FixedInt<N>>());
135 friend constexpr AddExpr<Derived, ValueExpr<internal::FixedInt<N>>> operator+(internal::FixedInt<N>,
137 return AddExpr<Derived, ValueExpr<internal::FixedInt<N>>>(b.derived(), ValueExpr<internal::FixedInt<N>>());
140 friend constexpr AddExpr<NegateExpr<Derived>, ValueExpr<internal::FixedInt<N>>> operator-(internal::FixedInt<N>,
142 return AddExpr<NegateExpr<Derived>, ValueExpr<internal::FixedInt<N>>>(-b.derived(),
143 ValueExpr<internal::FixedInt<N>>());
146 friend constexpr ProductExpr<ValueExpr<internal::FixedInt<N>>, Derived> operator*(internal::FixedInt<N>,
148 return ProductExpr<ValueExpr<internal::FixedInt<N>>, Derived>(ValueExpr<internal::FixedInt<N>>(), b.derived());
151 friend constexpr QuotientExpr<ValueExpr<internal::FixedInt<N>>, Derived> operator/(internal::FixedInt<N>,
153 return QuotientExpr<ValueExpr<internal::FixedInt<N>>, Derived>(ValueExpr<internal::FixedInt<N>>(), b.derived());
156 template <
typename OtherDerived>
157 constexpr AddExpr<Derived, OtherDerived> operator+(
const BaseExpr<OtherDerived>& b)
const {
158 return AddExpr<Derived, OtherDerived>(derived(), b.derived());
161 template <
typename OtherDerived>
162 constexpr AddExpr<Derived, NegateExpr<OtherDerived>> operator-(
const BaseExpr<OtherDerived>& b)
const {
163 return AddExpr<Derived, NegateExpr<OtherDerived>>(derived(), -b.derived());
166 template <
typename OtherDerived>
167 constexpr ProductExpr<Derived, OtherDerived> operator*(
const BaseExpr<OtherDerived>& b)
const {
168 return ProductExpr<Derived, OtherDerived>(derived(), b.derived());
171 template <
typename OtherDerived>
172 constexpr QuotientExpr<Derived, OtherDerived> operator/(
const BaseExpr<OtherDerived>& b)
const {
173 return QuotientExpr<Derived, OtherDerived>(derived(), b.derived());
180struct is_symbolic : std::is_convertible<T, BaseExpr<T>> {};
184template <
typename IndexType>
185class ValueExpr :
BaseExpr<ValueExpr<IndexType>> {
187 constexpr ValueExpr() =
default;
188 constexpr ValueExpr(IndexType val) : m_value(val) {}
189 template <
typename... Tags,
typename... Types>
190 constexpr IndexType eval_impl(
const SymbolValue<Tags, Types>&...)
const {
193 template <
typename... Tags,
typename... Types>
194 static constexpr IndexType eval_at_compile_time_impl(
const SymbolValue<Tags, Types>&...) {
195 return IndexType(Undefined);
205class ValueExpr<internal::FixedInt<N>> :
public BaseExpr<ValueExpr<internal::FixedInt<N>>> {
207 constexpr ValueExpr() =
default;
208 constexpr ValueExpr(internal::FixedInt<N>) {}
209 template <
typename... Tags,
typename... Types>
210 constexpr Index eval_impl(
const SymbolValue<Tags, Types>&...)
const {
213 template <
typename... Tags,
typename... Types>
214 static constexpr Index eval_at_compile_time_impl(
const SymbolValue<Tags, Types>&...) {
223template <
typename Tag,
typename Type>
226template <
typename Tag>
235 constexpr Index value()
const {
return m_value; }
238 static constexpr Index value_at_compile_time() {
return Index(Undefined); }
240 template <
typename... Tags,
typename... Types>
241 constexpr Index eval_impl(
const SymbolValue<Tags, Types>&...)
const {
245 template <
typename... Tags,
typename... Types>
246 static constexpr Index eval_at_compile_time_impl(
const SymbolValue<Tags, Types>&...) {
247 return value_at_compile_time();
254template <
typename Tag,
int N>
255class SymbolValue<Tag, internal::FixedInt<N>> :
public BaseExpr<SymbolValue<Tag, internal::FixedInt<N>>> {
257 constexpr SymbolValue() =
default;
260 constexpr SymbolValue(internal::FixedInt<N>) {}
263 constexpr Index value()
const {
return static_cast<Index
>(N); }
266 static constexpr Index value_at_compile_time() {
return static_cast<Index
>(N); }
268 template <
typename... Tags,
typename... Types>
269 constexpr Index eval_impl(
const SymbolValue<Tags, Types>&...)
const {
273 template <
typename... Tags,
typename... Types>
274 static constexpr Index eval_at_compile_time_impl(
const SymbolValue<Tags, Types>&...) {
275 return value_at_compile_time();
280template <
typename Tag,
typename... Types>
281struct EvalSymbolValueHelper;
284template <
typename Tag>
285struct EvalSymbolValueHelper<Tag> {
286 static constexpr Index eval_impl() {
287 eigen_assert(
false &&
"Symbol not found.");
288 return Index(Undefined);
290 static constexpr Index eval_at_compile_time_impl() {
return Index(Undefined); }
294template <
typename Tag,
typename Type,
typename... OtherTypes>
295struct EvalSymbolValueHelper<Tag,
SymbolValue<Tag, Type>, OtherTypes...> {
296 static constexpr Index eval_impl(
const SymbolValue<Tag, Type>& symbol,
const OtherTypes&...) {
297 return symbol.value();
299 static constexpr Index eval_at_compile_time_impl(
const SymbolValue<Tag, Type>& symbol,
const OtherTypes&...) {
300 return symbol.value_at_compile_time();
305template <
typename Tag,
typename T1,
typename... OtherTypes>
306struct EvalSymbolValueHelper<Tag, T1, OtherTypes...> {
307 static constexpr Index eval_impl(
const T1&,
const OtherTypes&... values) {
308 return EvalSymbolValueHelper<Tag, OtherTypes...>::eval_impl(values...);
310 static constexpr Index eval_at_compile_time_impl(
const T1&,
const OtherTypes&...) {
311 return EvalSymbolValueHelper<Tag, OtherTypes...>::eval_at_compile_time_impl(OtherTypes{}...);
316template <
typename tag>
317class SymbolExpr :
public BaseExpr<SymbolExpr<tag>> {
322 constexpr SymbolExpr() =
default;
336 template <
typename... Tags,
typename... Types>
337 constexpr Index eval_impl(
const SymbolValue<Tags, Types>&... values)
const {
338 return EvalSymbolValueHelper<Tag, SymbolValue<Tags, Types>...>::eval_impl(values...);
341 template <
typename... Tags,
typename... Types>
342 static constexpr Index eval_at_compile_time_impl(
const SymbolValue<Tags, Types>&...) {
343 return EvalSymbolValueHelper<Tag, SymbolValue<Tags, Types>...>::eval_at_compile_time_impl(
344 SymbolValue<Tags, Types>{}...);
348template <
typename Arg0>
349class NegateExpr :
public BaseExpr<NegateExpr<Arg0>> {
351 constexpr NegateExpr() =
default;
352 constexpr NegateExpr(
const Arg0& arg0) : m_arg0(arg0) {}
354 template <
typename... Tags,
typename... Types>
355 constexpr Index eval_impl(
const SymbolValue<Tags, Types>&... values)
const {
356 return -m_arg0.eval_impl(values...);
359 template <
typename... Tags,
typename... Types>
360 static constexpr Index eval_at_compile_time_impl(
const SymbolValue<Tags, Types>&...) {
361 constexpr Index v = Arg0::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
362 return (v == Undefined) ? Undefined : -v;
369template <
typename Arg0,
typename Arg1>
370class AddExpr :
public BaseExpr<AddExpr<Arg0, Arg1>> {
372 constexpr AddExpr() =
default;
373 constexpr AddExpr(
const Arg0& arg0,
const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
375 template <
typename... Tags,
typename... Types>
376 constexpr Index eval_impl(
const SymbolValue<Tags, Types>&... values)
const {
377 return m_arg0.eval_impl(values...) + m_arg1.eval_impl(values...);
380 template <
typename... Tags,
typename... Types>
381 static constexpr Index eval_at_compile_time_impl(
const SymbolValue<Tags, Types>&...) {
382 constexpr Index v0 = Arg0::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
383 constexpr Index v1 = Arg1::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
384 return (v0 == Undefined || v1 == Undefined) ? Undefined : v0 + v1;
392template <
typename Arg0,
typename Arg1>
393class ProductExpr :
public BaseExpr<ProductExpr<Arg0, Arg1>> {
395 constexpr ProductExpr() =
default;
396 constexpr ProductExpr(
const Arg0& arg0,
const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
398 template <
typename... Tags,
typename... Types>
399 constexpr Index eval_impl(
const SymbolValue<Tags, Types>&... values)
const {
400 return m_arg0.eval_impl(values...) * m_arg1.eval_impl(values...);
403 template <
typename... Tags,
typename... Types>
404 static constexpr Index eval_at_compile_time_impl(
const SymbolValue<Tags, Types>&...) {
405 constexpr Index v0 = Arg0::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
406 constexpr Index v1 = Arg1::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
407 return (v0 == Undefined || v1 == Undefined) ? Undefined : v0 * v1;
415template <
typename Arg0,
typename Arg1>
416class QuotientExpr :
public BaseExpr<QuotientExpr<Arg0, Arg1>> {
418 constexpr QuotientExpr() =
default;
419 constexpr QuotientExpr(
const Arg0& arg0,
const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}
421 template <
typename... Tags,
typename... Types>
422 constexpr Index eval_impl(
const SymbolValue<Tags, Types>&... values)
const {
423 return m_arg0.eval_impl(values...) / m_arg1.eval_impl(values...);
426 template <
typename... Tags,
typename... Types>
427 static constexpr Index eval_at_compile_time_impl(
const SymbolValue<Tags, Types>&...) {
428 constexpr Index v0 = Arg0::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
429 constexpr Index v1 = Arg1::eval_at_compile_time_impl(SymbolValue<Tags, Types>{}...);
430 return (v0 == Undefined || v1 == Undefined) ? Undefined : v0 / v1;
Definition SymbolicIndex.h:64
constexpr Index eval(const SymbolValue< Tags, Types > &... values) const
Definition SymbolicIndex.h:75
static constexpr Index eval_at_compile_time(const SymbolValue< Tags, Types > &...)
Definition SymbolicIndex.h:85
constexpr SymbolValue< Tag, Index > operator=(Index val) const
Definition SymbolicIndex.h:329
internal::symbolic_last_tag Tag
Definition SymbolicIndex.h:320
Definition SymbolicIndex.h:224