// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2024 Charles Schlosser <cs.schlosser@gmail.com>
//
// 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/.
// SPDX-License-Identifier: MPL-2.0

#ifndef EIGEN_FILL_H
#define EIGEN_FILL_H

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

namespace Eigen {

namespace internal {

template <typename Xpr>
struct eigen_fill_helper : std::false_type {};

// Only enable std::fill_n for trivially copyable scalars.  GCC's libstdc++
// fill_n pessimizes non-trivially-copyable types (extra moves per iteration),
// causing measurable regressions for types like AutoDiffScalar (issue #2956).
template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
struct eigen_fill_helper<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> : std::is_trivially_copyable<Scalar> {};

template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
struct eigen_fill_helper<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols>> : std::is_trivially_copyable<Scalar> {};

template <typename Xpr, int BlockRows, int BlockCols>
struct eigen_fill_helper<Block<Xpr, BlockRows, BlockCols, /*InnerPanel*/ true>> : eigen_fill_helper<Xpr> {};

template <typename Xpr, int BlockRows, int BlockCols>
struct eigen_fill_helper<Block<Xpr, BlockRows, BlockCols, /*InnerPanel*/ false>>
    : bool_constant<eigen_fill_helper<Xpr>::value && (Xpr::IsRowMajor ? (BlockRows == 1) : (BlockCols == 1))> {};

template <typename Xpr, int Options>
struct eigen_fill_helper<Map<Xpr, Options, Stride<0, 0>>> : eigen_fill_helper<Xpr> {};

template <typename Xpr, int Options, int OuterStride_>
struct eigen_fill_helper<Map<Xpr, Options, Stride<OuterStride_, 0>>>
    : bool_constant<eigen_fill_helper<Xpr>::value && enum_eq_not_dynamic(OuterStride_, Xpr::InnerSizeAtCompileTime)> {};

template <typename Xpr, int Options, int OuterStride_>
struct eigen_fill_helper<Map<Xpr, Options, Stride<OuterStride_, 1>>>
    : eigen_fill_helper<Map<Xpr, Options, Stride<OuterStride_, 0>>> {};

template <typename Xpr, int Options, int InnerStride_>
struct eigen_fill_helper<Map<Xpr, Options, InnerStride<InnerStride_>>>
    : eigen_fill_helper<Map<Xpr, Options, Stride<0, InnerStride_>>> {};

template <typename Xpr, int Options, int OuterStride_>
struct eigen_fill_helper<Map<Xpr, Options, OuterStride<OuterStride_>>>
    : eigen_fill_helper<Map<Xpr, Options, Stride<OuterStride_, 0>>> {};

template <typename Xpr>
struct eigen_fill_impl<Xpr, /*use_fill*/ false> {
  using Scalar = typename Xpr::Scalar;
  using PlainObject = typename Xpr::PlainObject;
  using Constant = typename PlainObject::ConstantReturnType;
  static EIGEN_DEVICE_FUNC constexpr void run(Xpr& dst, const Scalar& val) {
    const Constant src(dst.rows(), dst.cols(), val);
    run(dst, src);
  }
  template <typename SrcXpr>
  static EIGEN_DEVICE_FUNC constexpr void run(Xpr& dst, const SrcXpr& src) {
    call_dense_assignment_loop(dst, src, assign_op<Scalar, Scalar>());
  }
};

#if EIGEN_COMP_MSVC || defined(EIGEN_GPU_COMPILE_PHASE)
template <typename Xpr>
struct eigen_fill_impl<Xpr, /*use_fill*/ true> : eigen_fill_impl<Xpr, /*use_fill*/ false> {};
#else
template <typename Xpr>
struct eigen_fill_impl<Xpr, /*use_fill*/ true> {
  using Scalar = typename Xpr::Scalar;
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Xpr& dst, const Scalar& val) {
    const Scalar val_copy = val;
    using std::fill_n;
    fill_n(dst.data(), dst.size(), val_copy);
  }
  template <typename SrcXpr>
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Xpr& dst, const SrcXpr& src) {
    resize_if_allowed(dst, src, assign_op<Scalar, Scalar>());
    const Scalar& val = src.functor()();
    run(dst, val);
  }
};
#endif

template <typename Xpr>
struct eigen_memset_helper {
  using Scalar = typename Xpr::Scalar;
  static constexpr bool value = std::is_trivially_copyable<Scalar>::value &&
                                !static_cast<bool>(NumTraits<Scalar>::RequireInitialization) &&
                                eigen_fill_helper<Xpr>::value;
};

template <typename Xpr>
struct eigen_zero_impl<Xpr, /*use_memset*/ false> {
  using Scalar = typename Xpr::Scalar;
  using PlainObject = typename Xpr::PlainObject;
  using Zero = typename PlainObject::ZeroReturnType;
  static EIGEN_DEVICE_FUNC constexpr void run(Xpr& dst) {
    const Zero src(dst.rows(), dst.cols());
    run(dst, src);
  }
  template <typename SrcXpr>
  static EIGEN_DEVICE_FUNC constexpr void run(Xpr& dst, const SrcXpr& src) {
    call_dense_assignment_loop(dst, src, assign_op<Scalar, Scalar>());
  }
};

template <typename Xpr>
struct eigen_zero_impl<Xpr, /*use_memset*/ true> {
  using Scalar = typename Xpr::Scalar;
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Xpr& dst) {
    Index size = dst.size();
    EIGEN_IF_CONSTEXPR (Xpr::MaxSizeAtCompileTime != Dynamic) {
      if (size > Xpr::MaxSizeAtCompileTime) {
        eigen_internal_assert(false && "invalid dense object size");
        return;
      }
    }
    const std::ptrdiff_t num_bytes = size * static_cast<std::ptrdiff_t>(sizeof(Scalar));
    if (num_bytes <= 0) return;
    void* dst_ptr = static_cast<void*>(dst.data());
#ifndef EIGEN_NO_DEBUG
    eigen_assert((dst_ptr != nullptr) && "null pointer dereference error!");
#endif
    EIGEN_USING_STD(memset);
    memset(dst_ptr, 0, static_cast<std::size_t>(num_bytes));
  }
  template <typename SrcXpr>
  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Xpr& dst, const SrcXpr& src) {
    resize_if_allowed(dst, src, assign_op<Scalar, Scalar>());
    run(dst);
  }
};

}  // namespace internal
}  // namespace Eigen

#endif  // EIGEN_FILL_H
