15#include "./InternalHeaderCheck.h"
21template <
typename PlainObjectType_,
int Options_,
typename Str
ideType_>
22struct traits<Ref<PlainObjectType_, Options_, StrideType_> >
23 :
public traits<Map<PlainObjectType_, Options_, StrideType_> > {
24 using PlainObjectType = PlainObjectType_;
25 using StrideType = StrideType_;
28 Flags = traits<Map<PlainObjectType_, Options_, StrideType_> >::Flags | NestByRefBit,
29 Alignment = traits<Map<PlainObjectType_, Options_, StrideType_> >::Alignment,
30 InnerStrideAtCompileTime = traits<Map<PlainObjectType_, Options_, StrideType_> >::InnerStrideAtCompileTime,
31 OuterStrideAtCompileTime = traits<Map<PlainObjectType_, Options_, StrideType_> >::OuterStrideAtCompileTime
34 template <
typename Derived>
37 IsVectorAtCompileTime = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime,
38 HasDirectAccess = internal::has_direct_access<Derived>::value,
41 InnerStrideMatch =
int(InnerStrideAtCompileTime) == int(Dynamic) ||
42 int(InnerStrideAtCompileTime) == int(Derived::InnerStrideAtCompileTime) ||
43 (int(InnerStrideAtCompileTime) == 0 && int(Derived::InnerStrideAtCompileTime) == 1),
44 OuterStrideMatch = IsVectorAtCompileTime ||
int(OuterStrideAtCompileTime) == int(Dynamic) ||
45 int(OuterStrideAtCompileTime) == int(Derived::OuterStrideAtCompileTime),
46 AlignmentMatch = int(evaluator<Derived>::Alignment) >= int(Alignment),
47 ScalarTypeMatch = std::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
48 MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch &&
49 AlignmentMatch && ScalarTypeMatch
51 using type = bool_constant<MatchAtCompileTime>;
55template <
typename Derived>
56struct traits<RefBase<Derived> > :
public traits<Derived> {};
60template <
typename Derived>
61class RefBase :
public MapBase<Derived> {
62 using PlainObjectType =
typename internal::traits<Derived>::PlainObjectType;
63 using StrideType =
typename internal::traits<Derived>::StrideType;
66 using Base = MapBase<Derived>;
67 EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
69 EIGEN_DEVICE_FUNC
constexpr Index innerStride()
const {
70 return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
73 EIGEN_DEVICE_FUNC
constexpr Index outerStride()
const {
74 return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
75 : IsVectorAtCompileTime ? this->size()
80 EIGEN_DEVICE_FUNC RefBase()
81 : Base(0, RowsAtCompileTime == Dynamic ? 0 : RowsAtCompileTime,
82 ColsAtCompileTime == Dynamic ? 0 : ColsAtCompileTime),
84 m_stride(StrideType::OuterStrideAtCompileTime == Dynamic ? 0 : StrideType::OuterStrideAtCompileTime,
85 StrideType::InnerStrideAtCompileTime == Dynamic ? 0 : StrideType::InnerStrideAtCompileTime) {}
87 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
90 using StrideBase = Stride<StrideType::OuterStrideAtCompileTime, StrideType::InnerStrideAtCompileTime>;
93 static EIGEN_DEVICE_FUNC
constexpr Index resolveInnerStride(Index inner) {
return inner == 0 ? 1 : inner; }
96 static EIGEN_DEVICE_FUNC
constexpr Index resolveOuterStride(Index inner, Index outer, Index rows, Index cols,
97 bool isVectorAtCompileTime,
bool isRowMajor) {
98 return outer == 0 ? isVectorAtCompileTime ? inner * rows * cols : isRowMajor ? inner * cols : inner * rows : outer;
103 template <
typename Expression>
104 EIGEN_DEVICE_FUNC
bool construct(Expression& expr) {
107 EIGEN_STATIC_ASSERT(EIGEN_PREDICATE_SAME_MATRIX_SIZE(PlainObjectType, Expression)
109 || (PlainObjectType::IsVectorAtCompileTime &&
110 ((
int(PlainObjectType::RowsAtCompileTime) == Eigen::Dynamic ||
111 int(Expression::ColsAtCompileTime) == Eigen::Dynamic ||
112 int(PlainObjectType::RowsAtCompileTime) ==
int(Expression::ColsAtCompileTime)) &&
113 (
int(PlainObjectType::ColsAtCompileTime) == Eigen::Dynamic ||
114 int(Expression::RowsAtCompileTime) == Eigen::Dynamic ||
115 int(PlainObjectType::ColsAtCompileTime) ==
int(Expression::RowsAtCompileTime)))),
116 YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES)
119 Index rows = expr.rows();
120 Index cols = expr.cols();
121 EIGEN_IF_CONSTEXPR (PlainObjectType::RowsAtCompileTime == 1) {
122 eigen_assert(expr.rows() == 1 || expr.cols() == 1);
125 }
else EIGEN_IF_CONSTEXPR (PlainObjectType::ColsAtCompileTime == 1) {
126 eigen_assert(expr.rows() == 1 || expr.cols() == 1);
131 eigen_assert((PlainObjectType::RowsAtCompileTime == Dynamic) || (PlainObjectType::RowsAtCompileTime == rows));
132 eigen_assert((PlainObjectType::ColsAtCompileTime == Dynamic) || (PlainObjectType::ColsAtCompileTime == cols));
135 const bool transpose = PlainObjectType::IsVectorAtCompileTime && (rows != expr.rows());
137 const bool row_major = ((PlainObjectType::Flags)&
RowMajorBit) != 0;
138 const bool expr_row_major = (Expression::Flags &
RowMajorBit) != 0;
139 const bool storage_differs = (row_major != expr_row_major);
141 const bool swap_stride = (transpose != storage_differs);
144 const Index expr_inner_actual = resolveInnerStride(expr.innerStride());
145 const Index expr_outer_actual = resolveOuterStride(expr_inner_actual, expr.outerStride(), expr.rows(), expr.cols(),
146 Expression::IsVectorAtCompileTime != 0, expr_row_major);
150 const bool row_vector = (rows == 1);
151 const bool col_vector = (cols == 1);
152 const Index inner_stride =
153 ((!row_major && row_vector) || (row_major && col_vector))
154 ? (StrideType::InnerStrideAtCompileTime > 0 ? Index(StrideType::InnerStrideAtCompileTime) : 1)
155 : swap_stride ? expr_outer_actual
160 const Index outer_stride =
161 ((!row_major && col_vector) || (row_major && row_vector))
162 ? (StrideType::OuterStrideAtCompileTime > 0 ? Index(StrideType::OuterStrideAtCompileTime)
163 : rows * cols * inner_stride)
164 : swap_stride ? expr_inner_actual
168 const bool inner_valid = (StrideType::InnerStrideAtCompileTime == Dynamic) ||
169 (resolveInnerStride(Index(StrideType::InnerStrideAtCompileTime)) == inner_stride);
174 const bool outer_valid =
175 (StrideType::OuterStrideAtCompileTime == Dynamic) ||
176 (resolveOuterStride(inner_stride, Index(StrideType::OuterStrideAtCompileTime), rows, cols,
177 PlainObjectType::IsVectorAtCompileTime != 0, row_major) == outer_stride);
182 internal::construct_at<Base>(
this, expr.data(), rows, cols);
183 internal::construct_at(&m_stride, (StrideType::OuterStrideAtCompileTime == 0) ? 0 : outer_stride,
184 (StrideType::InnerStrideAtCompileTime == 0) ? 0 : inner_stride);
261template <
typename PlainObjectType,
int Options,
typename Str
ideType>
262class Ref :
public RefBase<Ref<PlainObjectType, Options, StrideType> > {
264 using Traits = internal::traits<Ref>;
265 template <
typename Derived, std::enable_if_t<
bool(Traits::
template match<Derived>::MatchAtCompileTime),
int> = 0>
269 using Base = RefBase<Ref>;
270 EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
272#ifndef EIGEN_PARSED_BY_DOXYGEN
273 template <
typename Derived, std::enable_if_t<
bool(Traits::
template match<Derived>::MatchAtCompileTime),
int> = 0>
275 EIGEN_STATIC_ASSERT(
bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
277 const bool success = Base::construct(expr.derived());
278 EIGEN_UNUSED_VARIABLE(success);
279 eigen_assert(success);
282 template <
typename Derived>
283 EIGEN_DEPRECATED_WITH_REASON(
"Omit the implementation-only second argument.")
284 EIGEN_DEVICE_FUNC
constexpr inline Ref(
286 std::enable_if_t<
bool(Traits::template match<Derived>::MatchAtCompileTime), Derived>*)
289 template <
typename Derived, std::enable_if_t<
bool(Traits::
template match<Derived>::MatchAtCompileTime),
int> = 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#ifndef EIGEN_PARSED_BY_DOXYGEN
307 template <
typename Derived>
308 EIGEN_DEPRECATED_WITH_REASON(
"Omit the implementation-only second argument.")
309 EIGEN_DEVICE_FUNC constexpr inline
Ref(
311 std::enable_if_t<
bool(Traits::template match<Derived>::MatchAtCompileTime), Derived>*)
315 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
319template <
typename TPlainObjectType,
int Options,
typename Str
ideType>
321 :
public RefBase<Ref<const TPlainObjectType, Options, StrideType> > {
322 using Traits = internal::traits<Ref>;
324 static constexpr bool may_map_m_object_successfully =
325 (
static_cast<int>(StrideType::InnerStrideAtCompileTime) == 0 ||
326 static_cast<int>(StrideType::InnerStrideAtCompileTime) == 1 ||
327 static_cast<int>(StrideType::InnerStrideAtCompileTime) == Dynamic) &&
328 (TPlainObjectType::IsVectorAtCompileTime ||
static_cast<int>(StrideType::OuterStrideAtCompileTime) == 0 ||
329 static_cast<int>(StrideType::OuterStrideAtCompileTime) == Dynamic ||
330 static_cast<int>(StrideType::OuterStrideAtCompileTime) ==
331 static_cast<int>(TPlainObjectType::InnerSizeAtCompileTime) ||
332 static_cast<int>(TPlainObjectType::InnerSizeAtCompileTime) == Dynamic);
335 using Base = RefBase<Ref>;
336 EIGEN_DENSE_PUBLIC_INTERFACE(
Ref)
338 template <
typename Derived, std::enable_if_t<
bool(Traits::
template match<Derived>::ScalarTypeMatch),
int> = 0>
344 EIGEN_STATIC_ASSERT(Traits::template match<Derived>::type::value || may_map_m_object_successfully,
345 STORAGE_LAYOUT_DOES_NOT_MATCH);
346 construct(expr.derived(),
typename Traits::template match<Derived>::type());
349 template <
typename Derived>
350 EIGEN_DEPRECATED_WITH_REASON(
"Omit the implementation-only second argument.")
351 EIGEN_DEVICE_FUNC constexpr inline
Ref(
353 std::enable_if_t<
bool(Traits::template match<Derived>::ScalarTypeMatch), Derived>*)
356 EIGEN_DEVICE_FUNC
constexpr inline Ref(
const Ref& other) : Base(other) {
360 EIGEN_DEVICE_FUNC
constexpr inline Ref(
Ref&& other) {
361 if (other.data() == other.m_object.data()) {
362 m_object = std::move(other.m_object);
363 Base::construct(m_object);
365 Base::construct(other);
368 template <
typename OtherRef>
369 EIGEN_DEVICE_FUNC
constexpr inline Ref(
const RefBase<OtherRef>& other) {
370 EIGEN_STATIC_ASSERT(Traits::template match<OtherRef>::type::value || may_map_m_object_successfully,
371 STORAGE_LAYOUT_DOES_NOT_MATCH);
372 construct(other.derived(),
typename Traits::template match<OtherRef>::type());
376 template <
typename Expression>
377 EIGEN_DEVICE_FUNC
void construct(
const Expression& expr, std::true_type) {
379 if (!Base::construct(expr)) {
380 construct(expr, std::false_type());
384 template <
typename Expression>
385 EIGEN_DEVICE_FUNC
void construct(
const Expression& expr, std::false_type) {
386 internal::call_assignment_no_alias(m_object, expr, internal::assign_op<Scalar, Scalar>());
387 const bool success = Base::construct(m_object);
388 EIGEN_ONLY_USED_FOR_DEBUG(success);
389 eigen_assert(success);
393 TPlainObjectType m_object;
Base class for all dense matrices, vectors, and arrays.
Definition DenseBase.h:45
Dense storage base class for matrices and arrays.
Definition PlainObjectBase.h:110
A matrix or vector expression mapping an existing expression.
Definition Ref.h:262
Ref(DenseBase< Derived > &expr)
Definition Ref.h:294
constexpr unsigned int RowMajorBit
Definition Constants.h:71