// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009-2010 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/.

#ifndef EIGEN_REPLICATE_H
#define EIGEN_REPLICATE_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

namespace internal {
template <typename MatrixType, int RowFactor, int ColFactor>
struct traits<Replicate<MatrixType, RowFactor, ColFactor> > : traits<MatrixType> {
  typedef typename MatrixType::Scalar Scalar;
  typedef typename traits<MatrixType>::StorageKind StorageKind;
  typedef typename traits<MatrixType>::XprKind XprKind;
  typedef typename ref_selector<MatrixType>::type MatrixTypeNested;
  typedef std::remove_reference_t<MatrixTypeNested> MatrixTypeNested_;
  enum {
    RowsAtCompileTime = RowFactor == Dynamic || int(MatrixType::RowsAtCompileTime) == Dynamic
                            ? Dynamic
                            : RowFactor * MatrixType::RowsAtCompileTime,
    ColsAtCompileTime = ColFactor == Dynamic || int(MatrixType::ColsAtCompileTime) == Dynamic
                            ? Dynamic
                            : ColFactor * MatrixType::ColsAtCompileTime,
    // FIXME we don't propagate the max sizes !!!
    MaxRowsAtCompileTime = RowsAtCompileTime,
    MaxColsAtCompileTime = ColsAtCompileTime,
    IsRowMajor = MaxRowsAtCompileTime == 1 && MaxColsAtCompileTime != 1   ? 1
                 : MaxColsAtCompileTime == 1 && MaxRowsAtCompileTime != 1 ? 0
                 : (MatrixType::Flags & RowMajorBit)                      ? 1
                                                                          : 0,

    // FIXME enable DirectAccess with negative strides?
    Flags = IsRowMajor ? RowMajorBit : 0
  };
};
}  // namespace internal

/**
 * \class Replicate
 * \ingroup Core_Module
 *
 * \brief Expression of the multiple replication of a matrix or vector
 *
 * \tparam MatrixType the type of the object we are replicating
 * \tparam RowFactor number of repetitions at compile time along the vertical direction, can be Dynamic.
 * \tparam ColFactor number of repetitions at compile time along the horizontal direction, can be Dynamic.
 *
 * This class represents an expression of the multiple replication of a matrix or vector.
 * It is the return type of DenseBase::replicate() and most of the time
 * this is the only way it is used.
 *
 * \sa DenseBase::replicate()
 */
template <typename MatrixType, int RowFactor, int ColFactor>
class Replicate : public internal::dense_xpr_base<Replicate<MatrixType, RowFactor, ColFactor> >::type {
  typedef typename internal::traits<Replicate>::MatrixTypeNested MatrixTypeNested;
  typedef typename internal::traits<Replicate>::MatrixTypeNested_ MatrixTypeNested_;

 public:
  typedef typename internal::dense_xpr_base<Replicate>::type Base;
  EIGEN_DENSE_PUBLIC_INTERFACE(Replicate)
  typedef internal::remove_all_t<MatrixType> NestedExpression;

  template <typename OriginalMatrixType>
  EIGEN_DEVICE_FUNC inline explicit Replicate(const OriginalMatrixType& matrix)
      : m_matrix(matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor) {
    EIGEN_STATIC_ASSERT((internal::is_same<std::remove_const_t<MatrixType>, OriginalMatrixType>::value),
                        THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
    eigen_assert(RowFactor != Dynamic && ColFactor != Dynamic);
  }

  template <typename OriginalMatrixType>
  EIGEN_DEVICE_FUNC inline Replicate(const OriginalMatrixType& matrix, Index rowFactor, Index colFactor)
      : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) {
    EIGEN_STATIC_ASSERT((internal::is_same<std::remove_const_t<MatrixType>, OriginalMatrixType>::value),
                        THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
  }

  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index rows() const { return m_matrix.rows() * m_rowFactor.value(); }
  EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index cols() const { return m_matrix.cols() * m_colFactor.value(); }

  EIGEN_DEVICE_FUNC const MatrixTypeNested_& nestedExpression() const { return m_matrix; }

 protected:
  MatrixTypeNested m_matrix;
  const internal::variable_if_dynamic<Index, RowFactor> m_rowFactor;
  const internal::variable_if_dynamic<Index, ColFactor> m_colFactor;
};

/**
 * \return an expression of the replication of \c *this
 *
 * Example: \include MatrixBase_replicate.cpp
 * Output: \verbinclude MatrixBase_replicate.out
 *
 * \sa VectorwiseOp::replicate(), DenseBase::replicate(Index,Index), class Replicate
 */
template <typename Derived>
template <int RowFactor, int ColFactor>
EIGEN_DEVICE_FUNC const Replicate<Derived, RowFactor, ColFactor> DenseBase<Derived>::replicate() const {
  return Replicate<Derived, RowFactor, ColFactor>(derived());
}

/**
 * \return an expression of the replication of each column (or row) of \c *this
 *
 * Example: \include DirectionWise_replicate_int.cpp
 * Output: \verbinclude DirectionWise_replicate_int.out
 *
 * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate
 */
template <typename ExpressionType, int Direction>
EIGEN_DEVICE_FUNC const typename VectorwiseOp<ExpressionType, Direction>::ReplicateReturnType
VectorwiseOp<ExpressionType, Direction>::replicate(Index factor) const {
  return typename VectorwiseOp<ExpressionType, Direction>::ReplicateReturnType(
      _expression(), Direction == Vertical ? factor : 1, Direction == Horizontal ? factor : 1);
}

}  // end namespace Eigen

#endif  // EIGEN_REPLICATE_H
