ReturnByValue.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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@inria.fr>
  5. // Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@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. #ifndef EIGEN_RETURNBYVALUE_H
  11. #define EIGEN_RETURNBYVALUE_H
  12. namespace Eigen {
  13. namespace internal {
  14. template<typename Derived>
  15. struct traits<ReturnByValue<Derived> >
  16. : public traits<typename traits<Derived>::ReturnType>
  17. {
  18. enum {
  19. // We're disabling the DirectAccess because e.g. the constructor of
  20. // the Block-with-DirectAccess expression requires to have a coeffRef method.
  21. // Also, we don't want to have to implement the stride stuff.
  22. Flags = (traits<typename traits<Derived>::ReturnType>::Flags
  23. | EvalBeforeNestingBit) & ~DirectAccessBit
  24. };
  25. };
  26. /* The ReturnByValue object doesn't even have a coeff() method.
  27. * So the only way that nesting it in an expression can work, is by evaluating it into a plain matrix.
  28. * So internal::nested always gives the plain return matrix type.
  29. *
  30. * FIXME: I don't understand why we need this specialization: isn't this taken care of by the EvalBeforeNestingBit ??
  31. * Answer: EvalBeforeNestingBit should be deprecated since we have the evaluators
  32. */
  33. template<typename Derived,int n,typename PlainObject>
  34. struct nested_eval<ReturnByValue<Derived>, n, PlainObject>
  35. {
  36. typedef typename traits<Derived>::ReturnType type;
  37. };
  38. } // end namespace internal
  39. /** \class ReturnByValue
  40. * \ingroup Core_Module
  41. *
  42. */
  43. template<typename Derived> class ReturnByValue
  44. : public internal::dense_xpr_base< ReturnByValue<Derived> >::type, internal::no_assignment_operator
  45. {
  46. public:
  47. typedef typename internal::traits<Derived>::ReturnType ReturnType;
  48. typedef typename internal::dense_xpr_base<ReturnByValue>::type Base;
  49. EIGEN_DENSE_PUBLIC_INTERFACE(ReturnByValue)
  50. template<typename Dest>
  51. EIGEN_DEVICE_FUNC
  52. inline void evalTo(Dest& dst) const
  53. { static_cast<const Derived*>(this)->evalTo(dst); }
  54. EIGEN_DEVICE_FUNC inline Index rows() const { return static_cast<const Derived*>(this)->rows(); }
  55. EIGEN_DEVICE_FUNC inline Index cols() const { return static_cast<const Derived*>(this)->cols(); }
  56. #ifndef EIGEN_PARSED_BY_DOXYGEN
  57. #define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
  58. class Unusable{
  59. Unusable(const Unusable&) {}
  60. Unusable& operator=(const Unusable&) {return *this;}
  61. };
  62. const Unusable& coeff(Index) const { return *reinterpret_cast<const Unusable*>(this); }
  63. const Unusable& coeff(Index,Index) const { return *reinterpret_cast<const Unusable*>(this); }
  64. Unusable& coeffRef(Index) { return *reinterpret_cast<Unusable*>(this); }
  65. Unusable& coeffRef(Index,Index) { return *reinterpret_cast<Unusable*>(this); }
  66. #undef Unusable
  67. #endif
  68. };
  69. template<typename Derived>
  70. template<typename OtherDerived>
  71. Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
  72. {
  73. other.evalTo(derived());
  74. return derived();
  75. }
  76. namespace internal {
  77. // Expression is evaluated in a temporary; default implementation of Assignment is bypassed so that
  78. // when a ReturnByValue expression is assigned, the evaluator is not constructed.
  79. // TODO: Finalize port to new regime; ReturnByValue should not exist in the expression world
  80. template<typename Derived>
  81. struct evaluator<ReturnByValue<Derived> >
  82. : public evaluator<typename internal::traits<Derived>::ReturnType>
  83. {
  84. typedef ReturnByValue<Derived> XprType;
  85. typedef typename internal::traits<Derived>::ReturnType PlainObject;
  86. typedef evaluator<PlainObject> Base;
  87. EIGEN_DEVICE_FUNC explicit evaluator(const XprType& xpr)
  88. : m_result(xpr.rows(), xpr.cols())
  89. {
  90. ::new (static_cast<Base*>(this)) Base(m_result);
  91. xpr.evalTo(m_result);
  92. }
  93. protected:
  94. PlainObject m_result;
  95. };
  96. } // end namespace internal
  97. } // end namespace Eigen
  98. #endif // EIGEN_RETURNBYVALUE_H