mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-10 10:49:04 +08:00
Refactor IndexedView
This commit is contained in:
parent
1148f0a9ec
commit
87300c93ca
@ -7,6 +7,7 @@
|
|||||||
// Public License v. 2.0. If a copy of the MPL was not distributed
|
// Public License v. 2.0. If a copy of the MPL was not distributed
|
||||||
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
|
||||||
#if !defined(EIGEN_PARSED_BY_DOXYGEN)
|
#if !defined(EIGEN_PARSED_BY_DOXYGEN)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -24,163 +25,278 @@ using IvcType = typename internal::IndexedViewCompatibleType<Indices, SizeAtComp
|
|||||||
typedef typename internal::IndexedViewCompatibleType<Index, 1>::type IvcIndex;
|
typedef typename internal::IndexedViewCompatibleType<Index, 1>::type IvcIndex;
|
||||||
|
|
||||||
template <typename Indices>
|
template <typename Indices>
|
||||||
IvcRowType<Indices> ivcRow(const Indices& indices) const {
|
inline IvcRowType<Indices> ivcRow(const Indices& indices) const {
|
||||||
return internal::makeIndexedViewCompatible(
|
return internal::makeIndexedViewCompatible(
|
||||||
indices, internal::variable_if_dynamic<Index, RowsAtCompileTime>(derived().rows()), Specialized);
|
indices, internal::variable_if_dynamic<Index, RowsAtCompileTime>(derived().rows()), Specialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Indices>
|
template <typename Indices>
|
||||||
IvcColType<Indices> ivcCol(const Indices& indices) const {
|
inline IvcColType<Indices> ivcCol(const Indices& indices) const {
|
||||||
return internal::makeIndexedViewCompatible(
|
return internal::makeIndexedViewCompatible(
|
||||||
indices, internal::variable_if_dynamic<Index, ColsAtCompileTime>(derived().cols()), Specialized);
|
indices, internal::variable_if_dynamic<Index, ColsAtCompileTime>(derived().cols()), Specialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Indices>
|
template <typename Indices>
|
||||||
IvcColType<Indices> ivcSize(const Indices& indices) const {
|
inline IvcColType<Indices> ivcSize(const Indices& indices) const {
|
||||||
return internal::makeIndexedViewCompatible(
|
return internal::makeIndexedViewCompatible(
|
||||||
indices, internal::variable_if_dynamic<Index, SizeAtCompileTime>(derived().size()), Specialized);
|
indices, internal::variable_if_dynamic<Index, SizeAtCompileTime>(derived().size()), Specialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this helper class assumes internal::valid_indexed_view_overload<RowIndices, ColIndices>::value == true
|
||||||
|
template <typename RowIndices, typename ColIndices,
|
||||||
|
bool UseSymbolic = internal::traits<IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>>::ReturnAsScalar,
|
||||||
|
bool UseBlock = internal::traits<IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>>::ReturnAsBlock,
|
||||||
|
bool UseGeneric = internal::traits<IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>>::ReturnAsIndexedView>
|
||||||
|
struct IndexedViewSelector;
|
||||||
|
|
||||||
|
// Generic
|
||||||
|
template <typename RowIndices, typename ColIndices>
|
||||||
|
struct IndexedViewSelector<RowIndices, ColIndices, false, false, true> {
|
||||||
|
using ReturnType = IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
|
||||||
|
using ConstReturnType = IndexedView<const Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
|
||||||
|
|
||||||
|
static inline ReturnType run(Derived& derived, const RowIndices& rowIndices, const ColIndices& colIndices) {
|
||||||
|
return ReturnType(derived, derived.ivcRow(rowIndices), derived.ivcCol(colIndices));
|
||||||
|
}
|
||||||
|
static inline ConstReturnType run(const Derived& derived, const RowIndices& rowIndices,
|
||||||
|
const ColIndices& colIndices) {
|
||||||
|
return ConstReturnType(derived, derived.ivcRow(rowIndices), derived.ivcCol(colIndices));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Block
|
||||||
|
template <typename RowIndices, typename ColIndices>
|
||||||
|
struct IndexedViewSelector<RowIndices, ColIndices, false, true, false> {
|
||||||
|
using IndexedViewType = IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
|
||||||
|
using ConstIndexedViewType = IndexedView<const Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
|
||||||
|
using ReturnType = typename internal::traits<IndexedViewType>::BlockType;
|
||||||
|
using ConstReturnType = typename internal::traits<ConstIndexedViewType>::BlockType;
|
||||||
|
|
||||||
|
static inline ReturnType run(Derived& derived, const RowIndices& rowIndices, const ColIndices& colIndices) {
|
||||||
|
IvcRowType<RowIndices> actualRowIndices = derived.ivcRow(rowIndices);
|
||||||
|
IvcColType<ColIndices> actualColIndices = derived.ivcCol(colIndices);
|
||||||
|
return ReturnType(derived, internal::first(actualRowIndices), internal::first(actualColIndices),
|
||||||
|
internal::index_list_size(actualRowIndices), internal::index_list_size(actualColIndices));
|
||||||
|
}
|
||||||
|
static inline ConstReturnType run(const Derived& derived, const RowIndices& rowIndices,
|
||||||
|
const ColIndices& colIndices) {
|
||||||
|
IvcRowType<RowIndices> actualRowIndices = derived.ivcRow(rowIndices);
|
||||||
|
IvcColType<ColIndices> actualColIndices = derived.ivcCol(colIndices);
|
||||||
|
return ConstReturnType(derived, internal::first(actualRowIndices), internal::first(actualColIndices),
|
||||||
|
internal::index_list_size(actualRowIndices), internal::index_list_size(actualColIndices));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Symbolic
|
||||||
|
template <typename RowIndices, typename ColIndices>
|
||||||
|
struct IndexedViewSelector<RowIndices, ColIndices, true, false, false> {
|
||||||
|
using ReturnType = typename DenseBase<Derived>::Scalar&;
|
||||||
|
using ConstReturnType = typename DenseBase<Derived>::CoeffReturnType;
|
||||||
|
|
||||||
|
static inline ReturnType run(Derived& derived, const RowIndices& rowIndices, const ColIndices& colIndices) {
|
||||||
|
return derived(internal::eval_expr_given_size(rowIndices, derived.rows()),
|
||||||
|
internal::eval_expr_given_size(colIndices, derived.cols()));
|
||||||
|
}
|
||||||
|
static inline ConstReturnType run(const Derived& derived, const RowIndices& rowIndices,
|
||||||
|
const ColIndices& colIndices) {
|
||||||
|
return derived(internal::eval_expr_given_size(rowIndices, derived.rows()),
|
||||||
|
internal::eval_expr_given_size(colIndices, derived.cols()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// this helper class assumes internal::is_valid_index_type<Indices>::value == false
|
||||||
|
template <typename Indices,
|
||||||
|
bool UseSymbolic = symbolic::is_symbolic<Indices>::value,
|
||||||
|
bool UseBlock = !UseSymbolic && internal::get_compile_time_incr<IvcType<Indices>>::value == 1,
|
||||||
|
bool UseGeneric = !UseSymbolic && !UseBlock>
|
||||||
|
struct VectorIndexedViewSelector;
|
||||||
|
|
||||||
|
// Generic
|
||||||
|
template <typename Indices>
|
||||||
|
struct VectorIndexedViewSelector<Indices, false, false, true> {
|
||||||
|
|
||||||
|
static constexpr bool IsRowMajor = DenseBase<Derived>::IsRowMajor;
|
||||||
|
|
||||||
|
using RowMajorReturnType = IndexedView<Derived, IvcIndex, IvcType<Indices>>;
|
||||||
|
using ConstRowMajorReturnType = IndexedView<const Derived, IvcIndex, IvcType<Indices>>;
|
||||||
|
|
||||||
|
using ColMajorReturnType = IndexedView<Derived, IvcType<Indices>, IvcIndex>;
|
||||||
|
using ConstColMajorReturnType = IndexedView<const Derived, IvcType<Indices>, IvcIndex>;
|
||||||
|
|
||||||
|
using ReturnType = typename internal::conditional<IsRowMajor, RowMajorReturnType, ColMajorReturnType>::type;
|
||||||
|
using ConstReturnType =
|
||||||
|
typename internal::conditional<IsRowMajor, ConstRowMajorReturnType, ConstColMajorReturnType>::type;
|
||||||
|
|
||||||
|
template <bool UseRowMajor = IsRowMajor, std::enable_if_t<UseRowMajor, bool> = true>
|
||||||
|
static inline RowMajorReturnType run(Derived& derived, const Indices& indices) {
|
||||||
|
return RowMajorReturnType(derived, IvcIndex(0), derived.ivcCol(indices));
|
||||||
|
}
|
||||||
|
template <bool UseRowMajor = IsRowMajor, std::enable_if_t<UseRowMajor, bool> = true>
|
||||||
|
static inline ConstRowMajorReturnType run(const Derived& derived, const Indices& indices) {
|
||||||
|
return ConstRowMajorReturnType(derived, IvcIndex(0), derived.ivcCol(indices));
|
||||||
|
}
|
||||||
|
template <bool UseRowMajor = IsRowMajor, std::enable_if_t<!UseRowMajor, bool> = true>
|
||||||
|
static inline ColMajorReturnType run(Derived& derived, const Indices& indices) {
|
||||||
|
return ColMajorReturnType(derived, derived.ivcRow(indices), IvcIndex(0));
|
||||||
|
}
|
||||||
|
template <bool UseRowMajor = IsRowMajor, std::enable_if_t<!UseRowMajor, bool> = true>
|
||||||
|
static inline ConstColMajorReturnType run(const Derived& derived, const Indices& indices) {
|
||||||
|
return ConstColMajorReturnType(derived, derived.ivcRow(indices), IvcIndex(0));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Block
|
||||||
|
template <typename Indices>
|
||||||
|
struct VectorIndexedViewSelector<Indices, false, true, false> {
|
||||||
|
|
||||||
|
using ReturnType = VectorBlock<Derived, internal::array_size<Indices>::value>;
|
||||||
|
using ConstReturnType = VectorBlock<const Derived, internal::array_size<Indices>::value>;
|
||||||
|
|
||||||
|
static inline ReturnType run(Derived& derived, const Indices& indices) {
|
||||||
|
IvcType<Indices> actualIndices = derived.ivcSize(indices);
|
||||||
|
return ReturnType(derived, internal::first(actualIndices), internal::index_list_size(actualIndices));
|
||||||
|
}
|
||||||
|
static inline ConstReturnType run(const Derived& derived, const Indices& indices) {
|
||||||
|
IvcType<Indices> actualIndices = derived.ivcSize(indices);
|
||||||
|
return ConstReturnType(derived, internal::first(actualIndices), internal::index_list_size(actualIndices));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Symbolic
|
||||||
|
template <typename Indices>
|
||||||
|
struct VectorIndexedViewSelector<Indices, true, false, false> {
|
||||||
|
|
||||||
|
using ReturnType = typename DenseBase<Derived>::Scalar&;
|
||||||
|
using ConstReturnType = typename DenseBase<Derived>::CoeffReturnType;
|
||||||
|
|
||||||
|
static inline ReturnType run(Derived& derived, const Indices& id) {
|
||||||
|
return derived(internal::eval_expr_given_size(id, derived.size()));
|
||||||
|
}
|
||||||
|
static inline ConstReturnType run(const Derived& derived, const Indices& id) {
|
||||||
|
return derived(internal::eval_expr_given_size(id, derived.size()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// SFINAE dummy types
|
||||||
|
|
||||||
|
template <typename RowIndices, typename ColIndices>
|
||||||
|
using EnableOverload = std::enable_if_t<
|
||||||
|
internal::valid_indexed_view_overload<RowIndices, ColIndices>::value && internal::is_lvalue<Derived>::value, bool>;
|
||||||
|
|
||||||
|
template <typename RowIndices, typename ColIndices>
|
||||||
|
using EnableConstOverload =
|
||||||
|
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value, bool>;
|
||||||
|
|
||||||
|
template <typename Indices>
|
||||||
|
using EnableVectorOverload =
|
||||||
|
std::enable_if_t<!internal::is_valid_index_type<Indices>::value && internal::is_lvalue<Derived>::value, bool>;
|
||||||
|
|
||||||
|
template <typename Indices>
|
||||||
|
using EnableConstVectorOverload = std::enable_if_t<!internal::is_valid_index_type<Indices>::value, bool>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template <typename RowIndices, typename ColIndices>
|
// Public API for 2D matrices/arrays
|
||||||
using IndexedViewType = IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
|
|
||||||
|
// non-const versions
|
||||||
|
|
||||||
template <typename RowIndices, typename ColIndices>
|
template <typename RowIndices, typename ColIndices>
|
||||||
using ConstIndexedViewType = IndexedView<const Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
|
using IndexedViewType = typename IndexedViewSelector<RowIndices, ColIndices>::ReturnType;
|
||||||
|
|
||||||
// This is the generic version
|
template <typename RowIndices, typename ColIndices, EnableOverload<RowIndices, ColIndices> = true>
|
||||||
|
IndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices, const ColIndices& colIndices) {
|
||||||
template <typename RowIndices, typename ColIndices>
|
return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, colIndices);
|
||||||
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
|
|
||||||
internal::traits<IndexedViewType<RowIndices, ColIndices>>::ReturnAsIndexedView,
|
|
||||||
IndexedViewType<RowIndices, ColIndices>>
|
|
||||||
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) {
|
|
||||||
return IndexedViewType<RowIndices, ColIndices>(derived(), ivcRow(rowIndices), ivcCol(colIndices));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename RowIndices, typename ColIndices>
|
template <typename RowType, size_t RowSize, typename ColIndices, typename RowIndices = Array<RowType, RowSize, 1>,
|
||||||
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
|
EnableOverload<RowIndices, ColIndices> = true>
|
||||||
internal::traits<ConstIndexedViewType<RowIndices, ColIndices>>::ReturnAsIndexedView,
|
IndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize], const ColIndices& colIndices) {
|
||||||
ConstIndexedViewType<RowIndices, ColIndices>>
|
return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, colIndices);
|
||||||
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) const {
|
|
||||||
return ConstIndexedViewType<RowIndices, ColIndices>(derived(), ivcRow(rowIndices), ivcCol(colIndices));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following overload returns a Block<> object
|
template <typename RowIndices, typename ColType, size_t ColSize, typename ColIndices = Array<ColType, ColSize, 1>,
|
||||||
|
EnableOverload<RowIndices, ColIndices> = true>
|
||||||
template <typename RowIndices, typename ColIndices>
|
IndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices, const ColType (&colIndices)[ColSize]) {
|
||||||
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
|
return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, ColIndices{colIndices});
|
||||||
internal::traits<IndexedViewType<RowIndices, ColIndices>>::ReturnAsBlock,
|
|
||||||
typename internal::traits<IndexedViewType<RowIndices, ColIndices>>::BlockType>
|
|
||||||
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) {
|
|
||||||
typedef typename internal::traits<IndexedViewType<RowIndices, ColIndices>>::BlockType BlockType;
|
|
||||||
IvcRowType<RowIndices> actualRowIndices = ivcRow(rowIndices);
|
|
||||||
IvcColType<ColIndices> actualColIndices = ivcCol(colIndices);
|
|
||||||
return BlockType(derived(), internal::first(actualRowIndices), internal::first(actualColIndices),
|
|
||||||
internal::index_list_size(actualRowIndices), internal::index_list_size(actualColIndices));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename RowIndices, typename ColIndices>
|
template <typename RowType, size_t RowSize, typename ColType, size_t ColSize,
|
||||||
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
|
typename RowIndices = Array<RowType, RowSize, 1>, typename ColIndices = Array<ColType, ColSize, 1>,
|
||||||
internal::traits<ConstIndexedViewType<RowIndices, ColIndices>>::ReturnAsBlock,
|
EnableOverload<RowIndices, ColIndices> = true>
|
||||||
typename internal::traits<ConstIndexedViewType<RowIndices, ColIndices>>::BlockType>
|
IndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize],
|
||||||
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) const {
|
const ColType (&colIndices)[ColSize]) {
|
||||||
typedef typename internal::traits<ConstIndexedViewType<RowIndices, ColIndices>>::BlockType BlockType;
|
return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, ColIndices{colIndices});
|
||||||
IvcRowType<RowIndices> actualRowIndices = ivcRow(rowIndices);
|
|
||||||
IvcColType<ColIndices> actualColIndices = ivcCol(colIndices);
|
|
||||||
return BlockType(derived(), internal::first(actualRowIndices), internal::first(actualColIndices),
|
|
||||||
internal::index_list_size(actualRowIndices), internal::index_list_size(actualColIndices));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following overload returns a Scalar
|
// const versions
|
||||||
|
|
||||||
template <typename RowIndices, typename ColIndices>
|
template <typename RowIndices, typename ColIndices>
|
||||||
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
|
using ConstIndexedViewType = typename IndexedViewSelector<RowIndices, ColIndices>::ConstReturnType;
|
||||||
internal::traits<IndexedViewType<RowIndices, ColIndices>>::ReturnAsScalar && internal::is_lvalue<Derived>::value,
|
|
||||||
Scalar&>
|
template <typename RowIndices, typename ColIndices, EnableConstOverload<RowIndices, ColIndices> = true>
|
||||||
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) {
|
ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices,
|
||||||
return Base::operator()(internal::eval_expr_given_size(rowIndices, rows()),
|
const ColIndices& colIndices) const {
|
||||||
internal::eval_expr_given_size(colIndices, cols()));
|
return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, colIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename RowIndices, typename ColIndices>
|
template <typename RowType, size_t RowSize, typename ColIndices, typename RowIndices = Array<RowType, RowSize, 1>,
|
||||||
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
|
EnableConstOverload<RowIndices, ColIndices> = true>
|
||||||
internal::traits<ConstIndexedViewType<RowIndices, ColIndices>>::ReturnAsScalar,
|
ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize],
|
||||||
CoeffReturnType>
|
const ColIndices& colIndices) const {
|
||||||
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) const {
|
return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, colIndices);
|
||||||
return Base::operator()(internal::eval_expr_given_size(rowIndices, rows()),
|
|
||||||
internal::eval_expr_given_size(colIndices, cols()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overloads for 1D vectors/arrays
|
template <typename RowIndices, typename ColType, size_t ColSize, typename ColIndices = Array<ColType, ColSize, 1>,
|
||||||
|
EnableConstOverload<RowIndices, ColIndices> = true>
|
||||||
|
ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices,
|
||||||
|
const ColType (&colIndices)[ColSize]) const {
|
||||||
|
return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, ColIndices{colIndices});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename RowType, size_t RowSize, typename ColType, size_t ColSize,
|
||||||
|
typename RowIndices = Array<RowType, RowSize, 1>, typename ColIndices = Array<ColType, ColSize, 1>,
|
||||||
|
EnableConstOverload<RowIndices, ColIndices> = true>
|
||||||
|
ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize],
|
||||||
|
const ColType (&colIndices)[ColSize]) const {
|
||||||
|
return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, ColIndices{colIndices});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public API for 1D vectors/arrays
|
||||||
|
|
||||||
|
// non-const versions
|
||||||
|
|
||||||
template <typename Indices>
|
template <typename Indices>
|
||||||
std::enable_if_t<IsRowMajor && (!(internal::get_compile_time_incr<IvcType<Indices>>::value == 1 ||
|
using VectorIndexedViewType = typename VectorIndexedViewSelector<Indices>::ReturnType;
|
||||||
internal::is_valid_index_type<Indices>::value)),
|
|
||||||
IndexedView<Derived, IvcIndex, IvcType<Indices>>>
|
template <typename Indices, EnableVectorOverload<Indices> = true>
|
||||||
operator()(const Indices& indices) {
|
VectorIndexedViewType<Indices> operator()(const Indices& indices) {
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return IndexedView<Derived, IvcIndex, IvcType<Indices>>(derived(), IvcIndex(0), ivcCol(indices));
|
return VectorIndexedViewSelector<Indices>::run(derived(), indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename IndexType, size_t Size, typename Indices = Array<IndexType, Size, 1>,
|
||||||
|
EnableVectorOverload<Indices> = true>
|
||||||
|
VectorIndexedViewType<Indices> operator()(const IndexType (&indices)[Size]) {
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
|
return VectorIndexedViewSelector<Indices>::run(derived(), Indices{indices});
|
||||||
|
}
|
||||||
|
|
||||||
|
// const versions
|
||||||
|
|
||||||
template <typename Indices>
|
template <typename Indices>
|
||||||
std::enable_if_t<IsRowMajor && (!(internal::get_compile_time_incr<IvcType<Indices>>::value == 1 ||
|
using ConstVectorIndexedViewType = typename VectorIndexedViewSelector<Indices>::ConstReturnType;
|
||||||
internal::is_valid_index_type<Indices>::value)),
|
|
||||||
IndexedView<const Derived, IvcIndex, IvcType<Indices>>>
|
template <typename Indices, EnableConstVectorOverload<Indices> = true>
|
||||||
operator()(const Indices& indices) const {
|
ConstVectorIndexedViewType<Indices> operator()(const Indices& indices) const {
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return IndexedView<const Derived, IvcIndex, IvcType<Indices>>(derived(), IvcIndex(0), ivcCol(indices));
|
return VectorIndexedViewSelector<Indices>::run(derived(), indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Indices>
|
template <typename IndexType, size_t Size, typename Indices = Array<IndexType, Size, 1>,
|
||||||
std::enable_if_t<(!IsRowMajor) && (!(internal::get_compile_time_incr<IvcType<Indices>>::value == 1 ||
|
EnableConstVectorOverload<Indices> = true>
|
||||||
internal::is_valid_index_type<Indices>::value)),
|
ConstVectorIndexedViewType<Indices> operator()(const IndexType (&indices)[Size]) const {
|
||||||
IndexedView<Derived, IvcType<Indices>, IvcIndex>>
|
|
||||||
operator()(const Indices& indices) {
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
return IndexedView<Derived, IvcType<Indices>, IvcIndex>(derived(), ivcRow(indices), IvcIndex(0));
|
return VectorIndexedViewSelector<Indices>::run(derived(), Indices{indices});
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Indices>
|
|
||||||
std::enable_if_t<(!IsRowMajor) && (!(internal::get_compile_time_incr<IvcType<Indices>>::value == 1 ||
|
|
||||||
internal::is_valid_index_type<Indices>::value)),
|
|
||||||
IndexedView<const Derived, IvcType<Indices>, IvcIndex>>
|
|
||||||
operator()(const Indices& indices) const {
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
|
||||||
return IndexedView<const Derived, IvcType<Indices>, IvcIndex>(derived(), ivcRow(indices), IvcIndex(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Indices>
|
|
||||||
std::enable_if_t<(internal::get_compile_time_incr<IvcType<Indices>>::value == 1) &&
|
|
||||||
(!internal::is_valid_index_type<Indices>::value) && (!symbolic::is_symbolic<Indices>::value),
|
|
||||||
VectorBlock<Derived, internal::array_size<Indices>::value>>
|
|
||||||
operator()(const Indices& indices) {
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
|
||||||
IvcType<Indices> actualIndices = ivcSize(indices);
|
|
||||||
return VectorBlock<Derived, internal::array_size<Indices>::value>(derived(), internal::first(actualIndices),
|
|
||||||
internal::index_list_size(actualIndices));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Indices>
|
|
||||||
std::enable_if_t<(internal::get_compile_time_incr<IvcType<Indices>>::value == 1) &&
|
|
||||||
(!internal::is_valid_index_type<Indices>::value) && (!symbolic::is_symbolic<Indices>::value),
|
|
||||||
VectorBlock<const Derived, internal::array_size<Indices>::value>>
|
|
||||||
operator()(const Indices& indices) const {
|
|
||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
|
||||||
IvcType<Indices> actualIndices = ivcSize(indices);
|
|
||||||
return VectorBlock<const Derived, internal::array_size<Indices>::value>(derived(), internal::first(actualIndices),
|
|
||||||
internal::index_list_size(actualIndices));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IndexType>
|
|
||||||
std::enable_if_t<symbolic::is_symbolic<IndexType>::value && internal::is_lvalue<Derived>::value, Scalar&> operator()(const IndexType& id) {
|
|
||||||
return Base::operator()(internal::eval_expr_given_size(id, size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename IndexType>
|
|
||||||
std::enable_if_t<symbolic::is_symbolic<IndexType>::value, CoeffReturnType> operator()(const IndexType& id) const {
|
|
||||||
return Base::operator()(internal::eval_expr_given_size(id, size()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // EIGEN_PARSED_BY_DOXYGEN
|
#else // EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
@ -295,6 +295,69 @@ void check_indexed_view()
|
|||||||
VERIFY_IS_EQUAL( a(std::array<int,3>{1,3,5}).SizeAtCompileTime, 3 );
|
VERIFY_IS_EQUAL( a(std::array<int,3>{1,3,5}).SizeAtCompileTime, 3 );
|
||||||
VERIFY_IS_EQUAL( b(std::array<int,3>{1,3,5}).SizeAtCompileTime, 3 );
|
VERIFY_IS_EQUAL( b(std::array<int,3>{1,3,5}).SizeAtCompileTime, 3 );
|
||||||
|
|
||||||
|
// check different index types (C-style array, STL container, Eigen type)
|
||||||
|
{
|
||||||
|
Index size = 10;
|
||||||
|
ArrayXd r = ArrayXd::Random(size);
|
||||||
|
ArrayXi idx = ArrayXi::EqualSpaced(size, 0, 1);
|
||||||
|
std::shuffle(idx.begin(), idx.end(), std::random_device());
|
||||||
|
|
||||||
|
int c_array[3] = { idx[0], idx[1], idx[2] };
|
||||||
|
std::vector<int> std_vector{ idx[0], idx[1], idx[2] };
|
||||||
|
Matrix<int, 3, 1> eigen_matrix{ idx[0], idx[1], idx[2] };
|
||||||
|
|
||||||
|
// non-const access
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r({ idx[0], idx[1], idx[2] }), r(c_array));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r({ idx[0], idx[1], idx[2] }), r(std_vector));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r({ idx[0], idx[1], idx[2] }), r(eigen_matrix));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r(std_vector), r(c_array));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r(std_vector), r(eigen_matrix));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r(eigen_matrix), r(c_array));
|
||||||
|
|
||||||
|
const ArrayXd& r_ref = r;
|
||||||
|
// const access
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r_ref({ idx[0], idx[1], idx[2] }), r_ref(c_array));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r_ref({ idx[0], idx[1], idx[2] }), r_ref(std_vector));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r_ref({ idx[0], idx[1], idx[2] }), r_ref(eigen_matrix));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r_ref(std_vector), r_ref(c_array));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r_ref(std_vector), r_ref(eigen_matrix));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(r_ref(eigen_matrix), r_ref(c_array));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Index rows = 8;
|
||||||
|
Index cols = 11;
|
||||||
|
ArrayXXd R = ArrayXXd::Random(rows, cols);
|
||||||
|
ArrayXi r_idx = ArrayXi::EqualSpaced(rows, 0, 1);
|
||||||
|
ArrayXi c_idx = ArrayXi::EqualSpaced(cols, 0, 1);
|
||||||
|
std::shuffle(r_idx.begin(), r_idx.end(), std::random_device());
|
||||||
|
std::shuffle(c_idx.begin(), c_idx.end(), std::random_device());
|
||||||
|
|
||||||
|
int c_array_rows[3] = { r_idx[0], r_idx[1], r_idx[2] };
|
||||||
|
int c_array_cols[4] = { c_idx[0], c_idx[1], c_idx[2], c_idx[3] };
|
||||||
|
std::vector<int> std_vector_rows{ r_idx[0], r_idx[1], r_idx[2] };
|
||||||
|
std::vector<int> std_vector_cols{ c_idx[0], c_idx[1], c_idx[2], c_idx[3] };
|
||||||
|
Matrix<int, 3, 1> eigen_matrix_rows{ r_idx[0], r_idx[1], r_idx[2] };
|
||||||
|
Matrix<int, 4, 1> eigen_matrix_cols{ c_idx[0], c_idx[1], c_idx[2], c_idx[3] };
|
||||||
|
|
||||||
|
// non-const access
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R({ r_idx[0], r_idx[1], r_idx[2] }, { c_idx[0], c_idx[1], c_idx[2], c_idx[3] }), R(c_array_rows, c_array_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R({ r_idx[0], r_idx[1], r_idx[2] }, { c_idx[0], c_idx[1], c_idx[2], c_idx[3] }), R(std_vector_rows, std_vector_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R({ r_idx[0], r_idx[1], r_idx[2] }, { c_idx[0], c_idx[1], c_idx[2], c_idx[3] }), R(eigen_matrix_rows, eigen_matrix_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R(std_vector_rows, std_vector_cols), R(c_array_rows, c_array_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R(std_vector_rows, std_vector_cols), R(eigen_matrix_rows, eigen_matrix_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R(eigen_matrix_rows, eigen_matrix_cols), R(c_array_rows, c_array_cols));
|
||||||
|
|
||||||
|
const ArrayXXd& R_ref = R;
|
||||||
|
// const access
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R_ref({ r_idx[0], r_idx[1], r_idx[2] }, { c_idx[0], c_idx[1], c_idx[2], c_idx[3] }), R_ref(c_array_rows, c_array_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R_ref({ r_idx[0], r_idx[1], r_idx[2] }, { c_idx[0], c_idx[1], c_idx[2], c_idx[3] }), R_ref(std_vector_rows, std_vector_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R_ref({ r_idx[0], r_idx[1], r_idx[2] }, { c_idx[0], c_idx[1], c_idx[2], c_idx[3] }), R_ref(eigen_matrix_rows, eigen_matrix_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R_ref(std_vector_rows, std_vector_cols), R_ref(c_array_rows, c_array_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R_ref(std_vector_rows, std_vector_cols), R_ref(eigen_matrix_rows, eigen_matrix_cols));
|
||||||
|
VERIFY_IS_CWISE_EQUAL(R_ref(eigen_matrix_rows, eigen_matrix_cols), R_ref(c_array_rows, c_array_cols));
|
||||||
|
}
|
||||||
|
|
||||||
// check mat(i,j) with weird types for i and j
|
// check mat(i,j) with weird types for i and j
|
||||||
{
|
{
|
||||||
VERIFY_IS_APPROX( A(B.RowsAtCompileTime-1, 1), A(3,1) );
|
VERIFY_IS_APPROX( A(B.RowsAtCompileTime-1, 1), A(3,1) );
|
||||||
@ -357,8 +420,33 @@ void check_indexed_view()
|
|||||||
A(XX,Y) = 1;
|
A(XX,Y) = 1;
|
||||||
A(X,YY) = 1;
|
A(X,YY) = 1;
|
||||||
// check symbolic indices
|
// check symbolic indices
|
||||||
a(last) = 1;
|
a(last) = 1.0;
|
||||||
A(last, last) = 1;
|
A(last, last) = 1;
|
||||||
|
// check weird non-const, non-lvalue scenarios
|
||||||
|
{
|
||||||
|
// in these scenarios, the objects are not declared 'const', and the compiler will atttempt to use the non-const
|
||||||
|
// overloads without intervention
|
||||||
|
|
||||||
|
// non-const map to a const object
|
||||||
|
Map<const ArrayXd> a_map(a.data(), a.size());
|
||||||
|
Map<const ArrayXXi> A_map(A.data(), A.rows(), A.cols());
|
||||||
|
|
||||||
|
VERIFY_IS_EQUAL(a_map(last), a.coeff(a.size() - 1));
|
||||||
|
VERIFY_IS_EQUAL(A_map(last, last), A.coeff(A.rows() - 1, A.cols() - 1));
|
||||||
|
|
||||||
|
// non-const expressions that have no modifiable data
|
||||||
|
using Op = internal::scalar_constant_op<double>;
|
||||||
|
using VectorXpr = CwiseNullaryOp<Op, VectorXd>;
|
||||||
|
using MatrixXpr = CwiseNullaryOp<Op, MatrixXd>;
|
||||||
|
double constant_val = internal::random<double>();
|
||||||
|
Op op(constant_val);
|
||||||
|
VectorXpr vectorXpr(10, 1, op);
|
||||||
|
MatrixXpr matrixXpr(8, 11, op);
|
||||||
|
|
||||||
|
VERIFY_IS_EQUAL(vectorXpr.coeff(vectorXpr.size() - 1), vectorXpr(last));
|
||||||
|
VERIFY_IS_EQUAL(matrixXpr.coeff(matrixXpr.rows() - 1, matrixXpr.cols() - 1), matrixXpr(last, last));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check compilation of varying integer types as index types:
|
// Check compilation of varying integer types as index types:
|
||||||
Index i = n/2;
|
Index i = n/2;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user