blob: b796b397fb3a54fe1961c660747fcb4e89f73e8e [file] [log] [blame]
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// 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/.
#if !defined(EIGEN_PARSED_BY_DOXYGEN)
protected:
// define some aliases to ease readability
template <typename Indices>
using IvcRowType = typename internal::IndexedViewCompatibleType<Indices, RowsAtCompileTime>::type;
template <typename Indices>
using IvcColType = typename internal::IndexedViewCompatibleType<Indices, ColsAtCompileTime>::type;
template <typename Indices>
using IvcType = typename internal::IndexedViewCompatibleType<Indices, SizeAtCompileTime>::type;
typedef typename internal::IndexedViewCompatibleType<Index, 1>::type IvcIndex;
template <typename Indices>
IvcRowType<Indices> ivcRow(const Indices& indices) const {
return internal::makeIndexedViewCompatible(
indices, internal::variable_if_dynamic<Index, RowsAtCompileTime>(derived().rows()), Specialized);
}
template <typename Indices>
IvcColType<Indices> ivcCol(const Indices& indices) const {
return internal::makeIndexedViewCompatible(
indices, internal::variable_if_dynamic<Index, ColsAtCompileTime>(derived().cols()), Specialized);
}
template <typename Indices>
IvcColType<Indices> ivcSize(const Indices& indices) const {
return internal::makeIndexedViewCompatible(
indices, internal::variable_if_dynamic<Index, SizeAtCompileTime>(derived().size()), Specialized);
}
public:
template <typename RowIndices, typename ColIndices>
using IndexedViewType = IndexedView<Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
template <typename RowIndices, typename ColIndices>
using ConstIndexedViewType = IndexedView<const Derived, IvcRowType<RowIndices>, IvcColType<ColIndices>>;
// This is the generic version
template <typename RowIndices, typename 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>
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
internal::traits<ConstIndexedViewType<RowIndices, ColIndices>>::ReturnAsIndexedView,
ConstIndexedViewType<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 ColIndices>
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
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>
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
internal::traits<ConstIndexedViewType<RowIndices, ColIndices>>::ReturnAsBlock,
typename internal::traits<ConstIndexedViewType<RowIndices, ColIndices>>::BlockType>
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) const {
typedef typename internal::traits<ConstIndexedViewType<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));
}
// The following overload returns a Scalar
template <typename RowIndices, typename ColIndices>
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
internal::traits<IndexedViewType<RowIndices, ColIndices>>::ReturnAsScalar && internal::is_lvalue<Derived>::value,
Scalar&>
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) {
return Base::operator()(internal::eval_expr_given_size(rowIndices, rows()),
internal::eval_expr_given_size(colIndices, cols()));
}
template <typename RowIndices, typename ColIndices>
std::enable_if_t<internal::valid_indexed_view_overload<RowIndices, ColIndices>::value &&
internal::traits<ConstIndexedViewType<RowIndices, ColIndices>>::ReturnAsScalar,
CoeffReturnType>
operator()(const RowIndices& rowIndices, const ColIndices& colIndices) const {
return Base::operator()(internal::eval_expr_given_size(rowIndices, rows()),
internal::eval_expr_given_size(colIndices, cols()));
}
// Overloads for 1D vectors/arrays
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<Derived, IvcIndex, IvcType<Indices>>>
operator()(const Indices& indices) {
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return IndexedView<Derived, IvcIndex, IvcType<Indices>>(derived(), IvcIndex(0), ivcCol(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, IvcIndex, IvcType<Indices>>>
operator()(const Indices& indices) const {
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return IndexedView<const Derived, IvcIndex, IvcType<Indices>>(derived(), IvcIndex(0), ivcCol(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<Derived, IvcType<Indices>, IvcIndex>>
operator()(const Indices& indices) {
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return IndexedView<Derived, IvcType<Indices>, IvcIndex>(derived(), ivcRow(indices), IvcIndex(0));
}
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
/**
* \returns a generic submatrix view defined by the rows and columns indexed \a rowIndices and \a colIndices respectively.
*
* Each parameter must either be:
* - An integer indexing a single row or column
* - Eigen::placeholders::all indexing the full set of respective rows or columns in increasing order
* - An ArithmeticSequence as returned by the Eigen::seq and Eigen::seqN functions
* - Any %Eigen's vector/array of integers or expressions
* - Plain C arrays: \c int[N]
* - And more generally any type exposing the following two member functions:
* \code
* <integral type> operator[](<integral type>) const;
* <integral type> size() const;
* \endcode
* where \c <integral \c type> stands for any integer type compatible with Eigen::Index (i.e. \c std::ptrdiff_t).
*
* The last statement implies compatibility with \c std::vector, \c std::valarray, \c std::array, many of the Range-v3's ranges, etc.
*
* If the submatrix can be represented using a starting position \c (i,j) and positive sizes \c (rows,columns), then this
* method will returns a Block object after extraction of the relevant information from the passed arguments. This is the case
* when all arguments are either:
* - An integer
* - Eigen::placeholders::all
* - An ArithmeticSequence with compile-time increment strictly equal to 1, as returned by Eigen::seq(a,b), and Eigen::seqN(a,N).
*
* Otherwise a more general IndexedView<Derived,RowIndices',ColIndices'> object will be returned, after conversion of the inputs
* to more suitable types \c RowIndices' and \c ColIndices'.
*
* For 1D vectors and arrays, you better use the operator()(const Indices&) overload, which behave the same way but taking a single parameter.
*
* See also this <a href="https://stackoverflow.com/questions/46110917/eigen-replicate-items-along-one-dimension-without-useless-allocations">question</a> and its answer for an example of how to duplicate coefficients.
*
* \sa operator()(const Indices&), class Block, class IndexedView, DenseBase::block(Index,Index,Index,Index)
*/
template<typename RowIndices, typename ColIndices>
IndexedView_or_Block
operator()(const RowIndices& rowIndices, const ColIndices& colIndices);
/** This is an overload of operator()(const RowIndices&, const ColIndices&) for 1D vectors or arrays
*
* \only_for_vectors
*/
template<typename Indices>
IndexedView_or_VectorBlock
operator()(const Indices& indices);
#endif // EIGEN_PARSED_BY_DOXYGEN