#include <iostream>
#include <string>
#include <tuple>

// helper function to print a tuple of any size
template<class Tuple, std::size_t N>
struct TuplePrinter {
    static void print(const Tuple& t) 
    {
        TuplePrinter<Tuple, N-1>::print(t);
        std::cout << ", " << std::get<N-1>(t);
    }
};
 
template<class Tuple>
struct TuplePrinter<Tuple, 1> {
    static void print(const Tuple& t) 
    {
        std::cout << std::get<0>(t);
    }
};
 
template<class Tuple>
struct TuplePrinter<Tuple, 0> {
    static void print(const Tuple& t) 
    {
    }
};
 
template<class... Args>
void print(const std::tuple<Args...>& t) 
{
    std::cout << "(";
    TuplePrinter<decltype(t), sizeof...(Args)>::print(t);
    std::cout << ")\n";
}

struct Row
{
   template <int N, typename ... Args> struct Helper;

   template <typename Arg1> struct Helper<1, Arg1>
   {
      static std::tuple<Arg1> getResult(Row& r)
      {
         return std::make_tuple(r.getResult<Arg1>(0));
      }
   };

   template <int N, typename Arg1, typename ... Args>
      struct Helper<N, Arg1, Args...>
      {
         static std::tuple <Arg1, Args ...> getResult(Row& r)
         {
            return std::tuple_cat(std::make_tuple(r.getResult<Arg1>(N-1)),
                                  Helper<N-1, Args...>::getResult(r));
         }
      };

   template <typename Arg> Arg getResult(int index)
   {
      // This is where the value needs to be extracted from the row.
      // It is a dummy implementation for testing purposes.
      return Arg{};
   }

   template <typename ... Args>
      std::tuple <Args ...> getResult()
      {
         return Helper<sizeof...(Args), Args...>::getResult(*this);
      }
};

int main()
{
   Row r;
   auto res1 = r.getResult<std::string>();
   auto res2 = r.getResult<int>();
   auto res3 = r.getResult<int, double, int>();
   auto res4 = r.getResult<int, int, double, double>();
   auto res5 = r.getResult<std::string, std::string, int, int, double, double>();

   print(res1);
   print(res2);
   print(res3);
   print(res4);
   print(res5);

   return 0;
}
