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

#include "main.h"

#include <Eigen/Core>
#include <Eigen/src/Core/arch/GPU/Tuple.h>

using namespace Eigen::internal;
using Eigen::internal::tuple_impl::tuple;
  
void basic_tuple_test() {  
  // Construction.
  tuple<> tuple0 {};
  tuple<int> tuple1 {1};
  tuple<int, float> tuple2 {3, 5.0f};
  tuple<int, float, double> tuple3 {7, 11.0f, 13.0};
  // Default construction.
  tuple<> tuple0default;
  EIGEN_UNUSED_VARIABLE(tuple0default)
  tuple<int> tuple1default;
  EIGEN_UNUSED_VARIABLE(tuple1default)
  tuple<int, float> tuple2default;
  EIGEN_UNUSED_VARIABLE(tuple2default)
  tuple<int, float, double> tuple3default;
  EIGEN_UNUSED_VARIABLE(tuple3default)
  
  // Assignment.
  tuple<> tuple0b = tuple0;
  EIGEN_UNUSED_VARIABLE(tuple0b)
  decltype(tuple1) tuple1b = tuple1;
  EIGEN_UNUSED_VARIABLE(tuple1b)
  decltype(tuple2) tuple2b = tuple2;
  EIGEN_UNUSED_VARIABLE(tuple2b)
  decltype(tuple3) tuple3b = tuple3;
  EIGEN_UNUSED_VARIABLE(tuple3b)
  
  // get.
  VERIFY_IS_EQUAL(tuple_impl::get<0>(tuple3), 7);
  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple3), 11.0f);
  VERIFY_IS_EQUAL(tuple_impl::get<2>(tuple3), 13.0);
  
  // tuple_impl::tuple_size.
  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple0)>::value, size_t(0));
  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple1)>::value, size_t(1));
  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple2)>::value, size_t(2));
  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple3)>::value, size_t(3));
  
  // tuple_impl::tuple_cat.
  auto tuple2cat3 = tuple_impl::tuple_cat(tuple2, tuple3);
  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple2cat3)>::value, size_t(5));
  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple2cat3), 5.0f);
  VERIFY_IS_EQUAL(tuple_impl::get<3>(tuple2cat3), 11.0f);
  auto tuple3cat0 = tuple_impl::tuple_cat(tuple3, tuple0);
  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple3cat0)>::value, size_t(3));
  auto singlecat = tuple_impl::tuple_cat(tuple3);
  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(singlecat)>::value, size_t(3));
  auto emptycat = tuple_impl::tuple_cat();
  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(emptycat)>::value, size_t(0));
  auto tuple0cat1cat2cat3 = tuple_impl::tuple_cat(tuple0, tuple1, tuple2, tuple3);
  VERIFY_IS_EQUAL(tuple_impl::tuple_size<decltype(tuple0cat1cat2cat3)>::value, size_t(6));
  
  // make_tuple.
  // The tuple types should uses values for the second and fourth parameters.
  double tmp = 20;
  auto tuple_make = tuple_impl::make_tuple(int(10), tmp, float(20.0f), tuple0);
  VERIFY( (std::is_same<decltype(tuple_make), tuple<int, double, float, tuple<> > >::value) );
  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple_make), tmp);
  
  // forward_as_tuple.
  // The tuple types should uses references for the second and fourth parameters.
  auto tuple_forward = tuple_impl::forward_as_tuple(int(10), tmp, float(20.0f), tuple0);
  VERIFY( (std::is_same<decltype(tuple_forward), tuple<int, double&, float, tuple<>& > >::value) );
  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple_forward), tmp);
  
  // tie.
  auto tuple_tie = tuple_impl::tie(tuple0, tuple1, tuple2, tuple3);
  VERIFY( (std::is_same<decltype(tuple_tie), 
                        tuple<decltype(tuple0)&,
                              decltype(tuple1)&,
                              decltype(tuple2)&,
                              decltype(tuple3)&> >::value) );
  VERIFY_IS_EQUAL( (tuple_impl::get<1>(tuple_impl::get<2>(tuple_tie))), 5.0f );
  // Modify value and ensure tuple2 is updated.
  tuple_impl::get<1>(tuple_impl::get<2>(tuple_tie)) = 10.0f;
  VERIFY_IS_EQUAL( (tuple_impl::get<1>(tuple2)), 10.0f );
  
  // Assignment.
  int x = -1;
  float y = -1;
  double z = -1;
  tuple_impl::tie(x, y, z) = tuple3;
  VERIFY_IS_EQUAL(x, tuple_impl::get<0>(tuple3));
  VERIFY_IS_EQUAL(y, tuple_impl::get<1>(tuple3));
  VERIFY_IS_EQUAL(z, tuple_impl::get<2>(tuple3));
  tuple<int, float, double> tuple3c(-2, -2.0f, -2.0);
  tuple3c = std::move(tuple3b);
  VERIFY_IS_EQUAL(tuple_impl::get<0>(tuple3c), tuple_impl::get<0>(tuple3));
  VERIFY_IS_EQUAL(tuple_impl::get<1>(tuple3c), tuple_impl::get<1>(tuple3));
  VERIFY_IS_EQUAL(tuple_impl::get<2>(tuple3c), tuple_impl::get<2>(tuple3));
}

void eigen_tuple_test() {
  tuple<Eigen::Matrix3d, Eigen::MatrixXd> tuple;
  tuple_impl::get<0>(tuple).setRandom();
  tuple_impl::get<1>(tuple).setRandom(10, 10);
  
  auto tuple_tie = tuple_impl::tie(tuple_impl::get<0>(tuple), tuple_impl::get<1>(tuple));
  tuple_impl::get<1>(tuple_tie).setIdentity();
  VERIFY(tuple_impl::get<1>(tuple).isIdentity());
}

EIGEN_DECLARE_TEST(tuple)
{
  CALL_SUBTEST(basic_tuple_test());
  CALL_SUBTEST(eigen_tuple_test());
}
