14#include "./InternalHeaderCheck.h"
20template <
typename PlainObjectType_,
int Options_,
typename Str
ideType_>
21struct traits<Ref<PlainObjectType_, Options_, StrideType_> >
22 :
public traits<Map<PlainObjectType_, Options_, StrideType_> > {
23 typedef PlainObjectType_ PlainObjectType;
24 typedef StrideType_ StrideType;
27 Flags = traits<Map<PlainObjectType_, Options_, StrideType_> >::Flags | NestByRefBit,
28 Alignment = traits<Map<PlainObjectType_, Options_, StrideType_> >::Alignment,
29 InnerStrideAtCompileTime = traits<Map<PlainObjectType_, Options_, StrideType_> >::InnerStrideAtCompileTime,
30 OuterStrideAtCompileTime = traits<Map<PlainObjectType_, Options_, StrideType_> >::OuterStrideAtCompileTime
33 template <
typename Derived>
36 IsVectorAtCompileTime = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime,
37 HasDirectAccess = internal::has_direct_access<Derived>::ret,
39 IsVectorAtCompileTime || ((PlainObjectType::Flags &
RowMajorBit) == (Derived::Flags & RowMajorBit)),
40 InnerStrideMatch =
int(InnerStrideAtCompileTime) == int(Dynamic) ||
41 int(InnerStrideAtCompileTime) == int(Derived::InnerStrideAtCompileTime) ||
42 (int(InnerStrideAtCompileTime) == 0 && int(Derived::InnerStrideAtCompileTime) == 1),
43 OuterStrideMatch = IsVectorAtCompileTime ||
int(OuterStrideAtCompileTime) == int(Dynamic) ||
44 int(OuterStrideAtCompileTime) == int(Derived::OuterStrideAtCompileTime),
50 DerivedAlignment = int(evaluator<Derived>::Alignment),
51 AlignmentMatch = (int(traits<PlainObjectType>::Alignment) == int(Unaligned)) ||
52 (DerivedAlignment >=
int(Alignment)),
54 ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
55 MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch &&
56 AlignmentMatch && ScalarTypeMatch
58 typedef std::conditional_t<MatchAtCompileTime, internal::true_type, internal::false_type> type;
62template <
typename Derived>
63struct traits<RefBase<Derived> > :
public traits<Derived> {};
67template <
typename Derived>
68class RefBase :
public MapBase<Derived> {
69 typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType;
70 typedef typename internal::traits<Derived>::StrideType StrideType;
73 typedef MapBase<Derived> Base;
74 EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
76 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline Index innerStride()
const {
77 return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.
inner() : 1;
80 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
inline Index outerStride()
const {
81 return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.
outer()
82 : IsVectorAtCompileTime ? this->size()
87 EIGEN_DEVICE_FUNC RefBase()
88 : Base(0, RowsAtCompileTime ==
Dynamic ? 0 : RowsAtCompileTime,
89 ColsAtCompileTime ==
Dynamic ? 0 : ColsAtCompileTime),
91 m_stride(StrideType::OuterStrideAtCompileTime ==
Dynamic ? 0 : StrideType::OuterStrideAtCompileTime,
92 StrideType::InnerStrideAtCompileTime ==
Dynamic ? 0 : StrideType::InnerStrideAtCompileTime) {}
94 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
97 typedef Stride<StrideType::OuterStrideAtCompileTime, StrideType::InnerStrideAtCompileTime> StrideBase;
100 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index resolveInnerStride(Index inner) {
return inner == 0 ? 1 : inner; }
103 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index resolveOuterStride(Index inner, Index outer, Index rows, Index cols,
104 bool isVectorAtCompileTime,
bool isRowMajor) {
105 return outer == 0 ? isVectorAtCompileTime ? inner * rows * cols : isRowMajor ? inner * cols : inner * rows : outer;
110 template <
typename Expression>
111 EIGEN_DEVICE_FUNC
bool construct(Expression& expr) {
114 EIGEN_STATIC_ASSERT(EIGEN_PREDICATE_SAME_MATRIX_SIZE(PlainObjectType, Expression)
116 || (PlainObjectType::IsVectorAtCompileTime &&
119 int(PlainObjectType::RowsAtCompileTime) ==
int(Expression::ColsAtCompileTime)) &&
122 int(PlainObjectType::ColsAtCompileTime) ==
int(Expression::RowsAtCompileTime)))),
123 YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES)
126 Index rows = expr.rows();
127 Index cols = expr.cols();
128 if (PlainObjectType::RowsAtCompileTime == 1) {
129 eigen_assert(expr.rows() == 1 || expr.cols() == 1);
132 }
else if (PlainObjectType::ColsAtCompileTime == 1) {
133 eigen_assert(expr.rows() == 1 || expr.cols() == 1);
138 eigen_assert((PlainObjectType::RowsAtCompileTime ==
Dynamic) || (PlainObjectType::RowsAtCompileTime == rows));
139 eigen_assert((PlainObjectType::ColsAtCompileTime ==
Dynamic) || (PlainObjectType::ColsAtCompileTime == cols));
142 const bool transpose = PlainObjectType::IsVectorAtCompileTime && (rows != expr.rows());
144 const bool row_major = ((PlainObjectType::Flags)&
RowMajorBit) != 0;
145 const bool expr_row_major = (Expression::Flags &
RowMajorBit) != 0;
146 const bool storage_differs = (row_major != expr_row_major);
148 const bool swap_stride = (transpose != storage_differs);
151 const Index expr_inner_actual = resolveInnerStride(expr.innerStride());
152 const Index expr_outer_actual = resolveOuterStride(expr_inner_actual, expr.outerStride(), expr.rows(), expr.cols(),
153 Expression::IsVectorAtCompileTime != 0, expr_row_major);
157 const bool row_vector = (rows == 1);
158 const bool col_vector = (cols == 1);
159 const Index inner_stride =
160 ((!row_major && row_vector) || (row_major && col_vector))
161 ? (StrideType::InnerStrideAtCompileTime > 0 ?
Index(StrideType::InnerStrideAtCompileTime) : 1)
162 : swap_stride ? expr_outer_actual
167 const Index outer_stride =
168 ((!row_major && col_vector) || (row_major && row_vector))
169 ? (StrideType::OuterStrideAtCompileTime > 0 ?
Index(StrideType::OuterStrideAtCompileTime)
170 : rows * cols * inner_stride)
171 : swap_stride ? expr_inner_actual
175 const bool inner_valid = (StrideType::InnerStrideAtCompileTime ==
Dynamic) ||
176 (resolveInnerStride(
Index(StrideType::InnerStrideAtCompileTime)) == inner_stride);
181 const bool outer_valid =
182 (StrideType::OuterStrideAtCompileTime ==
Dynamic) ||
183 (resolveOuterStride(inner_stride,
Index(StrideType::OuterStrideAtCompileTime), rows, cols,
184 PlainObjectType::IsVectorAtCompileTime != 0, row_major) == outer_stride);
189 internal::construct_at<Base>(
this, expr.data(), rows, cols);
190 internal::construct_at(&m_stride, (StrideType::OuterStrideAtCompileTime == 0) ? 0 : outer_stride,
191 (StrideType::InnerStrideAtCompileTime == 0) ? 0 : inner_stride);
263template <
typename PlainObjectType,
int Options,
typename Str
ideType>
264class Ref :
public RefBase<Ref<PlainObjectType, Options, StrideType> > {
266 typedef internal::traits<Ref> Traits;
267 template <
typename Derived>
268 EIGEN_DEVICE_FUNC
inline Ref(
270 std::enable_if_t<
bool(Traits::template match<Derived>::MatchAtCompileTime), Derived>* = 0);
273 typedef RefBase<Ref> Base;
274 EIGEN_DENSE_PUBLIC_INTERFACE(
Ref)
276#ifndef EIGEN_PARSED_BY_DOXYGEN
277 template <
typename Derived>
278 EIGEN_DEVICE_FUNC
inline Ref(
280 std::enable_if_t<
bool(Traits::template match<Derived>::MatchAtCompileTime), Derived>* = 0) {
281 EIGEN_STATIC_ASSERT(
bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
283 const bool success = Base::construct(expr.derived());
284 EIGEN_UNUSED_VARIABLE(success)
285 eigen_assert(success);
287 template <
typename Derived>
288 EIGEN_DEVICE_FUNC
inline Ref(
290 std::enable_if_t<
bool(Traits::template match<Derived>::MatchAtCompileTime), Derived>* = 0)
293 template <
typename Derived>
297 EIGEN_STATIC_ASSERT(
bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
298 EIGEN_STATIC_ASSERT(
bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
299 EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase, THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
301 const bool success = Base::construct(expr.const_cast_derived());
302 EIGEN_UNUSED_VARIABLE(success)
303 eigen_assert(success);
306 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(
Ref)
310template <
typename TPlainObjectType,
int Options,
typename Str
ideType>
311class Ref<const TPlainObjectType, Options, StrideType>
312 :
public RefBase<Ref<const TPlainObjectType, Options, StrideType> > {
313 typedef internal::traits<Ref> Traits;
315 static constexpr bool may_map_m_object_successfully =
316 (
static_cast<int>(StrideType::InnerStrideAtCompileTime) == 0 ||
317 static_cast<int>(StrideType::InnerStrideAtCompileTime) == 1 ||
318 static_cast<int>(StrideType::InnerStrideAtCompileTime) ==
Dynamic) &&
319 (TPlainObjectType::IsVectorAtCompileTime ||
static_cast<int>(StrideType::OuterStrideAtCompileTime) == 0 ||
320 static_cast<int>(StrideType::OuterStrideAtCompileTime) ==
Dynamic ||
321 static_cast<int>(StrideType::OuterStrideAtCompileTime) ==
322 static_cast<int>(TPlainObjectType::InnerSizeAtCompileTime) ||
323 static_cast<int>(TPlainObjectType::InnerSizeAtCompileTime) ==
Dynamic);
326 typedef RefBase<Ref> Base;
327 EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
329 template <
typename Derived>
330 EIGEN_DEVICE_FUNC
inline Ref(
const DenseBase<Derived>& expr,
331 std::enable_if_t<
bool(Traits::template match<Derived>::ScalarTypeMatch), Derived>* = 0) {
336 EIGEN_STATIC_ASSERT(Traits::template match<Derived>::type::value || may_map_m_object_successfully,
337 STORAGE_LAYOUT_DOES_NOT_MATCH);
338 construct(expr.derived(),
typename Traits::template match<Derived>::type());
341 EIGEN_DEVICE_FUNC
inline Ref(
const Ref& other) : Base(other) {
345 EIGEN_DEVICE_FUNC
inline Ref(Ref&& other) {
346 if (other.data() == other.m_object.data()) {
347 m_object = std::move(other.m_object);
348 Base::construct(m_object);
350 Base::construct(other);
353 template <
typename OtherRef>
354 EIGEN_DEVICE_FUNC
inline Ref(
const RefBase<OtherRef>& other) {
355 EIGEN_STATIC_ASSERT(Traits::template match<OtherRef>::type::value || may_map_m_object_successfully,
356 STORAGE_LAYOUT_DOES_NOT_MATCH);
357 construct(other.derived(),
typename Traits::template match<OtherRef>::type());
361 template <
typename Expression>
362 EIGEN_DEVICE_FUNC
void construct(
const Expression& expr, internal::true_type) {
364 if (!Base::construct(expr)) {
365 construct(expr, internal::false_type());
369 template <
typename Expression>
370 EIGEN_DEVICE_FUNC
void construct(
const Expression& expr, internal::false_type) {
371 internal::call_assignment_no_alias(m_object, expr, internal::assign_op<Scalar, Scalar>());
372 const bool success = Base::construct(m_object);
373 EIGEN_ONLY_USED_FOR_DEBUG(success)
374 eigen_assert(success);
378 TPlainObjectType m_object;
Base class for all dense matrices, vectors, and arrays.
Definition DenseBase.h:44
Dense storage base class for matrices and arrays.
Definition PlainObjectBase.h:121
A matrix or vector expression mapping an existing expression.
Definition Ref.h:264
Ref(DenseBase< Derived > &expr)
Definition Ref.h:294
EIGEN_CONSTEXPR Index inner() const
Definition Stride.h:76
EIGEN_CONSTEXPR Index outer() const
Definition Stride.h:74
const unsigned int RowMajorBit
Definition Constants.h:70
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83
const int Dynamic
Definition Constants.h:25