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) 2006-2008 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      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 #ifndef EIGEN_SWAP_H
     11 #define EIGEN_SWAP_H
     12 
     13 namespace Eigen {
     14 
     15 /** \class SwapWrapper
     16   * \ingroup Core_Module
     17   *
     18   * \internal
     19   *
     20   * \brief Internal helper class for swapping two expressions
     21   */
     22 namespace internal {
     23 template<typename ExpressionType>
     24 struct traits<SwapWrapper<ExpressionType> > : traits<ExpressionType> {};
     25 }
     26 
     27 template<typename ExpressionType> class SwapWrapper
     28   : public internal::dense_xpr_base<SwapWrapper<ExpressionType> >::type
     29 {
     30   public:
     31 
     32     typedef typename internal::dense_xpr_base<SwapWrapper>::type Base;
     33     EIGEN_DENSE_PUBLIC_INTERFACE(SwapWrapper)
     34     typedef typename internal::packet_traits<Scalar>::type Packet;
     35 
     36     inline SwapWrapper(ExpressionType& xpr) : m_expression(xpr) {}
     37 
     38     inline Index rows() const { return m_expression.rows(); }
     39     inline Index cols() const { return m_expression.cols(); }
     40     inline Index outerStride() const { return m_expression.outerStride(); }
     41     inline Index innerStride() const { return m_expression.innerStride(); }
     42 
     43     typedef typename internal::conditional<
     44                        internal::is_lvalue<ExpressionType>::value,
     45                        Scalar,
     46                        const Scalar
     47                      >::type ScalarWithConstIfNotLvalue;
     48 
     49     inline ScalarWithConstIfNotLvalue* data() { return m_expression.data(); }
     50     inline const Scalar* data() const { return m_expression.data(); }
     51 
     52     inline Scalar& coeffRef(Index rowId, Index colId)
     53     {
     54       return m_expression.const_cast_derived().coeffRef(rowId, colId);
     55     }
     56 
     57     inline Scalar& coeffRef(Index index)
     58     {
     59       return m_expression.const_cast_derived().coeffRef(index);
     60     }
     61 
     62     inline Scalar& coeffRef(Index rowId, Index colId) const
     63     {
     64       return m_expression.coeffRef(rowId, colId);
     65     }
     66 
     67     inline Scalar& coeffRef(Index index) const
     68     {
     69       return m_expression.coeffRef(index);
     70     }
     71 
     72     template<typename OtherDerived>
     73     void copyCoeff(Index rowId, Index colId, const DenseBase<OtherDerived>& other)
     74     {
     75       OtherDerived& _other = other.const_cast_derived();
     76       eigen_internal_assert(rowId >= 0 && rowId < rows()
     77                          && colId >= 0 && colId < cols());
     78       Scalar tmp = m_expression.coeff(rowId, colId);
     79       m_expression.coeffRef(rowId, colId) = _other.coeff(rowId, colId);
     80       _other.coeffRef(rowId, colId) = tmp;
     81     }
     82 
     83     template<typename OtherDerived>
     84     void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
     85     {
     86       OtherDerived& _other = other.const_cast_derived();
     87       eigen_internal_assert(index >= 0 && index < m_expression.size());
     88       Scalar tmp = m_expression.coeff(index);
     89       m_expression.coeffRef(index) = _other.coeff(index);
     90       _other.coeffRef(index) = tmp;
     91     }
     92 
     93     template<typename OtherDerived, int StoreMode, int LoadMode>
     94     void copyPacket(Index rowId, Index colId, const DenseBase<OtherDerived>& other)
     95     {
     96       OtherDerived& _other = other.const_cast_derived();
     97       eigen_internal_assert(rowId >= 0 && rowId < rows()
     98                         && colId >= 0 && colId < cols());
     99       Packet tmp = m_expression.template packet<StoreMode>(rowId, colId);
    100       m_expression.template writePacket<StoreMode>(rowId, colId,
    101         _other.template packet<LoadMode>(rowId, colId)
    102       );
    103       _other.template writePacket<LoadMode>(rowId, colId, tmp);
    104     }
    105 
    106     template<typename OtherDerived, int StoreMode, int LoadMode>
    107     void copyPacket(Index index, const DenseBase<OtherDerived>& other)
    108     {
    109       OtherDerived& _other = other.const_cast_derived();
    110       eigen_internal_assert(index >= 0 && index < m_expression.size());
    111       Packet tmp = m_expression.template packet<StoreMode>(index);
    112       m_expression.template writePacket<StoreMode>(index,
    113         _other.template packet<LoadMode>(index)
    114       );
    115       _other.template writePacket<LoadMode>(index, tmp);
    116     }
    117 
    118     ExpressionType& expression() const { return m_expression; }
    119 
    120   protected:
    121     ExpressionType& m_expression;
    122 };
    123 
    124 } // end namespace Eigen
    125 
    126 #endif // EIGEN_SWAP_H
    127