// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2013 Christian Seiler <christian@iwakd.de>
//
// 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_TENSORSYMMETRY_STATICSYMMETRY_H
#define EIGEN_TENSORSYMMETRY_STATICSYMMETRY_H

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

namespace Eigen {

namespace internal {

template <typename indices_, int flags_>
struct tensor_static_symgroup_element {
  typedef indices_ indices;
  constexpr static int flags = flags_;
};

template <typename Gen, int... indices>
constexpr std::integer_sequence<int,
                                ((indices == Gen::One) ? Gen::Two : ((indices == Gen::Two) ? Gen::One : indices))...>
tensor_static_symgroup_swapped_indices(std::integer_sequence<int, indices...>) {
  return {};
}

template <typename Gen, int N>
struct tensor_static_symgroup_element_ctor {
  typedef tensor_static_symgroup_element<
      decltype(tensor_static_symgroup_swapped_indices<Gen>(std::make_integer_sequence<int, N>{})), Gen::Flags>
      type;
};

template <int N>
struct tensor_static_symgroup_identity_ctor {
  typedef tensor_static_symgroup_element<std::make_integer_sequence<int, N>, 0> type;
};

template <typename iib>
struct tensor_static_symgroup_multiply_helper {
  template <int... iia>
  constexpr static std::integer_sequence<int, get<iia, iib>::value...> helper(std::integer_sequence<int, iia...>) {
    return {};
  }
};

template <typename A, typename B>
struct tensor_static_symgroup_multiply {
 private:
  typedef typename A::indices iia;
  typedef typename B::indices iib;
  constexpr static int ffa = A::flags;
  constexpr static int ffb = B::flags;

 public:
  static_assert(iia::size() == iib::size(), "Cannot multiply symmetry elements with different number of indices.");

  typedef tensor_static_symgroup_element<decltype(tensor_static_symgroup_multiply_helper<iib>::helper(iia())),
                                         ffa ^ ffb>
      type;
};

template <typename A, typename B>
struct tensor_static_symgroup_equality {
  typedef typename A::indices iia;
  typedef typename B::indices iib;
  constexpr static int ffa = A::flags;
  constexpr static int ffb = B::flags;
  static_assert(iia::size() == iib::size(), "Cannot compare symmetry elements with different number of indices.");

  constexpr static bool value = std::is_same<iia, iib>::value;

 private:
  /* this should be zero if they are identical, or else the tensor
   * will be forced to be pure real, pure imaginary or even pure zero
   */
  constexpr static int flags_cmp_ = ffa ^ ffb;

  /* either they are not equal, then we don't care whether the flags
   * match, or they are equal, and then we have to check
   */
  constexpr static bool is_zero = value && flags_cmp_ == NegationFlag;
  constexpr static bool is_real = value && flags_cmp_ == ConjugationFlag;
  constexpr static bool is_imag = value && flags_cmp_ == (NegationFlag | ConjugationFlag);

 public:
  constexpr static int global_flags =
      (is_real ? GlobalRealFlag : 0) | (is_imag ? GlobalImagFlag : 0) | (is_zero ? GlobalZeroFlag : 0);
};

template <std::size_t NumIndices, typename... Gen>
struct tensor_static_symgroup {
  typedef StaticSGroup<Gen...> type;
  constexpr static std::size_t size = type::static_size;
};

template <typename Index, std::size_t N, int... ii, int... jj>
constexpr static std::array<Index, N> tensor_static_symgroup_index_permute(const std::array<Index, N>& idx,
                                                                           std::integer_sequence<int, ii...>,
                                                                           std::integer_sequence<int, jj...>) {
  return {{idx[ii]..., idx[sizeof...(ii) + jj]...}};
}

template <typename Index, int... ii>
static inline std::vector<Index> tensor_static_symgroup_index_permute(const std::vector<Index>& idx,
                                                                      std::integer_sequence<int, ii...>) {
  std::vector<Index> result{{idx[ii]...}};
  std::size_t target_size = idx.size();
  for (std::size_t i = result.size(); i < target_size; i++) result.push_back(idx[i]);
  return result;
}

template <typename T>
struct tensor_static_symgroup_do_apply;

template <typename first, typename... next>
struct tensor_static_symgroup_do_apply<internal::type_list<first, next...>> {
  template <typename Op, typename RV, std::size_t SGNumIndices, typename Index, std::size_t NumIndices,
            typename... Args>
  static inline RV run(const std::array<Index, NumIndices>& idx, RV initial, Args&&... args) {
    static_assert(NumIndices >= SGNumIndices,
                  "Can only apply symmetry group to objects that have at least the required amount of indices.");
    initial = Op::run(tensor_static_symgroup_index_permute(
                          idx, typename first::indices(), std::make_integer_sequence<int, NumIndices - SGNumIndices>{}),
                      first::flags, initial, std::forward<Args>(args)...);
    return tensor_static_symgroup_do_apply<internal::type_list<next...>>::template run<Op, RV, SGNumIndices>(
        idx, initial, args...);
  }

  template <typename Op, typename RV, std::size_t SGNumIndices, typename Index, typename... Args>
  static inline RV run(const std::vector<Index>& idx, RV initial, Args&&... args) {
    eigen_assert(idx.size() >= SGNumIndices &&
                 "Can only apply symmetry group to objects that have at least the required amount of indices.");
    initial = Op::run(tensor_static_symgroup_index_permute(idx, typename first::indices()), first::flags, initial,
                      std::forward<Args>(args)...);
    return tensor_static_symgroup_do_apply<internal::type_list<next...>>::template run<Op, RV, SGNumIndices>(
        idx, initial, args...);
  }
};

template <>
struct tensor_static_symgroup_do_apply<internal::type_list<>> {
  template <typename Op, typename RV, std::size_t SGNumIndices, typename Index, std::size_t NumIndices,
            typename... Args>
  static inline RV run(const std::array<Index, NumIndices>&, RV initial, Args&&...) {
    // do nothing
    return initial;
  }

  template <typename Op, typename RV, std::size_t SGNumIndices, typename Index, typename... Args>
  static inline RV run(const std::vector<Index>&, RV initial, Args&&...) {
    // do nothing
    return initial;
  }
};

}  // end namespace internal

template <typename... Gen>
class StaticSGroup {
  constexpr static std::size_t NumIndices = internal::tensor_symmetry_num_indices<Gen...>::value;
  typedef internal::group_theory::enumerate_group_elements<
      internal::tensor_static_symgroup_multiply, internal::tensor_static_symgroup_equality,
      typename internal::tensor_static_symgroup_identity_ctor<NumIndices>::type,
      internal::type_list<typename internal::tensor_static_symgroup_element_ctor<Gen, NumIndices>::type...>>
      group_elements;
  typedef typename group_elements::type ge;

 public:
  constexpr StaticSGroup() = default;
  constexpr StaticSGroup(const StaticSGroup<Gen...>&) = default;
  constexpr StaticSGroup(StaticSGroup<Gen...>&&) = default;

  template <typename Op, typename RV, typename Index, std::size_t N, typename... Args>
  static inline RV apply(const std::array<Index, N>& idx, RV initial, Args&&... args) {
    return internal::tensor_static_symgroup_do_apply<ge>::template run<Op, RV, NumIndices>(idx, initial, args...);
  }

  template <typename Op, typename RV, typename Index, typename... Args>
  static inline RV apply(const std::vector<Index>& idx, RV initial, Args&&... args) {
    eigen_assert(idx.size() == NumIndices);
    return internal::tensor_static_symgroup_do_apply<ge>::template run<Op, RV, NumIndices>(idx, initial, args...);
  }

  constexpr static std::size_t static_size = ge::count;

  constexpr static std::size_t size() { return ge::count; }
  constexpr static int globalFlags() { return group_elements::global_flags; }

  template <typename Tensor_, typename... IndexTypes>
  inline internal::tensor_symmetry_value_setter<Tensor_, StaticSGroup<Gen...>> operator()(
      Tensor_& tensor, typename Tensor_::Index firstIndex, IndexTypes... otherIndices) const {
    static_assert(sizeof...(otherIndices) + 1 == Tensor_::NumIndices,
                  "Number of indices used to access a tensor coefficient must be equal to the rank of the tensor.");
    return operator()(tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices>{{firstIndex, otherIndices...}});
  }

  template <typename Tensor_>
  inline internal::tensor_symmetry_value_setter<Tensor_, StaticSGroup<Gen...>> operator()(
      Tensor_& tensor, std::array<typename Tensor_::Index, Tensor_::NumIndices> const& indices) const {
    return internal::tensor_symmetry_value_setter<Tensor_, StaticSGroup<Gen...>>(tensor, *this, indices);
  }
};

}  // end namespace Eigen

#endif  // EIGEN_TENSORSYMMETRY_STATICSYMMETRY_H

/*
 * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle;
 */
