Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/eigen3/Eigen/src/Core/util/IntegralConstant.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 //
0006 // This Source Code Form is subject to the terms of the Mozilla
0007 // Public License v. 2.0. If a copy of the MPL was not distributed
0008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0009 
0010 
0011 #ifndef EIGEN_INTEGRAL_CONSTANT_H
0012 #define EIGEN_INTEGRAL_CONSTANT_H
0013 
0014 namespace Eigen {
0015 
0016 namespace internal {
0017 
0018 template<int N> class FixedInt;
0019 template<int N> class VariableAndFixedInt;
0020 
0021 /** \internal
0022   * \class FixedInt
0023   *
0024   * This class embeds a compile-time integer \c N.
0025   *
0026   * It is similar to c++11 std::integral_constant<int,N> but with some additional features
0027   * such as:
0028   *  - implicit conversion to int
0029   *  - arithmetic and some bitwise operators: -, +, *, /, %, &, |
0030   *  - c++98/14 compatibility with fix<N> and fix<N>() syntax to define integral constants.
0031   *
0032   * It is strongly discouraged to directly deal with this class FixedInt. Instances are expcected to
0033   * be created by the user using Eigen::fix<N> or Eigen::fix<N>(). In C++98-11, the former syntax does
0034   * not create a FixedInt<N> instance but rather a point to function that needs to be \em cleaned-up
0035   * using the generic helper:
0036   * \code
0037   * internal::cleanup_index_type<T>::type
0038   * internal::cleanup_index_type<T,DynamicKey>::type
0039   * \endcode
0040   * where T can a FixedInt<N>, a pointer to function FixedInt<N> (*)(), or numerous other integer-like representations.
0041   * \c DynamicKey is either Dynamic (default) or DynamicIndex and used to identify true compile-time values.
0042   *
0043   * For convenience, you can extract the compile-time value \c N in a generic way using the following helper:
0044   * \code
0045   * internal::get_fixed_value<T,DefaultVal>::value
0046   * \endcode
0047   * that will give you \c N if T equals FixedInt<N> or FixedInt<N> (*)(), and \c DefaultVal if T does not embed any compile-time value (e.g., T==int).
0048   *
0049   * \sa fix<N>, class VariableAndFixedInt
0050   */
0051 template<int N> class FixedInt
0052 {
0053 public:
0054   static const int value = N;
0055   EIGEN_CONSTEXPR operator int() const { return value; }
0056   FixedInt() {}
0057   FixedInt( VariableAndFixedInt<N> other) {
0058     #ifndef EIGEN_INTERNAL_DEBUGGING
0059     EIGEN_UNUSED_VARIABLE(other);
0060     #endif
0061     eigen_internal_assert(int(other)==N);
0062   }
0063 
0064   FixedInt<-N> operator-() const { return FixedInt<-N>(); }
0065   template<int M>
0066   FixedInt<N+M> operator+( FixedInt<M>) const { return FixedInt<N+M>(); }
0067   template<int M>
0068   FixedInt<N-M> operator-( FixedInt<M>) const { return FixedInt<N-M>(); }
0069   template<int M>
0070   FixedInt<N*M> operator*( FixedInt<M>) const { return FixedInt<N*M>(); }
0071   template<int M>
0072   FixedInt<N/M> operator/( FixedInt<M>) const { return FixedInt<N/M>(); }
0073   template<int M>
0074   FixedInt<N%M> operator%( FixedInt<M>) const { return FixedInt<N%M>(); }
0075   template<int M>
0076   FixedInt<N|M> operator|( FixedInt<M>) const { return FixedInt<N|M>(); }
0077   template<int M>
0078   FixedInt<N&M> operator&( FixedInt<M>) const { return FixedInt<N&M>(); }
0079 
0080 #if EIGEN_HAS_CXX14_VARIABLE_TEMPLATES
0081   // Needed in C++14 to allow fix<N>():
0082   FixedInt operator() () const { return *this; }
0083 
0084   VariableAndFixedInt<N> operator() (int val) const { return VariableAndFixedInt<N>(val); }
0085 #else
0086   FixedInt ( FixedInt<N> (*)() ) {}
0087 #endif
0088 
0089 #if EIGEN_HAS_CXX11
0090   FixedInt(std::integral_constant<int,N>) {}
0091 #endif
0092 };
0093 
0094 /** \internal
0095   * \class VariableAndFixedInt
0096   *
0097   * This class embeds both a compile-time integer \c N and a runtime integer.
0098   * Both values are supposed to be equal unless the compile-time value \c N has a special
0099   * value meaning that the runtime-value should be used. Depending on the context, this special
0100   * value can be either Eigen::Dynamic (for positive quantities) or Eigen::DynamicIndex (for
0101   * quantities that can be negative).
0102   *
0103   * It is the return-type of the function Eigen::fix<N>(int), and most of the time this is the only
0104   * way it is used. It is strongly discouraged to directly deal with instances of VariableAndFixedInt.
0105   * Indeed, in order to write generic code, it is the responsibility of the callee to properly convert
0106   * it to either a true compile-time quantity (i.e. a FixedInt<N>), or to a runtime quantity (e.g., an Index)
0107   * using the following generic helper:
0108   * \code
0109   * internal::cleanup_index_type<T>::type
0110   * internal::cleanup_index_type<T,DynamicKey>::type
0111   * \endcode
0112   * where T can be a template instantiation of VariableAndFixedInt or numerous other integer-like representations.
0113   * \c DynamicKey is either Dynamic (default) or DynamicIndex and used to identify true compile-time values.
0114   *
0115   * For convenience, you can also extract the compile-time value \c N using the following helper:
0116   * \code
0117   * internal::get_fixed_value<T,DefaultVal>::value
0118   * \endcode
0119   * that will give you \c N if T equals VariableAndFixedInt<N>, and \c DefaultVal if T does not embed any compile-time value (e.g., T==int).
0120   *
0121   * \sa fix<N>(int), class FixedInt
0122   */
0123 template<int N> class VariableAndFixedInt
0124 {
0125 public:
0126   static const int value = N;
0127   operator int() const { return m_value; }
0128   VariableAndFixedInt(int val) { m_value = val; }
0129 protected:
0130   int m_value;
0131 };
0132 
0133 template<typename T, int Default=Dynamic> struct get_fixed_value {
0134   static const int value = Default;
0135 };
0136 
0137 template<int N,int Default> struct get_fixed_value<FixedInt<N>,Default> {
0138   static const int value = N;
0139 };
0140 
0141 #if !EIGEN_HAS_CXX14
0142 template<int N,int Default> struct get_fixed_value<FixedInt<N> (*)(),Default> {
0143   static const int value = N;
0144 };
0145 #endif
0146 
0147 template<int N,int Default> struct get_fixed_value<VariableAndFixedInt<N>,Default> {
0148   static const int value = N ;
0149 };
0150 
0151 template<typename T, int N, int Default>
0152 struct get_fixed_value<variable_if_dynamic<T,N>,Default> {
0153   static const int value = N;
0154 };
0155 
0156 template<typename T> EIGEN_DEVICE_FUNC Index get_runtime_value(const T &x) { return x; }
0157 #if !EIGEN_HAS_CXX14
0158 template<int N> EIGEN_DEVICE_FUNC Index get_runtime_value(FixedInt<N> (*)()) { return N; }
0159 #endif
0160 
0161 // Cleanup integer/FixedInt/VariableAndFixedInt/etc types:
0162 
0163 // By default, no cleanup:
0164 template<typename T, int DynamicKey=Dynamic, typename EnableIf=void> struct cleanup_index_type { typedef T type; };
0165 
0166 // Convert any integral type (e.g., short, int, unsigned int, etc.) to Eigen::Index
0167 template<typename T, int DynamicKey> struct cleanup_index_type<T,DynamicKey,typename internal::enable_if<internal::is_integral<T>::value>::type> { typedef Index type; };
0168 
0169 #if !EIGEN_HAS_CXX14
0170 // In c++98/c++11, fix<N> is a pointer to function that we better cleanup to a true FixedInt<N>:
0171 template<int N, int DynamicKey> struct cleanup_index_type<FixedInt<N> (*)(), DynamicKey> { typedef FixedInt<N> type; };
0172 #endif
0173 
0174 // If VariableAndFixedInt does not match DynamicKey, then we turn it to a pure compile-time value:
0175 template<int N, int DynamicKey> struct cleanup_index_type<VariableAndFixedInt<N>, DynamicKey> { typedef FixedInt<N> type; };
0176 // If VariableAndFixedInt matches DynamicKey, then we turn it to a pure runtime-value (aka Index):
0177 template<int DynamicKey> struct cleanup_index_type<VariableAndFixedInt<DynamicKey>, DynamicKey> { typedef Index type; };
0178 
0179 #if EIGEN_HAS_CXX11
0180 template<int N, int DynamicKey> struct cleanup_index_type<std::integral_constant<int,N>, DynamicKey> { typedef FixedInt<N> type; };
0181 #endif
0182 
0183 } // end namespace internal
0184 
0185 #ifndef EIGEN_PARSED_BY_DOXYGEN
0186 
0187 #if EIGEN_HAS_CXX14_VARIABLE_TEMPLATES
0188 template<int N>
0189 static const internal::FixedInt<N> fix{};
0190 #else
0191 template<int N>
0192 inline internal::FixedInt<N> fix() { return internal::FixedInt<N>(); }
0193 
0194 // The generic typename T is mandatory. Otherwise, a code like fix<N> could refer to either the function above or this next overload.
0195 // This way a code like fix<N> can only refer to the previous function.
0196 template<int N,typename T>
0197 inline internal::VariableAndFixedInt<N> fix(T val) { return internal::VariableAndFixedInt<N>(internal::convert_index<int>(val)); }
0198 #endif
0199 
0200 #else // EIGEN_PARSED_BY_DOXYGEN
0201 
0202 /** \var fix<N>()
0203   * \ingroup Core_Module
0204   *
0205   * This \em identifier permits to construct an object embedding a compile-time integer \c N.
0206   *
0207   * \tparam N the compile-time integer value
0208   *
0209   * It is typically used in conjunction with the Eigen::seq and Eigen::seqN functions to pass compile-time values to them:
0210   * \code
0211   * seqN(10,fix<4>,fix<-3>)   // <=> [10 7 4 1]
0212   * \endcode
0213   *
0214   * See also the function fix(int) to pass both a compile-time and runtime value.
0215   *
0216   * In c++14, it is implemented as:
0217   * \code
0218   * template<int N> static const internal::FixedInt<N> fix{};
0219   * \endcode
0220   * where internal::FixedInt<N> is an internal template class similar to
0221   * <a href="http://en.cppreference.com/w/cpp/types/integral_constant">\c std::integral_constant </a><tt> <int,N> </tt>
0222   * Here, \c fix<N> is thus an object of type \c internal::FixedInt<N>.
0223   *
0224   * In c++98/11, it is implemented as a function:
0225   * \code
0226   * template<int N> inline internal::FixedInt<N> fix();
0227   * \endcode
0228   * Here internal::FixedInt<N> is thus a pointer to function.
0229   *
0230   * If for some reason you want a true object in c++98 then you can write: \code fix<N>() \endcode which is also valid in c++14.
0231   *
0232   * \sa fix<N>(int), seq, seqN
0233   */
0234 template<int N>
0235 static const auto fix();
0236 
0237 /** \fn fix<N>(int)
0238   * \ingroup Core_Module
0239   *
0240   * This function returns an object embedding both a compile-time integer \c N, and a fallback runtime value \a val.
0241   *
0242   * \tparam N the compile-time integer value
0243   * \param  val the fallback runtime integer value
0244   *
0245   * This function is a more general version of the \ref fix identifier/function that can be used in template code
0246   * where the compile-time value could turn out to actually mean "undefined at compile-time". For positive integers
0247   * such as a size or a dimension, this case is identified by Eigen::Dynamic, whereas runtime signed integers
0248   * (e.g., an increment/stride) are identified as Eigen::DynamicIndex. In such a case, the runtime value \a val
0249   * will be used as a fallback.
0250   *
0251   * A typical use case would be:
0252   * \code
0253   * template<typename Derived> void foo(const MatrixBase<Derived> &mat) {
0254   *   const int N = Derived::RowsAtCompileTime==Dynamic ? Dynamic : Derived::RowsAtCompileTime/2;
0255   *   const int n = mat.rows()/2;
0256   *   ... mat( seqN(0,fix<N>(n) ) ...;
0257   * }
0258   * \endcode
0259   * In this example, the function Eigen::seqN knows that the second argument is expected to be a size.
0260   * If the passed compile-time value N equals Eigen::Dynamic, then the proxy object returned by fix will be dissmissed, and converted to an Eigen::Index of value \c n.
0261   * Otherwise, the runtime-value \c n will be dissmissed, and the returned ArithmeticSequence will be of the exact same type as <tt> seqN(0,fix<N>) </tt>.
0262   *
0263   * \sa fix, seqN, class ArithmeticSequence
0264   */
0265 template<int N>
0266 static const auto fix(int val);
0267 
0268 #endif // EIGEN_PARSED_BY_DOXYGEN
0269 
0270 } // end namespace Eigen
0271 
0272 #endif // EIGEN_INTEGRAL_CONSTANT_H