chromium/third_party/eigen3/src/Eigen/src/Core/util/SymbolicIndex.h

// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2017 Gael Guennebaud <[email protected]>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_SYMBOLIC_INDEX_H
#define EIGEN_SYMBOLIC_INDEX_H

// IWYU pragma: private
#include "../InternalHeaderCheck.h"

namespace Eigen {

/** \namespace Eigen::symbolic
 * \ingroup Core_Module
 *
 * This namespace defines a set of classes and functions to build and evaluate symbolic expressions of scalar type
 * Index. Here is a simple example:
 *
 * \code
 * // First step, defines symbols:
 * struct x_tag {};  static const symbolic::SymbolExpr<x_tag> x;
 * struct y_tag {};  static const symbolic::SymbolExpr<y_tag> y;
 * struct z_tag {};  static const symbolic::SymbolExpr<z_tag> z;
 *
 * // Defines an expression:
 * auto expr = (x+3)/y+z;
 *
 * // And evaluate it: (c++14)
 * std::cout << expr.eval(x=6,y=3,z=-13) << "\n";
 *
 * \endcode
 *
 * It is currently only used internally to define and manipulate the
 * Eigen::placeholders::last and Eigen::placeholders::lastp1 symbols in
 * Eigen::seq and Eigen::seqN.
 *
 */
namespace symbolic {

template <typename Tag>
class Symbol;
template <typename Tag, typename Type>
class SymbolValue;
template <typename Arg0>
class NegateExpr;
template <typename Arg1, typename Arg2>
class AddExpr;
template <typename Arg1, typename Arg2>
class ProductExpr;
template <typename Arg1, typename Arg2>
class QuotientExpr;
template <typename IndexType = Index>
class ValueExpr;

/** \class BaseExpr
 * \ingroup Core_Module
 * Common base class of any symbolic expressions
 */
template <typename Derived_>
class BaseExpr {};

template <typename T>
struct is_symbolic {};

// A simple wrapper around an integral value to provide the eval method.
// We could also use a free-function symbolic_eval...
template <typename IndexType>
class ValueExpr : BaseExpr<ValueExpr<IndexType>> {};

// Specialization for compile-time value,
// It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
ValueExpr<internal::FixedInt<N>>;

/** Represents the actual value of a symbol identified by its tag
 *
 * It is the return type of SymbolValue::operator=, and most of the time this is only way it is used.
 */
template <typename Tag, typename Type>
class SymbolValue : public BaseExpr<SymbolValue<Tag, Type>> {};

SymbolValue<Tag, Index>;

SymbolValue<Tag, internal::FixedInt<N>>;

// Find and return a symbol value based on the tag.
template <typename Tag, typename... Types>
struct EvalSymbolValueHelper;

// Empty base case, symbol not found.
EvalSymbolValueHelper<Tag>;

// We found a symbol value matching the provided Tag!
EvalSymbolValueHelper<Tag, SymbolValue<Tag, Type>, OtherTypes...>;

// No symbol value in first value, recursive search starting with next.
EvalSymbolValueHelper<Tag, T1, OtherTypes...>;

/** Expression of a symbol uniquely identified by the template parameter type \c tag */
template <typename tag>
class SymbolExpr : public BaseExpr<SymbolExpr<tag>> {};

template <typename Arg0>
class NegateExpr : public BaseExpr<NegateExpr<Arg0>> {};

template <typename Arg0, typename Arg1>
class AddExpr : public BaseExpr<AddExpr<Arg0, Arg1>> {};

template <typename Arg0, typename Arg1>
class ProductExpr : public BaseExpr<ProductExpr<Arg0, Arg1>> {};

template <typename Arg0, typename Arg1>
class QuotientExpr : public BaseExpr<QuotientExpr<Arg0, Arg1>> {};

}  // end namespace symbolic

}  // end namespace Eigen

#endif  // EIGEN_SYMBOLIC_INDEX_H