LCOV - code coverage report
Current view: top level - Core/util - IntegralConstant.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 3 3 100.0 %
Date: 1980-01-01 00:00:00 Functions: 3 3 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // This file is part of Eigen, a lightweight C++ template library
       2                 :            : // for linear algebra.
       3                 :            : //
       4                 :            : // Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
       5                 :            : //
       6                 :            : // This Source Code Form is subject to the terms of the Mozilla
       7                 :            : // Public License v. 2.0. If a copy of the MPL was not distributed
       8                 :            : // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
       9                 :            : 
      10                 :            : 
      11                 :            : #ifndef EIGEN_INTEGRAL_CONSTANT_H
      12                 :            : #define EIGEN_INTEGRAL_CONSTANT_H
      13                 :            : 
      14                 :            : namespace Eigen {
      15                 :            : 
      16                 :            : namespace internal {
      17                 :            : 
      18                 :            : template<int N> class FixedInt;
      19                 :            : template<int N> class VariableAndFixedInt;
      20                 :            : 
      21                 :            : /** \internal
      22                 :            :   * \class FixedInt
      23                 :            :   *
      24                 :            :   * This class embeds a compile-time integer \c N.
      25                 :            :   *
      26                 :            :   * It is similar to c++11 std::integral_constant<int,N> but with some additional features
      27                 :            :   * such as:
      28                 :            :   *  - implicit conversion to int
      29                 :            :   *  - arithmetic and some bitwise operators: -, +, *, /, %, &, |
      30                 :            :   *  - c++98/14 compatibility with fix<N> and fix<N>() syntax to define integral constants.
      31                 :            :   *
      32                 :            :   * It is strongly discouraged to directly deal with this class FixedInt. Instances are expcected to
      33                 :            :   * be created by the user using Eigen::fix<N> or Eigen::fix<N>(). In C++98-11, the former syntax does
      34                 :            :   * not create a FixedInt<N> instance but rather a point to function that needs to be \em cleaned-up
      35                 :            :   * using the generic helper:
      36                 :            :   * \code
      37                 :            :   * internal::cleanup_index_type<T>::type
      38                 :            :   * internal::cleanup_index_type<T,DynamicKey>::type
      39                 :            :   * \endcode
      40                 :            :   * where T can a FixedInt<N>, a pointer to function FixedInt<N> (*)(), or numerous other integer-like representations.
      41                 :            :   * \c DynamicKey is either Dynamic (default) or DynamicIndex and used to identify true compile-time values.
      42                 :            :   *
      43                 :            :   * For convenience, you can extract the compile-time value \c N in a generic way using the following helper:
      44                 :            :   * \code
      45                 :            :   * internal::get_fixed_value<T,DefaultVal>::value
      46                 :            :   * \endcode
      47                 :            :   * 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).
      48                 :            :   *
      49                 :            :   * \sa fix<N>, class VariableAndFixedInt
      50                 :            :   */
      51                 :            : template<int N> class FixedInt
      52                 :            : {
      53                 :            : public:
      54                 :            :   static const int value = N;
      55                 :            :   EIGEN_CONSTEXPR operator int() const { return value; }
      56                 :          4 :   FixedInt() {}
      57                 :            :   FixedInt( VariableAndFixedInt<N> other) {
      58                 :            :     #ifndef EIGEN_INTERNAL_DEBUGGING
      59                 :            :     EIGEN_UNUSED_VARIABLE(other);
      60                 :            :     #endif
      61                 :            :     eigen_internal_assert(int(other)==N);
      62                 :            :   }
      63                 :            : 
      64                 :            :   FixedInt<-N> operator-() const { return FixedInt<-N>(); }
      65                 :            :   template<int M>
      66                 :            :   FixedInt<N+M> operator+( FixedInt<M>) const { return FixedInt<N+M>(); }
      67                 :            :   template<int M>
      68                 :            :   FixedInt<N-M> operator-( FixedInt<M>) const { return FixedInt<N-M>(); }
      69                 :            :   template<int M>
      70                 :            :   FixedInt<N*M> operator*( FixedInt<M>) const { return FixedInt<N*M>(); }
      71                 :            :   template<int M>
      72                 :            :   FixedInt<N/M> operator/( FixedInt<M>) const { return FixedInt<N/M>(); }
      73                 :            :   template<int M>
      74                 :            :   FixedInt<N%M> operator%( FixedInt<M>) const { return FixedInt<N%M>(); }
      75                 :            :   template<int M>
      76                 :            :   FixedInt<N|M> operator|( FixedInt<M>) const { return FixedInt<N|M>(); }
      77                 :            :   template<int M>
      78                 :            :   FixedInt<N&M> operator&( FixedInt<M>) const { return FixedInt<N&M>(); }
      79                 :            : 
      80                 :            : #if EIGEN_HAS_CXX14_VARIABLE_TEMPLATES
      81                 :            :   // Needed in C++14 to allow fix<N>():
      82                 :          4 :   FixedInt operator() () const { return *this; }
      83                 :            : 
      84                 :            :   VariableAndFixedInt<N> operator() (int val) const { return VariableAndFixedInt<N>(val); }
      85                 :            : #else
      86                 :            :   FixedInt ( FixedInt<N> (*)() ) {}
      87                 :            : #endif
      88                 :            : 
      89                 :            : #if EIGEN_HAS_CXX11
      90                 :            :   FixedInt(std::integral_constant<int,N>) {}
      91                 :            : #endif
      92                 :            : };
      93                 :            : 
      94                 :            : /** \internal
      95                 :            :   * \class VariableAndFixedInt
      96                 :            :   *
      97                 :            :   * This class embeds both a compile-time integer \c N and a runtime integer.
      98                 :            :   * Both values are supposed to be equal unless the compile-time value \c N has a special
      99                 :            :   * value meaning that the runtime-value should be used. Depending on the context, this special
     100                 :            :   * value can be either Eigen::Dynamic (for positive quantities) or Eigen::DynamicIndex (for
     101                 :            :   * quantities that can be negative).
     102                 :            :   *
     103                 :            :   * It is the return-type of the function Eigen::fix<N>(int), and most of the time this is the only
     104                 :            :   * way it is used. It is strongly discouraged to directly deal with instances of VariableAndFixedInt.
     105                 :            :   * Indeed, in order to write generic code, it is the responsibility of the callee to properly convert
     106                 :            :   * it to either a true compile-time quantity (i.e. a FixedInt<N>), or to a runtime quantity (e.g., an Index)
     107                 :            :   * using the following generic helper:
     108                 :            :   * \code
     109                 :            :   * internal::cleanup_index_type<T>::type
     110                 :            :   * internal::cleanup_index_type<T,DynamicKey>::type
     111                 :            :   * \endcode
     112                 :            :   * where T can be a template instantiation of VariableAndFixedInt or numerous other integer-like representations.
     113                 :            :   * \c DynamicKey is either Dynamic (default) or DynamicIndex and used to identify true compile-time values.
     114                 :            :   *
     115                 :            :   * For convenience, you can also extract the compile-time value \c N using the following helper:
     116                 :            :   * \code
     117                 :            :   * internal::get_fixed_value<T,DefaultVal>::value
     118                 :            :   * \endcode
     119                 :            :   * 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).
     120                 :            :   *
     121                 :            :   * \sa fix<N>(int), class FixedInt
     122                 :            :   */
     123                 :            : template<int N> class VariableAndFixedInt
     124                 :            : {
     125                 :            : public:
     126                 :            :   static const int value = N;
     127                 :            :   operator int() const { return m_value; }
     128                 :            :   VariableAndFixedInt(int val) { m_value = val; }
     129                 :            : protected:
     130                 :            :   int m_value;
     131                 :            : };
     132                 :            : 
     133                 :            : template<typename T, int Default=Dynamic> struct get_fixed_value {
     134                 :            :   static const int value = Default;
     135                 :            : };
     136                 :            : 
     137                 :            : template<int N,int Default> struct get_fixed_value<FixedInt<N>,Default> {
     138                 :            :   static const int value = N;
     139                 :            : };
     140                 :            : 
     141                 :            : #if !EIGEN_HAS_CXX14
     142                 :            : template<int N,int Default> struct get_fixed_value<FixedInt<N> (*)(),Default> {
     143                 :            :   static const int value = N;
     144                 :            : };
     145                 :            : #endif
     146                 :            : 
     147                 :            : template<int N,int Default> struct get_fixed_value<VariableAndFixedInt<N>,Default> {
     148                 :            :   static const int value = N ;
     149                 :            : };
     150                 :            : 
     151                 :            : template<typename T, int N, int Default>
     152                 :            : struct get_fixed_value<variable_if_dynamic<T,N>,Default> {
     153                 :            :   static const int value = N;
     154                 :            : };
     155                 :            : 
     156                 :        612 : template<typename T> EIGEN_DEVICE_FUNC Index get_runtime_value(const T &x) { return x; }
     157                 :            : #if !EIGEN_HAS_CXX14
     158                 :            : template<int N> EIGEN_DEVICE_FUNC Index get_runtime_value(FixedInt<N> (*)()) { return N; }
     159                 :            : #endif
     160                 :            : 
     161                 :            : // Cleanup integer/FixedInt/VariableAndFixedInt/etc types:
     162                 :            : 
     163                 :            : // By default, no cleanup:
     164                 :            : template<typename T, int DynamicKey=Dynamic, typename EnableIf=void> struct cleanup_index_type { typedef T type; };
     165                 :            : 
     166                 :            : // Convert any integral type (e.g., short, int, unsigned int, etc.) to Eigen::Index
     167                 :            : template<typename T, int DynamicKey> struct cleanup_index_type<T,DynamicKey,typename internal::enable_if<internal::is_integral<T>::value>::type> { typedef Index type; };
     168                 :            : 
     169                 :            : #if !EIGEN_HAS_CXX14
     170                 :            : // In c++98/c++11, fix<N> is a pointer to function that we better cleanup to a true FixedInt<N>:
     171                 :            : template<int N, int DynamicKey> struct cleanup_index_type<FixedInt<N> (*)(), DynamicKey> { typedef FixedInt<N> type; };
     172                 :            : #endif
     173                 :            : 
     174                 :            : // If VariableAndFixedInt does not match DynamicKey, then we turn it to a pure compile-time value:
     175                 :            : template<int N, int DynamicKey> struct cleanup_index_type<VariableAndFixedInt<N>, DynamicKey> { typedef FixedInt<N> type; };
     176                 :            : // If VariableAndFixedInt matches DynamicKey, then we turn it to a pure runtime-value (aka Index):
     177                 :            : template<int DynamicKey> struct cleanup_index_type<VariableAndFixedInt<DynamicKey>, DynamicKey> { typedef Index type; };
     178                 :            : 
     179                 :            : #if EIGEN_HAS_CXX11
     180                 :            : template<int N, int DynamicKey> struct cleanup_index_type<std::integral_constant<int,N>, DynamicKey> { typedef FixedInt<N> type; };
     181                 :            : #endif
     182                 :            : 
     183                 :            : } // end namespace internal
     184                 :            : 
     185                 :            : #ifndef EIGEN_PARSED_BY_DOXYGEN
     186                 :            : 
     187                 :            : #if EIGEN_HAS_CXX14_VARIABLE_TEMPLATES
     188                 :            : template<int N>
     189                 :            : static const internal::FixedInt<N> fix{};
     190                 :            : #else
     191                 :            : template<int N>
     192                 :            : inline internal::FixedInt<N> fix() { return internal::FixedInt<N>(); }
     193                 :            : 
     194                 :            : // The generic typename T is mandatory. Otherwise, a code like fix<N> could refer to either the function above or this next overload.
     195                 :            : // This way a code like fix<N> can only refer to the previous function.
     196                 :            : template<int N,typename T>
     197                 :            : inline internal::VariableAndFixedInt<N> fix(T val) { return internal::VariableAndFixedInt<N>(internal::convert_index<int>(val)); }
     198                 :            : #endif
     199                 :            : 
     200                 :            : #else // EIGEN_PARSED_BY_DOXYGEN
     201                 :            : 
     202                 :            : /** \var fix<N>()
     203                 :            :   * \ingroup Core_Module
     204                 :            :   *
     205                 :            :   * This \em identifier permits to construct an object embedding a compile-time integer \c N.
     206                 :            :   *
     207                 :            :   * \tparam N the compile-time integer value
     208                 :            :   *
     209                 :            :   * It is typically used in conjunction with the Eigen::seq and Eigen::seqN functions to pass compile-time values to them:
     210                 :            :   * \code
     211                 :            :   * seqN(10,fix<4>,fix<-3>)   // <=> [10 7 4 1]
     212                 :            :   * \endcode
     213                 :            :   *
     214                 :            :   * See also the function fix(int) to pass both a compile-time and runtime value.
     215                 :            :   *
     216                 :            :   * In c++14, it is implemented as:
     217                 :            :   * \code
     218                 :            :   * template<int N> static const internal::FixedInt<N> fix{};
     219                 :            :   * \endcode
     220                 :            :   * where internal::FixedInt<N> is an internal template class similar to
     221                 :            :   * <a href="http://en.cppreference.com/w/cpp/types/integral_constant">\c std::integral_constant </a><tt> <int,N> </tt>
     222                 :            :   * Here, \c fix<N> is thus an object of type \c internal::FixedInt<N>.
     223                 :            :   *
     224                 :            :   * In c++98/11, it is implemented as a function:
     225                 :            :   * \code
     226                 :            :   * template<int N> inline internal::FixedInt<N> fix();
     227                 :            :   * \endcode
     228                 :            :   * Here internal::FixedInt<N> is thus a pointer to function.
     229                 :            :   *
     230                 :            :   * 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.
     231                 :            :   *
     232                 :            :   * \sa fix<N>(int), seq, seqN
     233                 :            :   */
     234                 :            : template<int N>
     235                 :            : static const auto fix();
     236                 :            : 
     237                 :            : /** \fn fix<N>(int)
     238                 :            :   * \ingroup Core_Module
     239                 :            :   *
     240                 :            :   * This function returns an object embedding both a compile-time integer \c N, and a fallback runtime value \a val.
     241                 :            :   *
     242                 :            :   * \tparam N the compile-time integer value
     243                 :            :   * \param  val the fallback runtime integer value
     244                 :            :   *
     245                 :            :   * This function is a more general version of the \ref fix identifier/function that can be used in template code
     246                 :            :   * where the compile-time value could turn out to actually mean "undefined at compile-time". For positive integers
     247                 :            :   * such as a size or a dimension, this case is identified by Eigen::Dynamic, whereas runtime signed integers
     248                 :            :   * (e.g., an increment/stride) are identified as Eigen::DynamicIndex. In such a case, the runtime value \a val
     249                 :            :   * will be used as a fallback.
     250                 :            :   *
     251                 :            :   * A typical use case would be:
     252                 :            :   * \code
     253                 :            :   * template<typename Derived> void foo(const MatrixBase<Derived> &mat) {
     254                 :            :   *   const int N = Derived::RowsAtCompileTime==Dynamic ? Dynamic : Derived::RowsAtCompileTime/2;
     255                 :            :   *   const int n = mat.rows()/2;
     256                 :            :   *   ... mat( seqN(0,fix<N>(n) ) ...;
     257                 :            :   * }
     258                 :            :   * \endcode
     259                 :            :   * In this example, the function Eigen::seqN knows that the second argument is expected to be a size.
     260                 :            :   * 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.
     261                 :            :   * 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>.
     262                 :            :   *
     263                 :            :   * \sa fix, seqN, class ArithmeticSequence
     264                 :            :   */
     265                 :            : template<int N>
     266                 :            : static const auto fix(int val);
     267                 :            : 
     268                 :            : #endif // EIGEN_PARSED_BY_DOXYGEN
     269                 :            : 
     270                 :            : } // end namespace Eigen
     271                 :            : 
     272                 :            : #endif // EIGEN_INTEGRAL_CONSTANT_H

Generated by: LCOV version 1.0