#ifndef TUPLE_TO_VECTOR_PROCESSOR_HPP
#define TUPLE_TO_VECTOR_PROCESSOR_HPP

#include <node_processor/INodeProcessor.hpp>

template <typename TupleProcessorT, size_t N>
class TupleToVectorProcessor final : public INodeProcessor
{
 private:
  ASTNode& m_node;

  std::unique_ptr<TupleProcessorT> m_tuple_processor;

 public:
  DataVariant
  execute(ExecutionPolicy& exec_policy)
  {
    AggregateDataVariant v = std::get<AggregateDataVariant>(m_tuple_processor->execute(exec_policy));

    Assert(v.size() == N);

    TinyVector<N> x;

    for (size_t i = 0; i < N; ++i) {
      std::visit(
        [&](auto&& v) {
          using ValueT = std::decay_t<decltype(v)>;
          if constexpr (std::is_arithmetic_v<ValueT>) {
            x[i] = v;
          } else {
            // LCOV_EXCL_START
            Assert(false, "unexpected value type");
            // LCOV_EXCL_STOP
          }
        },
        v[i]);
    }

    return DataVariant{std::move(x)};
  }

  TupleToVectorProcessor(ASTNode& node) : m_node{node}, m_tuple_processor{std::make_unique<TupleProcessorT>(node)} {}

  TupleToVectorProcessor(ASTNode& node, std::unique_ptr<TupleProcessorT>&& tuple_processor)
    : m_node{node}, m_tuple_processor{std::move(tuple_processor)}
  {}
};

#endif   // TUPLE_TO_VECTOR_PROCESSOR_HPP