Tuple.h

// Tuple.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2022

#pragma once
#ifndef Ceda_cxUtils_Tuple_H
#define Ceda_cxUtils_Tuple_H

#include "xostream.h"
#include <tuple>

namespace ceda
{

template < typename T , typename... Ts >
auto head( std::tuple<T,Ts...> t )
{
   return  std::get<0>(t);
}

template < std::size_t... Ns , typename... Ts >
auto tail_impl( std::index_sequence<Ns...> , std::tuple<Ts...> t )
{
   return  std::make_tuple( std::get<Ns+1u>(t)... );
}

template < typename... Ts >
auto tail( std::tuple<Ts...> t )
{
   return  tail_impl( std::make_index_sequence<sizeof...(Ts) - 1u>() , t );
}

template<ssize_t i, typename... Ts>
void WriteTuple_detail(xostream& os, const std::tuple<Ts...>& t)
{
    if constexpr(i > 0)
        os << ',';
    os << std::get<i>(t);
    if constexpr(i+1 < std::tuple_size_v<std::tuple<Ts...>>)
        WriteTuple_detail<i+1>(os, t);
}

template<typename... Ts>
xostream& operator<<(xostream& os, const std::tuple<Ts...>& t)
{
    os << '(';
    WriteTuple_detail<0>(os, t);
    os << ')';
    return os;
}

}

#endif // include guard