forked from Alepha/Alepha
77 lines
1.7 KiB
C++
77 lines
1.7 KiB
C++
static_assert( __cplusplus >= 2023'02 );
|
|
|
|
#pragma once
|
|
|
|
#include <Alepha/Alepha.h>
|
|
|
|
#include <tuple>
|
|
#include <type_traits>
|
|
|
|
#include <Alepha/Concepts.h>
|
|
|
|
namespace Alepha::Hydrogen::Utility ::detail:: tuple_algorithms_m
|
|
{
|
|
namespace tuple
|
|
{
|
|
template< typename First, typename ... Args >
|
|
auto car( std::tuple< First, Args... > tuple );
|
|
|
|
auto cdr( Concepts::Tuple auto tuple );
|
|
|
|
template< typename ... Args >
|
|
auto reverse( std::tuple< Args... > tuple );
|
|
}
|
|
|
|
template< typename First, typename ... Args >
|
|
auto
|
|
tuple::car( std::tuple< First, Args... > tuple )
|
|
{
|
|
return std::get< 0 >( tuple );
|
|
}
|
|
|
|
template< std::size_t first, std::size_t ... rest >
|
|
auto
|
|
cdr_index_sequence( std::index_sequence< first, rest... > )
|
|
{
|
|
return std::index_sequence< rest... >{};
|
|
}
|
|
|
|
template< typename ... Args >
|
|
auto
|
|
cdr_indices( const std::tuple< Args... > & )
|
|
{
|
|
return cdr_index_sequence( std::make_index_sequence< sizeof...( Args ) >{} );
|
|
}
|
|
|
|
template< std::size_t ... ints >
|
|
auto
|
|
get_indices( Concepts::Tuple auto tuple, std::index_sequence< ints... > )
|
|
{
|
|
return std::tuple{ std::get< ints >( tuple )... };
|
|
}
|
|
|
|
auto
|
|
tuple::cdr( Concepts::Tuple auto tuple )
|
|
{
|
|
return get_indices( tuple, cdr_indices( tuple ) );
|
|
}
|
|
|
|
template< typename ... Args >
|
|
auto
|
|
tuple::reverse( std::tuple< Args... > tuple )
|
|
{
|
|
if constexpr( sizeof...( Args ) == 0 ) return std::tuple{};
|
|
else return std::tuple_cat( tuple::reverse( cdr( tuple ) ), std::tuple{ car( tuple ) } );
|
|
}
|
|
|
|
inline namespace exports
|
|
{
|
|
namespace tuple= tuple_algorithms_m::tuple;
|
|
}
|
|
}
|
|
|
|
namespace Alepha::Hydrogen::Utility::inline exports::inline tuple_algorithms_m
|
|
{
|
|
using namespace detail::tuple_algorithms_m::exports;
|
|
}
|