#include "YODA/Exceptions.h"
#include "YODA/Utils/ndarray.h"
#include <array>
#include <cstdlib>
#include <iostream>
#include <string>
#include <utility>

using namespace std;
using namespace YODA;

int main() {

  using Pair = pair<double,double>;

  // Nullary constructors
  (void)Utils::ndarray<int,1>();
  (void)Utils::ndarray<double,2>();
  (void)Utils::ndarray<string,3>();
  (void)Utils::ndarray<Pair,1>();

  vector<int> vec{1, 2, 3, 4, 5};
  Utils::ndarray<int,5> narr1(vec);

  for (Utils::ndarray<int,5>::const_iterator it = narr1.begin(); it != narr1.end(); ++it) {
    cout << *it << endl;
  }

  for (int i = 0; i < 5; ++i) {
    if (narr1[i] != i+1) return EXIT_FAILURE;
    narr1[i] = 5-i;
  }
  narr1.clear();

  array<double,6> arr{0.0, 0.2, 0.5, 0.6, 0.8, 1.0};
  Utils::ndarray<double,6> narr2(arr);
  narr2.clear();

  vector<string> labels{"A"s, "B"s, "C"s};
  Utils::ndarray<string,3> narr3(labels);

  size_t idx = 0;
  for (const string& str : narr3) {
    if (str != labels[idx++]) return EXIT_FAILURE;
  }
  narr3.clear();

  Utils::ndarray<Pair,1> narr4({{1.0,2.0}});
  if (int(narr4[0].first + narr4[0].second + 0.5) != 3)  return EXIT_FAILURE;
  narr4.clear();

  try {
    Utils::ndarray<int,4> narr2(vec);
    return EXIT_FAILURE;
  }
  catch (const RangeError&) {
    return EXIT_SUCCESS;
  }
}
