1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_XPRHELPER_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_XPRHELPER_H
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// just a workaround because GCC seems to not really like empty structs
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// FIXME: gcc 4.3 generates bad code when strict-aliasing is enabled
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// so currently we simply disable this optimization for gcc 4.3
172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#if EIGEN_COMP_GNUC && !EIGEN_GNUC_AT(4,3)
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  #define EIGEN_EMPTY_STRUCT_CTOR(X) \
192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \
202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X(const X& ) {}
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#else
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  #define EIGEN_EMPTY_STRUCT_CTOR(X)
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename IndexDest, typename IndexSrc>
302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_DEVICE_FUNC
312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wanginline IndexDest convert_index(const IndexSrc& idx) {
322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away:
332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type");
342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return IndexDest(idx);
352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// promote_scalar_arg is an helper used in operation between an expression and a scalar, like:
392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang//    expression * scalar
402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Its role is to determine how the type T of the scalar operand should be promoted given the scalar type ExprScalar of the given expression.
412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// The IsSupported template parameter must be provided by the caller as: internal::has_ReturnType<ScalarBinaryOpTraits<ExprScalar,T,op> >::value using the proper order for ExprScalar and T.
422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Then the logic is as follows:
432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang//  - if the operation is natively supported as defined by IsSupported, then the scalar type is not promoted, and T is returned.
442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang//  - otherwise, NumTraits<ExprScalar>::Literal is returned if T is implicitly convertible to NumTraits<ExprScalar>::Literal AND that this does not imply a float to integer conversion.
452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang//  - otherwise, ExprScalar is returned if T is implicitly convertible to ExprScalar AND that this does not imply a float to integer conversion.
462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang//  - In all other cases, the promoted type is not defined, and the respective operation is thus invalid and not available (SFINAE).
472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename ExprScalar,typename T, bool IsSupported>
482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg;
492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T>
512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg<S,T,true>
522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef T type;
542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Recursively check safe conversion to PromotedType, and then ExprScalar if they are different.
572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename ExprScalar,typename T,typename PromotedType,
582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  bool ConvertibleToLiteral = internal::is_convertible<T,PromotedType>::value,
592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  bool IsSafe = NumTraits<T>::IsInteger || !NumTraits<PromotedType>::IsInteger>
602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported;
612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Start recursion with NumTraits<ExprScalar>::Literal
632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T>
642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg<S,T,false> : promote_scalar_arg_unsupported<S,T,typename NumTraits<S>::Literal> {};
652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// We found a match!
672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T, typename PromotedType>
682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported<S,T,PromotedType,true,true>
692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef PromotedType type;
712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// No match, but no real-to-integer issues, and ExprScalar and current PromotedType are different,
742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// so let's try to promote to ExprScalar
752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename ExprScalar,typename T, typename PromotedType>
762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported<ExprScalar,T,PromotedType,false,true>
772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang   : promote_scalar_arg_unsupported<ExprScalar,T,ExprScalar>
782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{};
792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Unsafe real-to-integer, let's stop.
812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T, typename PromotedType, bool ConvertibleToLiteral>
822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported<S,T,PromotedType,ConvertibleToLiteral,false> {};
832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// T is not even convertible to ExprScalar, let's stop.
852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S,typename T>
862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct promote_scalar_arg_unsupported<S,T,S,false,true> {};
872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//classes inheriting no_assignment_operator don't generate a default operator=.
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass no_assignment_operator
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  private:
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    no_assignment_operator& operator=(const no_assignment_operator&);
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal return the index type with the largest number of bits */
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename I1, typename I2>
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct promote_index_type
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type;
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal If the template parameter Value is Dynamic, this class is just a wrapper around a T variable that
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * can be accessed using value() and setValue().
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * Otherwise, this class is an empty structure and value() just returns the template parameter Value.
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, int Value> class variable_if_dynamic
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> class variable_if_dynamic<T, Dynamic>
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    T m_value;
1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC variable_if_dynamic() { eigen_assert(false); }
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamic(T value) : m_value(value) {}
1212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T value() const { return m_value; }
1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez/** \internal like variable_if_dynamic but for DynamicIndex
1267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  */
1277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename T, int Value> class variable_if_dynamicindex
1287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
1297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  public:
1307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T value() { return T(Value); }
1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T) {}
1347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
1357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename T> class variable_if_dynamicindex<T, DynamicIndex>
1377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{
1387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    T m_value;
1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(false); }
1407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  public:
1412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit variable_if_dynamicindex(T value) : m_value(value) {}
1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC T EIGEN_STRONG_INLINE value() const { return m_value; }
1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void setValue(T value) { m_value = value; }
1447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
1457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct functor_traits
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Cost = 10,
1517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    PacketAccess = false,
1527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    IsRepeatable = false
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct packet_traits;
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct unpacket_traits
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef T type;
1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef T half;
1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum
1632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  {
1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    size = 1,
1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    alignment = 1
1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  };
1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int Size, typename PacketType,
1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang         bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct find_best_packet_helper;
1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate< int Size, typename PacketType>
1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct find_best_packet_helper<Size,PacketType,true>
1752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef PacketType type;
1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int Size, typename PacketType>
1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct find_best_packet_helper<Size,PacketType,false>
1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename find_best_packet_helper<Size,typename unpacket_traits<PacketType>::half>::type type;
1832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int Size>
1862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct find_best_packet
1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename find_best_packet_helper<Size,typename packet_traits<T>::type>::type type;
1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
1912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#if EIGEN_MAX_STATIC_ALIGN_BYTES>0
1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int ArrayBytes, int AlignmentBytes,
1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang         bool Match     =  bool((ArrayBytes%AlignmentBytes)==0),
1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang         bool TryHalf   =  bool(EIGEN_MIN_ALIGN_BYTES<AlignmentBytes) >
1952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct compute_default_alignment_helper
1962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
1972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = 0 };
1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int ArrayBytes, int AlignmentBytes, bool TryHalf>
2012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf> // Match
2022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = AlignmentBytes };
2042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int ArrayBytes, int AlignmentBytes>
2072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true> // Try-half
2082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // current packet too large, try with an half-packet
2102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value };
2112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#else
2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// If static alignment is disabled, no need to bother.
2142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// This also avoids a division by zero in "bool Match =  bool((ArrayBytes%AlignmentBytes)==0)"
2152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int ArrayBytes, int AlignmentBytes>
2162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct compute_default_alignment_helper
2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = 0 };
2192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif
2212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int Size> struct compute_default_alignment {
2232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = compute_default_alignment_helper<Size*sizeof(T),EIGEN_MAX_STATIC_ALIGN_BYTES>::value };
2242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
2262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct compute_default_alignment<T,Dynamic> {
2272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = EIGEN_MAX_ALIGN_BYTES };
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, int _Rows, int _Cols,
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         int _Options = AutoAlign |
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                          ( (_Rows==1 && _Cols!=1) ? RowMajor
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                          : (_Cols==1 && _Rows!=1) ? ColMajor
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                          : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         int _MaxRows = _Rows,
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         int _MaxCols = _Cols
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath> class make_proper_matrix_type
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      IsColVector = _Cols==1 && _Rows!=1,
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      IsRowVector = _Rows==1 && _Cols!=1,
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Options = IsColVector ? (_Options | ColMajor) & ~RowMajor
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : IsRowVector ? (_Options | RowMajor) & ~ColMajor
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : _Options
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Matrix<_Scalar, _Rows, _Cols, Options, _MaxRows, _MaxCols> type;
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass compute_matrix_flags
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
2532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    enum { row_major_bit = Options&RowMajor ? RowMajorBit : 0 };
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
2552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // FIXME currently we still have to handle DirectAccessBit at the expression level to handle DenseCoeffsBase<>
2562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // and then propagate this information to the evaluator's flags.
2572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    // However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
2582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int _Rows, int _Cols> struct size_at_compile_time
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename XprType> struct size_of_xpr_at_compile_time
2672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { ret = size_at_compile_time<traits<XprType>::RowsAtCompileTime,traits<XprType>::ColsAtCompileTime>::ret };
2692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * whereas eval is a const reference in the case of a matrix
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
2762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct plain_matrix_type<T,Dense>
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
2792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, traits<T>::Flags>::type type;
2802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
2812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct plain_matrix_type<T,DiagonalShape>
2822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
2832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename T::PlainObject type;
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int Flags> struct plain_matrix_type_dense<T,MatrixXpr,Flags>
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<typename traits<T>::Scalar,
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                traits<T>::RowsAtCompileTime,
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                traits<T>::ColsAtCompileTime,
2912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                traits<T>::MaxRowsAtCompileTime,
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                traits<T>::MaxColsAtCompileTime
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          > type;
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int Flags> struct plain_matrix_type_dense<T,ArrayXpr,Flags>
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Array<typename traits<T>::Scalar,
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                traits<T>::RowsAtCompileTime,
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                traits<T>::ColsAtCompileTime,
3022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                AutoAlign | (Flags&RowMajorBit ? RowMajor : ColMajor),
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                traits<T>::MaxRowsAtCompileTime,
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                traits<T>::MaxColsAtCompileTime
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          > type;
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* eval : the return type of eval(). For matrices, this is just a const reference
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * in order to avoid a useless copy
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T, typename StorageKind = typename traits<T>::StorageKind> struct eval;
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct eval<T,Dense>
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename plain_matrix_type<T>::type type;
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   typedef typename T::PlainObject type;
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//   typedef T::Matrix<typename traits<T>::Scalar,
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                 traits<T>::RowsAtCompileTime,
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                 traits<T>::ColsAtCompileTime,
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                 AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                 traits<T>::MaxRowsAtCompileTime,
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//                 traits<T>::MaxColsAtCompileTime
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//           > type;
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
3272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct eval<T,DiagonalShape>
3282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
3292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename plain_matrix_type<T>::type type;
3302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
3312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for matrices, no need to evaluate, just use a const reference to avoid a useless copy
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef const Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef const Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& type;
343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
3462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/* similar to plain_matrix_type, but using the evaluator's Flags */
3472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_object_eval;
3482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
3492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T>
3502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct plain_object_eval<T,Dense>
3512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
3522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename plain_matrix_type_dense<T,typename traits<T>::XprKind, evaluator<T>::Flags>::type type;
3532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
3542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */
358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct plain_matrix_type_column_major
359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { Rows = traits<T>::RowsAtCompileTime,
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         Cols = traits<T>::ColsAtCompileTime,
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         MaxRows = traits<T>::MaxRowsAtCompileTime,
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         MaxCols = traits<T>::MaxColsAtCompileTime
364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<typename traits<T>::Scalar,
366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                Rows,
367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                Cols,
368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor,
369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                MaxRows,
370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                MaxCols
371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          > type;
372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */
376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T> struct plain_matrix_type_row_major
377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { Rows = traits<T>::RowsAtCompileTime,
379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         Cols = traits<T>::ColsAtCompileTime,
380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         MaxRows = traits<T>::MaxRowsAtCompileTime,
381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         MaxCols = traits<T>::MaxColsAtCompileTime
382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<typename traits<T>::Scalar,
384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                Rows,
385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                Cols,
386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                (MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor,
387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                MaxRows,
388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                MaxCols
389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          > type;
390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal The reference selector for template expressions. The idea is that we don't
393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * need to use references for expressions since they are light weight proxy
394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * objects which should generate no copying overhead. */
395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <typename T>
396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct ref_selector
397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename conditional<
399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool(traits<T>::Flags & NestByRefBit),
400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    T const&,
401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const T
402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  >::type type;
4032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename conditional<
4052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    bool(traits<T>::Flags & NestByRefBit),
4062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    T &,
4072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    T
4082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  >::type non_const_type;
409c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
410c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
411c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal Adds the const qualifier on the value-type of T2 if and only if T1 is a const type */
412c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T1, typename T2>
413c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct transfer_constness
414c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
415c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename conditional<
416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool(internal::is_const<T1>::value),
417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename internal::add_const_on_value_type<T2>::type,
418c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    T2
419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  >::type type;
420c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
4232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// However, we still need a mechanism to detect whether an expression which is evaluated multiple time
4242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// has to be evaluated into a temporary.
4252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// That's the purpose of this new nested_eval helper:
4262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal Determines how a given expression should be nested when evaluated multiple times.
427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be
4282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * evaluated into the bigger product expression. The choice is between nesting the expression b+c as-is, or
429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * evaluating that expression b+c into a temporary variable d, and nest d so that the resulting expression is
430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * a*d. Evaluating can be beneficial for example if every coefficient access in the resulting expression causes
431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * many coefficient accesses in the nested expressions -- as is the case with matrix product for example.
432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
4332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \tparam T the type of the expression being nested.
4342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \tparam n the number of coefficient accesses in the nested expression for each coefficient access in the bigger expression.
4352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \tparam PlainObject the type of the temporary if needed.
436c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
4372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int n, typename PlainObject = typename plain_object_eval<T>::type> struct nested_eval
438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
4412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CoeffReadCost = evaluator<T>::CoeffReadCost,  // NOTE What if an evaluator evaluate itself into a tempory?
4422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                                                  //      Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1.
4432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                                                  //      This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON
4442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                                                  //      for all evaluator creating a temporary. This flag is then propagated by the parent evaluators.
4452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                                                  //      Another solution could be to count the number of temps?
4462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    NAsInteger = n == Dynamic ? HugeCost : n,
4472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CostEval   = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
4482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    CostNoEval = NAsInteger * CoeffReadCost,
4492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    Evaluate = (int(evaluator<T>::Flags) & EvalBeforeNestingBit) || (int(CostEval) < int(CostNoEval))
450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename conditional<Evaluate, PlainObject, typename ref_selector<T>::type>::type type;
453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename T>
4562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao WangEIGEN_DEVICE_FUNC
457615d816d068b4d0f5e8df601930b5f160bf7eda1Tim Murrayinline T* const_cast_ptr(const T* ptr)
458c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
459c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return const_cast<T*>(ptr);
460c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
462c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
463c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct dense_xpr_base
464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */
466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
469c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct dense_xpr_base<Derived, MatrixXpr>
470c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
471c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef MatrixBase<Derived> type;
472c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
473c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
474c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
475c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct dense_xpr_base<Derived, ArrayXpr>
476c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
477c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef ArrayBase<Derived> type;
478c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
479c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind>
4812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct generic_xpr_base;
482c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
4832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Derived, typename XprKind>
4842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct generic_xpr_base<Derived, XprKind, Dense>
485c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
4862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef typename dense_xpr_base<Derived,XprKind>::type type;
487c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
488c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
489c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename XprType, typename CastType> struct cast_return_type
490c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename XprType::Scalar CurrentScalarType;
492c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename remove_all<CastType>::type _CastType;
493c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename _CastType::Scalar NewScalarType;
494c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename conditional<is_same<CurrentScalarType,NewScalarType>::value,
495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                              const XprType&,CastType>::type type;
496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <typename A, typename B> struct promote_storage_type;
499c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
500c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <typename A> struct promote_storage_type<A,A>
501c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
502c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef A ret;
503c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
5042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A> struct promote_storage_type<A, const A>
5052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
5062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef A ret;
5072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
5082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A> struct promote_storage_type<const A, A>
5092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
5102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef A ret;
5112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
5122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal Specify the "storage kind" of applying a coefficient-wise
5142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * binary operations between two expressions of kinds A and B respectively.
5152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * The template parameter Functor permits to specialize the resulting storage kind wrt to
5162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * the functor.
5172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * The default rules are as follows:
5182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \code
5192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * A      op A      -> A
5202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * A      op dense  -> dense
5212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * dense  op B      -> dense
5222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * sparse op dense  -> sparse
5232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * dense  op sparse -> sparse
5242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \endcode
5252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
5262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, typename B, typename Functor> struct cwise_promote_storage_type;
5272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, typename Functor>                   struct cwise_promote_storage_type<A,A,Functor>                                      { typedef A      ret; };
5292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Functor>                               struct cwise_promote_storage_type<Dense,Dense,Functor>                              { typedef Dense  ret; };
5302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, typename Functor>                   struct cwise_promote_storage_type<A,Dense,Functor>                                  { typedef Dense  ret; };
5312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename B, typename Functor>                   struct cwise_promote_storage_type<Dense,B,Functor>                                  { typedef Dense  ret; };
5322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Functor>                               struct cwise_promote_storage_type<Sparse,Dense,Functor>                             { typedef Sparse ret; };
5332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename Functor>                               struct cwise_promote_storage_type<Dense,Sparse,Functor>                             { typedef Sparse ret; };
5342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename LhsKind, typename RhsKind, int LhsOrder, int RhsOrder> struct cwise_promote_storage_order {
5362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = LhsOrder };
5372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
5382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename LhsKind, int LhsOrder, int RhsOrder>   struct cwise_promote_storage_order<LhsKind,Sparse,LhsOrder,RhsOrder>                { enum { value = RhsOrder }; };
5402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename RhsKind, int LhsOrder, int RhsOrder>   struct cwise_promote_storage_order<Sparse,RhsKind,LhsOrder,RhsOrder>                { enum { value = LhsOrder }; };
5412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int Order>                                      struct cwise_promote_storage_order<Sparse,Sparse,Order,Order>                       { enum { value = Order }; };
5422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \internal Specify the "storage kind" of multiplying an expression of kind A with kind B.
5452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * The template parameter ProductTag permits to specialize the resulting storage kind wrt to
5462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * some compile-time properties of the product: GemmProduct, GemvProduct, OuterProduct, InnerProduct.
5472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * The default rules are as follows:
5482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \code
5492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *  K * K            -> K
5502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *  dense * K        -> dense
5512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *  K * dense        -> dense
5522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *  diag * K         -> K
5532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *  K * diag         -> K
5542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *  Perm * K         -> K
5552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * K * Perm          -> K
5562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \endcode
5572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
5582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, typename B, int ProductTag> struct product_promote_storage_type;
5592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, int ProductTag> struct product_promote_storage_type<A,                  A,                  ProductTag> { typedef A     ret;};
5612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag>             struct product_promote_storage_type<Dense,              Dense,              ProductTag> { typedef Dense ret;};
5622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, int ProductTag> struct product_promote_storage_type<A,                  Dense,              ProductTag> { typedef Dense ret; };
5632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename B, int ProductTag> struct product_promote_storage_type<Dense,              B,                  ProductTag> { typedef Dense ret; };
5642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, int ProductTag> struct product_promote_storage_type<A,                  DiagonalShape,      ProductTag> { typedef A ret; };
5662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename B, int ProductTag> struct product_promote_storage_type<DiagonalShape,      B,                  ProductTag> { typedef B ret; };
5672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag>             struct product_promote_storage_type<Dense,              DiagonalShape,      ProductTag> { typedef Dense ret; };
5682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag>             struct product_promote_storage_type<DiagonalShape,      Dense,              ProductTag> { typedef Dense ret; };
5692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
5702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename A, int ProductTag> struct product_promote_storage_type<A,                  PermutationStorage, ProductTag> { typedef A ret; };
5712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B,                  ProductTag> { typedef B ret; };
5722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag>             struct product_promote_storage_type<Dense,              PermutationStorage, ProductTag> { typedef Dense ret; };
5732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <int ProductTag>             struct product_promote_storage_type<PermutationStorage, Dense,              ProductTag> { typedef Dense ret; };
574c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
575c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal gives the plain matrix or array type to store a row/column/diagonal of a matrix type.
5762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \tparam Scalar optional parameter allowing to pass a different scalar type than the one of the MatrixType.
577c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
578c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
579c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct plain_row_type
580c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
581c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
582c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                 ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
583c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
584c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                 ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
585c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
586c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename conditional<
587c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
588c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MatrixRowType,
589c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ArrayRowType
590c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  >::type type;
591c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
592c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
593c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
594c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct plain_col_type
595c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
596c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
597c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
598c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
599c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
600c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
601c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename conditional<
602c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
603c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MatrixColType,
604c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ArrayColType
605c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  >::type type;
606c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
607c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
608c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
609c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct plain_diag_type
610c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
611c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
612c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
613c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
614c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Matrix<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> MatrixDiagType;
615c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef Array<Scalar, diag_size, 1, ExpressionType::PlainObject::Options & ~RowMajor, max_diag_size, 1> ArrayDiagType;
616c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
617c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename conditional<
618c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    is_same< typename traits<ExpressionType>::XprKind, MatrixXpr >::value,
619c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MatrixDiagType,
620c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ArrayDiagType
621c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  >::type type;
622c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
623c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
6242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename Expr,typename Scalar = typename Expr::Scalar>
6252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct plain_constant_type
6262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
6272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { Options = (traits<Expr>::Flags&RowMajorBit)?RowMajor:0 };
6282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef Array<Scalar,  traits<Expr>::RowsAtCompileTime,   traits<Expr>::ColsAtCompileTime,
6302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> array_type;
6312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef Matrix<Scalar,  traits<Expr>::RowsAtCompileTime,   traits<Expr>::ColsAtCompileTime,
6332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang                 Options, traits<Expr>::MaxRowsAtCompileTime,traits<Expr>::MaxColsAtCompileTime> matrix_type;
6342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef CwiseNullaryOp<scalar_constant_op<Scalar>, const typename conditional<is_same< typename traits<Expr>::XprKind, MatrixXpr >::value, matrix_type, array_type>::type > type;
6362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
6372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
638c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename ExpressionType>
639c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct is_lvalue
640c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
6412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = (!bool(is_const<ExpressionType>::value)) &&
642c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                 bool(traits<ExpressionType>::Flags & LvalueBit) };
643c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
644c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
6452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct is_diagonal
6462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ enum { ret = false }; };
6472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct is_diagonal<DiagonalBase<T> >
6492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ enum { ret = true }; };
6502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T> struct is_diagonal<DiagonalWrapper<T> >
6522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ enum { ret = true }; };
6532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
6552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{ enum { ret = true }; };
6562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename S1, typename S2> struct glue_shapes;
6582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<> struct glue_shapes<DenseShape,TriangularShape> { typedef TriangularShape type;  };
6592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T1, typename T2>
6612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangbool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if<has_direct_access<T1>::ret&&has_direct_access<T2>::ret, T1>::type * = 0)
6622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
6632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
6642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
6652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T1, typename T2>
6672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangbool is_same_dense(const T1 &, const T2 &, typename enable_if<!(has_direct_access<T1>::ret&&has_direct_access<T2>::ret), T1>::type * = 0)
6682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
6692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return false;
6702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
6712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Internal helper defining the cost of a scalar division for the type T.
6732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// The default heuristic can be specialized for each scalar type and architecture.
6742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T,bool Vectorized=false,typename EnaleIf = void>
6752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct scalar_div_cost {
6762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = 8*NumTraits<T>::MulCost };
6772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
6782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T,bool Vectorized>
6802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct scalar_div_cost<std::complex<T>, Vectorized> {
6812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  enum { value = 2*scalar_div_cost<T>::value
6822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang               + 6*NumTraits<T>::MulCost
6832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang               + 3*NumTraits<T>::AddCost
6842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  };
6852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
6862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<bool Vectorized>
6892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct scalar_div_cost<signed long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 24 }; };
6902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<bool Vectorized>
6912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct scalar_div_cost<unsigned long,Vectorized,typename conditional<sizeof(long)==8,void,false_type>::type> { enum { value = 21 }; };
6922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
6942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifdef EIGEN_DEBUG_ASSIGN
6952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstd::string demangle_traversal(int t)
6962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
6972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(t==DefaultTraversal) return "DefaultTraversal";
6982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(t==LinearTraversal) return "LinearTraversal";
6992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
7002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
7012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
7022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return "?";
7032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
7042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstd::string demangle_unrolling(int t)
7052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
7062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(t==NoUnrolling) return "NoUnrolling";
7072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(t==InnerUnrolling) return "InnerUnrolling";
7082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(t==CompleteUnrolling) return "CompleteUnrolling";
7092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return "?";
7102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
7112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstd::string demangle_flags(int f)
7122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
7132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  std::string res;
7142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(f&RowMajorBit)                 res += " | RowMajor";
7152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(f&PacketAccessBit)             res += " | Packet";
7162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(f&LinearAccessBit)             res += " | Linear";
7172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(f&LvalueBit)                   res += " | Lvalue";
7182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(f&DirectAccessBit)             res += " | Direct";
7192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(f&NestByRefBit)                res += " | NestByRef";
7202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  if(f&NoPreferredStorageOrderBit)  res += " | NoPreferredStorageOrderBit";
7212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  return res;
7232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang}
7242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif
7252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
726c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
727c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
7282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7292b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \class ScalarBinaryOpTraits
7302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \ingroup Core_Module
7312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
7322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \brief Determines whether the given binary operation of two numeric types is allowed and what the scalar return type is.
7332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
7342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * This class permits to control the scalar return type of any binary operation performed on two different scalar types through (partial) template specializations.
7352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
7362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * For instance, let \c U1, \c U2 and \c U3 be three user defined scalar types for which most operations between instances of \c U1 and \c U2 returns an \c U3.
7372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * You can let %Eigen knows that by defining:
7382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    \code
7392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename BinaryOp>
7402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    struct ScalarBinaryOpTraits<U1,U2,BinaryOp> { typedef U3 ReturnType;  };
7412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<typename BinaryOp>
7422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    struct ScalarBinaryOpTraits<U2,U1,BinaryOp> { typedef U3 ReturnType;  };
7432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    \endcode
7442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * You can then explicitly disable some particular operations to get more explicit error messages:
7452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    \code
7462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<>
7472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    struct ScalarBinaryOpTraits<U1,U2,internal::scalar_max_op<U1,U2> > {};
7482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    \endcode
7492b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * Or customize the return type for individual operation:
7502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    \code
7512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    template<>
7522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    struct ScalarBinaryOpTraits<U1,U2,internal::scalar_sum_op<U1,U2> > { typedef U1 ReturnType; };
7532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    \endcode
7542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
7552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * By default, the following generic combinations are supported:
7562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  <table class="manual">
7572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  <tr><th>ScalarA</th><th>ScalarB</th><th>BinaryOp</th><th>ReturnType</th><th>Note</th></tr>
7582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  <tr            ><td>\c T </td><td>\c T </td><td>\c * </td><td>\c T </td><td></td></tr>
7592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  <tr class="alt"><td>\c NumTraits<T>::Real </td><td>\c T </td><td>\c * </td><td>\c T </td><td>Only if \c NumTraits<T>::IsComplex </td></tr>
7602b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  <tr            ><td>\c T </td><td>\c NumTraits<T>::Real </td><td>\c * </td><td>\c T </td><td>Only if \c NumTraits<T>::IsComplex </td></tr>
7612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  </table>
7622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  *
7632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  * \sa CwiseBinaryOp
7642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  */
7652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename ScalarA, typename ScalarB, typename BinaryOp=internal::scalar_product_op<ScalarA,ScalarB> >
7662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits
7672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#ifndef EIGEN_PARSED_BY_DOXYGEN
7682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  // for backward compatibility, use the hints given by the (deprecated) internal::scalar_product_traits class.
7692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  : internal::scalar_product_traits<ScalarA,ScalarB>
7702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#endif // EIGEN_PARSED_BY_DOXYGEN
7712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{};
7722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename BinaryOp>
7742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<T,T,BinaryOp>
7752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
7762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef T ReturnType;
7772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
7782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename T, typename BinaryOp>
7802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<T, typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, BinaryOp>
7812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
7822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef T ReturnType;
7832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
7842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate <typename T, typename BinaryOp>
7852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<typename NumTraits<typename internal::enable_if<NumTraits<T>::IsComplex,T>::type>::Real, T, BinaryOp>
7862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
7872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef T ReturnType;
7882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
7892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// For Matrix * Permutation
7912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename BinaryOp>
7922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<T,void,BinaryOp>
7932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
7942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef T ReturnType;
7952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
7962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
7972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// For Permutation * Matrix
7982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename T, typename BinaryOp>
7992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<void,T,BinaryOp>
8002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
8012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef T ReturnType;
8022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
8032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// for Permutation*Permutation
8052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename BinaryOp>
8062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct ScalarBinaryOpTraits<void,void,BinaryOp>
8072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang{
8082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  typedef void ReturnType;
8092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang};
8102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
8112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// We require Lhs and Rhs to have "compatible" scalar types.
8122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
8132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
8142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// add together a float matrix and a double matrix.
8152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
8162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang  EIGEN_STATIC_ASSERT((Eigen::internal::has_ReturnType<ScalarBinaryOpTraits<LHS, RHS,BINOP> >::value), \
8172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang    YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
8182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang
819c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
820c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
821c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_XPRHELPER_H
822