| // 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> | 
 | inline IvcRowType<Indices> ivcRow(const Indices& indices) const { | 
 |   return internal::makeIndexedViewCompatible( | 
 |       indices, internal::variable_if_dynamic<Index, RowsAtCompileTime>(derived().rows()), Specialized); | 
 | } | 
 |  | 
 | template <typename Indices> | 
 | inline IvcColType<Indices> ivcCol(const Indices& indices) const { | 
 |   return internal::makeIndexedViewCompatible( | 
 |       indices, internal::variable_if_dynamic<Index, ColsAtCompileTime>(derived().cols()), Specialized); | 
 | } | 
 |  | 
 | template <typename Indices> | 
 | inline IvcType<Indices> ivcSize(const Indices& indices) const { | 
 |   return internal::makeIndexedViewCompatible( | 
 |       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 API for 2D matrices/arrays | 
 |  | 
 | // non-const versions | 
 |  | 
 | template <typename RowIndices, typename ColIndices> | 
 | using IndexedViewType = typename IndexedViewSelector<RowIndices, ColIndices>::ReturnType; | 
 |  | 
 | template <typename RowIndices, typename ColIndices, EnableOverload<RowIndices, ColIndices> = true> | 
 | IndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices, const ColIndices& colIndices) { | 
 |   return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, colIndices); | 
 | } | 
 |  | 
 | template <typename RowType, size_t RowSize, typename ColIndices, typename RowIndices = Array<RowType, RowSize, 1>, | 
 |           EnableOverload<RowIndices, ColIndices> = true> | 
 | IndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize], const ColIndices& colIndices) { | 
 |   return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, colIndices); | 
 | } | 
 |  | 
 | template <typename RowIndices, typename ColType, size_t ColSize, typename ColIndices = Array<ColType, ColSize, 1>, | 
 |           EnableOverload<RowIndices, ColIndices> = true> | 
 | IndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices, const ColType (&colIndices)[ColSize]) { | 
 |   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>, | 
 |           EnableOverload<RowIndices, ColIndices> = true> | 
 | IndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize], | 
 |                                                    const ColType (&colIndices)[ColSize]) { | 
 |   return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, ColIndices{colIndices}); | 
 | } | 
 |  | 
 | // const versions | 
 |  | 
 | template <typename RowIndices, typename ColIndices> | 
 | using ConstIndexedViewType = typename IndexedViewSelector<RowIndices, ColIndices>::ConstReturnType; | 
 |  | 
 | template <typename RowIndices, typename ColIndices, EnableConstOverload<RowIndices, ColIndices> = true> | 
 | ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowIndices& rowIndices, | 
 |                                                         const ColIndices& colIndices) const { | 
 |   return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), rowIndices, colIndices); | 
 | } | 
 |  | 
 | template <typename RowType, size_t RowSize, typename ColIndices, typename RowIndices = Array<RowType, RowSize, 1>, | 
 |           EnableConstOverload<RowIndices, ColIndices> = true> | 
 | ConstIndexedViewType<RowIndices, ColIndices> operator()(const RowType (&rowIndices)[RowSize], | 
 |                                                         const ColIndices& colIndices) const { | 
 |   return IndexedViewSelector<RowIndices, ColIndices>::run(derived(), RowIndices{rowIndices}, colIndices); | 
 | } | 
 |  | 
 | 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> | 
 | using VectorIndexedViewType = typename VectorIndexedViewSelector<Indices>::ReturnType; | 
 |  | 
 | template <typename Indices, EnableVectorOverload<Indices> = true> | 
 | VectorIndexedViewType<Indices> operator()(const Indices& indices) { | 
 |   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | 
 |   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> | 
 | using ConstVectorIndexedViewType = typename VectorIndexedViewSelector<Indices>::ConstReturnType; | 
 |  | 
 | template <typename Indices, EnableConstVectorOverload<Indices> = true> | 
 | ConstVectorIndexedViewType<Indices> operator()(const Indices& indices) const { | 
 |   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | 
 |   return VectorIndexedViewSelector<Indices>::run(derived(), indices); | 
 | } | 
 |  | 
 | template <typename IndexType, size_t Size, typename Indices = Array<IndexType, Size, 1>, | 
 |           EnableConstVectorOverload<Indices> = true> | 
 | ConstVectorIndexedViewType<Indices> operator()(const IndexType (&indices)[Size]) const { | 
 |   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) | 
 |   return VectorIndexedViewSelector<Indices>::run(derived(), Indices{indices}); | 
 | } | 
 |  | 
 | #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 |