cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

IntegralConstant.h (10949B)


      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   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   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 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