Home | History | Annotate | Download | only in Core
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud (at) inria.fr>
      5 // Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      6 //
      7 // This Source Code Form is subject to the terms of the Mozilla
      8 // Public License v. 2.0. If a copy of the MPL was not distributed
      9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
     10 
     11 #ifndef EIGEN_RETURNBYVALUE_H
     12 #define EIGEN_RETURNBYVALUE_H
     13 
     14 namespace Eigen {
     15 
     16 /** \class ReturnByValue
     17   * \ingroup Core_Module
     18   *
     19   */
     20 
     21 namespace internal {
     22 
     23 template<typename Derived>
     24 struct traits<ReturnByValue<Derived> >
     25   : public traits<typename traits<Derived>::ReturnType>
     26 {
     27   enum {
     28     // We're disabling the DirectAccess because e.g. the constructor of
     29     // the Block-with-DirectAccess expression requires to have a coeffRef method.
     30     // Also, we don't want to have to implement the stride stuff.
     31     Flags = (traits<typename traits<Derived>::ReturnType>::Flags
     32              | EvalBeforeNestingBit) & ~DirectAccessBit
     33   };
     34 };
     35 
     36 /* The ReturnByValue object doesn't even have a coeff() method.
     37  * So the only way that nesting it in an expression can work, is by evaluating it into a plain matrix.
     38  * So internal::nested always gives the plain return matrix type.
     39  *
     40  * FIXME: I don't understand why we need this specialization: isn't this taken care of by the EvalBeforeNestingBit ??
     41  */
     42 template<typename Derived,int n,typename PlainObject>
     43 struct nested<ReturnByValue<Derived>, n, PlainObject>
     44 {
     45   typedef typename traits<Derived>::ReturnType type;
     46 };
     47 
     48 } // end namespace internal
     49 
     50 template<typename Derived> class ReturnByValue
     51   : internal::no_assignment_operator, public internal::dense_xpr_base< ReturnByValue<Derived> >::type
     52 {
     53   public:
     54     typedef typename internal::traits<Derived>::ReturnType ReturnType;
     55 
     56     typedef typename internal::dense_xpr_base<ReturnByValue>::type Base;
     57     EIGEN_DENSE_PUBLIC_INTERFACE(ReturnByValue)
     58 
     59     template<typename Dest>
     60     inline void evalTo(Dest& dst) const
     61     { static_cast<const Derived*>(this)->evalTo(dst); }
     62     inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
     63     inline Index cols() const { return static_cast<const Derived*>(this)->cols(); }
     64 
     65 #ifndef EIGEN_PARSED_BY_DOXYGEN
     66 #define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
     67     class Unusable{
     68       Unusable(const Unusable&) {}
     69       Unusable& operator=(const Unusable&) {return *this;}
     70     };
     71     const Unusable& coeff(Index) const { return *reinterpret_cast<const Unusable*>(this); }
     72     const Unusable& coeff(Index,Index) const { return *reinterpret_cast<const Unusable*>(this); }
     73     Unusable& coeffRef(Index) { return *reinterpret_cast<Unusable*>(this); }
     74     Unusable& coeffRef(Index,Index) { return *reinterpret_cast<Unusable*>(this); }
     75     template<int LoadMode>  Unusable& packet(Index) const;
     76     template<int LoadMode>  Unusable& packet(Index, Index) const;
     77 #endif
     78 };
     79 
     80 template<typename Derived>
     81 template<typename OtherDerived>
     82 Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
     83 {
     84   other.evalTo(derived());
     85   return derived();
     86 }
     87 
     88 template<typename Derived>
     89 template<typename OtherDerived>
     90 Derived& DenseBase<Derived>::lazyAssign(const ReturnByValue<OtherDerived>& other)
     91 {
     92   other.evalTo(derived());
     93   return derived();
     94 }
     95 
     96 
     97 } // end namespace Eigen
     98 
     99 #endif // EIGEN_RETURNBYVALUE_H
    100