aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Core/Array.h15
-rw-r--r--Eigen/src/Core/DenseStorage.h226
-rw-r--r--Eigen/src/Core/Matrix.h15
-rw-r--r--Eigen/src/Core/PlainObjectBase.h14
-rw-r--r--Eigen/src/Core/util/Macros.h13
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/rvalue_types.cpp73
7 files changed, 277 insertions, 80 deletions
diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h
index 497efff66..3d0350834 100644
--- a/Eigen/src/Core/Array.h
+++ b/Eigen/src/Core/Array.h
@@ -124,6 +124,21 @@ class Array
}
#endif
+#ifdef EIGEN_HAVE_RVALUE_REFERENCES
+ Array(Array&& other)
+ : Base(std::move(other))
+ {
+ Base::_check_template_params();
+ if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic)
+ Base::_set_noalias(other);
+ }
+ Array& operator=(Array&& other)
+ {
+ other.swap(*this);
+ return *this;
+ }
+#endif
+
/** Constructs a vector or row-vector with given dimension. \only_for_vectors
*
* Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
diff --git a/Eigen/src/Core/DenseStorage.h b/Eigen/src/Core/DenseStorage.h
index 3e7f9c1b7..ae86b4d11 100644
--- a/Eigen/src/Core/DenseStorage.h
+++ b/Eigen/src/Core/DenseStorage.h
@@ -114,33 +114,37 @@ template<typename T, int Size, int _Rows, int _Cols, int _Options> class DenseSt
{
internal::plain_array<T,Size,_Options> m_data;
public:
- inline DenseStorage() {}
- inline DenseStorage(internal::constructor_without_unaligned_array_assert)
+ DenseStorage() {}
+ DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()) {}
- inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
- inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
- static inline DenseIndex rows(void) {return _Rows;}
- static inline DenseIndex cols(void) {return _Cols;}
- inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
- inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
- inline const T *data() const { return m_data.array; }
- inline T *data() { return m_data.array; }
+ DenseStorage(const DenseStorage& other) : m_data(other.m_data) {}
+ DenseStorage& operator=(DenseStorage other) { other.swap(*this); return *this; }
+ DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
+ void swap(DenseStorage& other) { std::swap(m_data,other.m_data); }
+ static DenseIndex rows(void) {return _Rows;}
+ static DenseIndex cols(void) {return _Cols;}
+ void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
+ void resize(DenseIndex,DenseIndex,DenseIndex) {}
+ const T *data() const { return m_data.array; }
+ T *data() { return m_data.array; }
};
// null matrix
template<typename T, int _Rows, int _Cols, int _Options> class DenseStorage<T, 0, _Rows, _Cols, _Options>
{
public:
- inline DenseStorage() {}
- inline DenseStorage(internal::constructor_without_unaligned_array_assert) {}
- inline DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
- inline void swap(DenseStorage& ) {}
- static inline DenseIndex rows(void) {return _Rows;}
- static inline DenseIndex cols(void) {return _Cols;}
- inline void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
- inline void resize(DenseIndex,DenseIndex,DenseIndex) {}
- inline const T *data() const { return 0; }
- inline T *data() { return 0; }
+ DenseStorage() {}
+ DenseStorage(internal::constructor_without_unaligned_array_assert) {}
+ DenseStorage(const DenseStorage&) {}
+ DenseStorage& operator=(const DenseStorage&) { return *this; }
+ DenseStorage(DenseIndex,DenseIndex,DenseIndex) {}
+ void swap(DenseStorage& ) {}
+ static DenseIndex rows(void) {return _Rows;}
+ static DenseIndex cols(void) {return _Cols;}
+ void conservativeResize(DenseIndex,DenseIndex,DenseIndex) {}
+ void resize(DenseIndex,DenseIndex,DenseIndex) {}
+ const T *data() const { return 0; }
+ T *data() { return 0; }
};
// more specializations for null matrices; these are necessary to resolve ambiguities
@@ -160,18 +164,20 @@ template<typename T, int Size, int _Options> class DenseStorage<T, Size, Dynamic
DenseIndex m_rows;
DenseIndex m_cols;
public:
- inline DenseStorage() : m_rows(0), m_cols(0) {}
- inline DenseStorage(internal::constructor_without_unaligned_array_assert)
+ DenseStorage() : m_rows(0), m_cols(0) {}
+ DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {}
- inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {}
- inline void swap(DenseStorage& other)
+ DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows), m_cols(other.m_cols) {}
+ DenseStorage& operator=(DenseStorage other) { other.swap(*this); return *this; }
+ DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) : m_rows(nbRows), m_cols(nbCols) {}
+ void swap(DenseStorage& other)
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
- inline DenseIndex rows() const {return m_rows;}
- inline DenseIndex cols() const {return m_cols;}
- inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
- inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
- inline const T *data() const { return m_data.array; }
- inline T *data() { return m_data.array; }
+ DenseIndex rows() const {return m_rows;}
+ DenseIndex cols() const {return m_cols;}
+ void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
+ void resize(DenseIndex, DenseIndex nbRows, DenseIndex nbCols) { m_rows = nbRows; m_cols = nbCols; }
+ const T *data() const { return m_data.array; }
+ T *data() { return m_data.array; }
};
// dynamic-size matrix with fixed-size storage and fixed width
@@ -180,17 +186,19 @@ template<typename T, int Size, int _Cols, int _Options> class DenseStorage<T, Si
internal::plain_array<T,Size,_Options> m_data;
DenseIndex m_rows;
public:
- inline DenseStorage() : m_rows(0) {}
- inline DenseStorage(internal::constructor_without_unaligned_array_assert)
+ DenseStorage() : m_rows(0) {}
+ DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_rows(0) {}
- inline DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {}
- inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
- inline DenseIndex rows(void) const {return m_rows;}
- inline DenseIndex cols(void) const {return _Cols;}
- inline void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
- inline void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
- inline const T *data() const { return m_data.array; }
- inline T *data() { return m_data.array; }
+ DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_rows(other.m_rows) {}
+ DenseStorage& operator=(DenseStorage other) { other.swap(*this); return *this; }
+ DenseStorage(DenseIndex, DenseIndex nbRows, DenseIndex) : m_rows(nbRows) {}
+ void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
+ DenseIndex rows(void) const {return m_rows;}
+ DenseIndex cols(void) const {return _Cols;}
+ void conservativeResize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
+ void resize(DenseIndex, DenseIndex nbRows, DenseIndex) { m_rows = nbRows; }
+ const T *data() const { return m_data.array; }
+ T *data() { return m_data.array; }
};
// dynamic-size matrix with fixed-size storage and fixed height
@@ -199,17 +207,19 @@ template<typename T, int Size, int _Rows, int _Options> class DenseStorage<T, Si
internal::plain_array<T,Size,_Options> m_data;
DenseIndex m_cols;
public:
- inline DenseStorage() : m_cols(0) {}
- inline DenseStorage(internal::constructor_without_unaligned_array_assert)
+ DenseStorage() : m_cols(0) {}
+ DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(internal::constructor_without_unaligned_array_assert()), m_cols(0) {}
- inline DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {}
- inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
- inline DenseIndex rows(void) const {return _Rows;}
- inline DenseIndex cols(void) const {return m_cols;}
- inline void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
- inline void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
- inline const T *data() const { return m_data.array; }
- inline T *data() { return m_data.array; }
+ DenseStorage(const DenseStorage& other) : m_data(other.m_data), m_cols(other.m_cols) {}
+ DenseStorage& operator=(DenseStorage other) { other.swap(*this); return *this; }
+ DenseStorage(DenseIndex, DenseIndex, DenseIndex nbCols) : m_cols(nbCols) {}
+ void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
+ DenseIndex rows(void) const {return _Rows;}
+ DenseIndex cols(void) const {return m_cols;}
+ void conservativeResize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
+ void resize(DenseIndex, DenseIndex, DenseIndex nbCols) { m_cols = nbCols; }
+ const T *data() const { return m_data.array; }
+ T *data() { return m_data.array; }
};
// purely dynamic matrix.
@@ -219,18 +229,35 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
DenseIndex m_rows;
DenseIndex m_cols;
public:
- inline DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
- inline DenseStorage(internal::constructor_without_unaligned_array_assert)
+ DenseStorage() : m_data(0), m_rows(0), m_cols(0) {}
+ DenseStorage(internal::constructor_without_unaligned_array_assert)
: m_data(0), m_rows(0), m_cols(0) {}
- inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
+ DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
: m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows), m_cols(nbCols)
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
- inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
- inline void swap(DenseStorage& other)
+#ifdef EIGEN_HAVE_RVALUE_REFERENCES
+ DenseStorage(DenseStorage&& other)
+ : m_data(std::move(other.m_data))
+ , m_rows(std::move(other.m_rows))
+ , m_cols(std::move(other.m_cols))
+ {
+ other.m_data = nullptr;
+ }
+ DenseStorage& operator=(DenseStorage&& other)
+ {
+ using std::swap;
+ swap(m_data, other.m_data);
+ swap(m_rows, other.m_rows);
+ swap(m_cols, other.m_cols);
+ return *this;
+ }
+#endif
+ ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
+ void swap(DenseStorage& other)
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
- inline DenseIndex rows(void) const {return m_rows;}
- inline DenseIndex cols(void) const {return m_cols;}
- inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
+ DenseIndex rows(void) const {return m_rows;}
+ DenseIndex cols(void) const {return m_cols;}
+ void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex nbCols)
{
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*m_cols);
m_rows = nbRows;
@@ -250,8 +277,11 @@ template<typename T, int _Options> class DenseStorage<T, Dynamic, Dynamic, Dynam
m_rows = nbRows;
m_cols = nbCols;
}
- inline const T *data() const { return m_data; }
- inline T *data() { return m_data; }
+ const T *data() const { return m_data; }
+ T *data() { return m_data; }
+ private:
+ DenseStorage(const DenseStorage&);
+ DenseStorage& operator=(const DenseStorage&);
};
// matrix with dynamic width and fixed height (so that matrix has dynamic size).
@@ -260,15 +290,30 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
T *m_data;
DenseIndex m_cols;
public:
- inline DenseStorage() : m_data(0), m_cols(0) {}
- inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
- inline DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(nbCols)
+ DenseStorage() : m_data(0), m_cols(0) {}
+ DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
+ DenseStorage(DenseIndex size, DenseIndex, DenseIndex nbCols) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_cols(nbCols)
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
- inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
- inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
- static inline DenseIndex rows(void) {return _Rows;}
- inline DenseIndex cols(void) const {return m_cols;}
- inline void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols)
+#ifdef EIGEN_HAVE_RVALUE_REFERENCES
+ DenseStorage(DenseStorage&& other)
+ : m_data(std::move(other.m_data))
+ , m_cols(std::move(other.m_cols))
+ {
+ other.m_data = nullptr;
+ }
+ DenseStorage& operator=(DenseStorage&& other)
+ {
+ using std::swap;
+ swap(m_data, other.m_data);
+ swap(m_cols, other.m_cols);
+ return *this;
+ }
+#endif
+ ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
+ void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
+ static DenseIndex rows(void) {return _Rows;}
+ DenseIndex cols(void) const {return m_cols;}
+ void conservativeResize(DenseIndex size, DenseIndex, DenseIndex nbCols)
{
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, _Rows*m_cols);
m_cols = nbCols;
@@ -286,8 +331,11 @@ template<typename T, int _Rows, int _Options> class DenseStorage<T, Dynamic, _Ro
}
m_cols = nbCols;
}
- inline const T *data() const { return m_data; }
- inline T *data() { return m_data; }
+ const T *data() const { return m_data; }
+ T *data() { return m_data; }
+ private:
+ DenseStorage(const DenseStorage&);
+ DenseStorage& operator=(const DenseStorage&);
};
// matrix with dynamic height and fixed width (so that matrix has dynamic size).
@@ -296,15 +344,30 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
T *m_data;
DenseIndex m_rows;
public:
- inline DenseStorage() : m_data(0), m_rows(0) {}
- inline DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
- inline DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows)
+ DenseStorage() : m_data(0), m_rows(0) {}
+ DenseStorage(internal::constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
+ DenseStorage(DenseIndex size, DenseIndex nbRows, DenseIndex) : m_data(internal::conditional_aligned_new_auto<T,(_Options&DontAlign)==0>(size)), m_rows(nbRows)
{ EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN }
- inline ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
- inline void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
- inline DenseIndex rows(void) const {return m_rows;}
- static inline DenseIndex cols(void) {return _Cols;}
- inline void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex)
+#ifdef EIGEN_HAVE_RVALUE_REFERENCES
+ DenseStorage(DenseStorage&& other)
+ : m_data(std::move(other.m_data))
+ , m_rows(std::move(other.m_rows))
+ {
+ other.m_data = nullptr;
+ }
+ DenseStorage& operator=(DenseStorage&& other)
+ {
+ using std::swap;
+ swap(m_data, other.m_data);
+ swap(m_rows, other.m_rows);
+ return *this;
+ }
+#endif
+ ~DenseStorage() { internal::conditional_aligned_delete_auto<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
+ void swap(DenseStorage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
+ DenseIndex rows(void) const {return m_rows;}
+ static DenseIndex cols(void) {return _Cols;}
+ void conservativeResize(DenseIndex size, DenseIndex nbRows, DenseIndex)
{
m_data = internal::conditional_aligned_realloc_new_auto<T,(_Options&DontAlign)==0>(m_data, size, m_rows*_Cols);
m_rows = nbRows;
@@ -322,8 +385,11 @@ template<typename T, int _Cols, int _Options> class DenseStorage<T, Dynamic, Dyn
}
m_rows = nbRows;
}
- inline const T *data() const { return m_data; }
- inline T *data() { return m_data; }
+ const T *data() const { return m_data; }
+ T *data() { return m_data; }
+ private:
+ DenseStorage(const DenseStorage&);
+ DenseStorage& operator=(const DenseStorage&);
};
} // end namespace Eigen
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index 0ba5d90cc..8dba1bf36 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.h
@@ -211,6 +211,21 @@ class Matrix
: Base(internal::constructor_without_unaligned_array_assert())
{ Base::_check_template_params(); EIGEN_INITIALIZE_COEFFS_IF_THAT_OPTION_IS_ENABLED }
+#ifdef EIGEN_HAVE_RVALUE_REFERENCES
+ Matrix(Matrix&& other)
+ : Base(std::move(other))
+ {
+ Base::_check_template_params();
+ if (RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic)
+ Base::_set_noalias(other);
+ }
+ Matrix& operator=(Matrix&& other)
+ {
+ other.swap(*this);
+ return *this;
+ }
+#endif
+
/** \brief Constructs a vector or row-vector with given dimension. \only_for_vectors
*
* Note that this is only useful for dynamic-size vectors. For fixed-size vectors,
diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h
index af0a479c7..e9aa3a88c 100644
--- a/Eigen/src/Core/PlainObjectBase.h
+++ b/Eigen/src/Core/PlainObjectBase.h
@@ -434,6 +434,20 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
}
#endif
+#ifdef EIGEN_HAVE_RVALUE_REFERENCES
+ PlainObjectBase(PlainObjectBase&& other)
+ : m_storage( std::move(other.m_storage) )
+ {
+ }
+
+ PlainObjectBase& operator=(PlainObjectBase&& other)
+ {
+ using std::swap;
+ swap(m_storage, other.m_storage);
+ return *this;
+ }
+#endif
+
EIGEN_STRONG_INLINE PlainObjectBase(Index a_size, Index nbRows, Index nbCols)
: m_storage(a_size, nbRows, nbCols)
{
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index 6798a3e0f..2a1ef296e 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -96,6 +96,19 @@
#define EIGEN_DEFAULT_DENSE_INDEX_TYPE std::ptrdiff_t
#endif
+// A Clang feature extension to determine compiler features.
+// We use it to determine 'cxx_rvalue_references'
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+// Do we support r-value references?
+#if (__has_feature(cxx_rvalue_references) || \
+ defined(__GXX_EXPERIMENTAL_CXX0X__) || \
+ (defined(_MSC_VER) && _MSC_VER >= 1600))
+ #define EIGEN_HAVE_RVALUE_REFERENCES
+#endif
+
/** Allows to disable some optimizations which might affect the accuracy of the result.
* Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them.
* They currently include:
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 19afe481e..84bf65ed4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -224,6 +224,7 @@ ei_add_test(sizeoverflow)
ei_add_test(prec_inverse_4x4)
ei_add_test(vectorwiseop)
ei_add_test(special_numbers)
+ei_add_test(rvalue_types)
ei_add_test(simplicial_cholesky)
ei_add_test(conjugate_gradient)
diff --git a/test/rvalue_types.cpp b/test/rvalue_types.cpp
new file mode 100644
index 000000000..5a581d0df
--- /dev/null
+++ b/test/rvalue_types.cpp
@@ -0,0 +1,73 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#include "main.h"
+
+#include <Eigen/Core>
+
+template <typename MatrixType>
+void rvalue_copyassign(const MatrixType& m)
+{
+#ifdef EIGEN_HAVE_RVALUE_REFERENCES
+ typedef typename internal::traits<MatrixType>::Scalar Scalar;
+
+ // create a temporary which we are about to destroy by moving
+ MatrixType tmp = m;
+ long src_address = reinterpret_cast<long>(tmp.data());
+
+ // move the temporary to n
+ MatrixType n = std::move(tmp);
+ long dst_address = reinterpret_cast<long>(n.data());
+
+ if (MatrixType::RowsAtCompileTime==Dynamic|| MatrixType::ColsAtCompileTime==Dynamic)
+ {
+ // verify that we actually moved the guts
+ VERIFY_IS_EQUAL(src_address, dst_address);
+ }
+
+ // verify that the content did not change
+ Scalar abs_diff = (m-n).array().abs().sum();
+ VERIFY_IS_EQUAL(abs_diff, Scalar(0));
+#endif
+}
+
+void test_rvalue_types()
+{
+ CALL_SUBTEST_1(rvalue_copyassign( MatrixXf::Random(50,50).eval() ));
+ CALL_SUBTEST_1(rvalue_copyassign( ArrayXXf::Random(50,50).eval() ));
+
+ CALL_SUBTEST_1(rvalue_copyassign( Matrix<float,1,Dynamic>::Random(50).eval() ));
+ CALL_SUBTEST_1(rvalue_copyassign( Array<float,1,Dynamic>::Random(50).eval() ));
+
+ CALL_SUBTEST_1(rvalue_copyassign( Matrix<float,Dynamic,1>::Random(50).eval() ));
+ CALL_SUBTEST_1(rvalue_copyassign( Array<float,Dynamic,1>::Random(50).eval() ));
+
+ CALL_SUBTEST_2(rvalue_copyassign( Array<float,2,1>::Random().eval() ));
+ CALL_SUBTEST_2(rvalue_copyassign( Array<float,3,1>::Random().eval() ));
+ CALL_SUBTEST_2(rvalue_copyassign( Array<float,4,1>::Random().eval() ));
+
+ CALL_SUBTEST_2(rvalue_copyassign( Array<float,2,2>::Random().eval() ));
+ CALL_SUBTEST_2(rvalue_copyassign( Array<float,3,3>::Random().eval() ));
+ CALL_SUBTEST_2(rvalue_copyassign( Array<float,4,4>::Random().eval() ));
+}