1
0
forked from Alepha/Alepha

A few more meta programming bits.

This commit is contained in:
2021-07-03 01:21:48 -04:00
parent 741c0dcdcf
commit 2bbb612df1
5 changed files with 180 additions and 0 deletions

58
Meta/is_streamable.h Normal file
View File

@ -0,0 +1,58 @@
static_assert( __cplusplus > 201700, "C++17 Required" );
#pragma once
#include <Alepha/Alepha.h>
#include <iosfwd>
namespace Alepha::Hydrogen::Meta
{
inline namespace exports { inline namespace type_traits {} }
namespace detail::type_traits::is_streamable
{
inline namespace exports {}
namespace impl
{
template< typename T, typename= void >
struct is_istreamable : std::false_type {};
template< typename T >
struct is_istreamable< T, std::void_t< decltype( std::declval< std::istream & >() >> std::declval< T & >() ) > > : std::true_type {};
template< typename T, typename= void >
struct is_ostreamable : std::false_type {};
template< typename T >
struct is_ostreamable< T, std::void_t< decltype( std::declval< std::ostream & >() << std::declval< T & >() ) > > : std::true_type {};
}
namespace exports
{
template< typename T >
constexpr bool is_istreamable_v= impl::is_istreamable< T >::value;
template< typename T >
constexpr bool is_ostreamable_v= impl::is_ostreamable< T >::value;
template< typename T >
constexpr bool is_streamable_v= is_istreamable_v< T > and is_ostreamable_v< T >;
template< typename T >
struct is_istreamable : std::bool_constant< is_istreamable_v< T > > {};
template< typename T >
struct is_ostreamable : std::bool_constant< is_ostreamable_v< T > > {};
template< typename T >
struct is_streamable : std::bool_constant< is_streamable_v< T > > {};
}
}
namespace exports::type_traits
{
using namespace detail::type_traits::is_streamable::exports;
}
}

33
Meta/is_tuple.h Normal file
View File

@ -0,0 +1,33 @@
static_assert( __cplusplus > 201700, "C++17 Required" );
#pragma once
#include <Alepha/Alepha.h>
#include <type_traits>
#include <tuple>
namespace Alepha::Hydrogen::Meta
{
inline namespace exports { inline namespace type_traits {} }
namespace detail::type_traits::is_tuple
{
inline namespace exports
{
template< typename T >
struct is_tuple : std::false_type {};
template< typename ... Args >
struct is_tuple< std::tuple< Args... > > : std::true_type {};
template< typename T >
constexpr bool is_tuple_v= is_tuple< T >::value;
}
}
namespace exports::type_traits
{
using namespace detail::type_traits::is_tuple::exports;
}
}

View File

@ -2,6 +2,8 @@ static_assert( __cplusplus > 201700, "C++17 Required" );
#include <Alepha/Meta/is_sequence.h>
#include <Alepha/Meta/is_streamable.h>
#include <Alepha/Testing/test.h>
#include <Alepha/Utility/evaluation.h>
@ -106,6 +108,12 @@ namespace
static_assert( not Alepha::Meta::is_string_v< std::forward_list< std::string > > );
static_assert( not Alepha::Meta::is_string_v< std::deque< std::string > > );
};
"meta.streams"_test <=[]
{
static_assert( Alepha::Meta::is_streamable_v< int > );
static_assert( not Alepha::Meta::is_streamable_v< void > );
};
};
}

36
Meta/tuple_decay.h Normal file
View File

@ -0,0 +1,36 @@
static_assert( __cplusplus > 201700, "C++17 Required" );
#pragma once
#include <Alepha/Alepha.h>
#include <type_traits>
#include <Alepha/Stud/type_traits.h>
namespace Alepha::Hydrogen::Meta
{
inline namespace exports { inline namespace type_traits {} }
namespace detail::type_traits::tuple_decay
{
inline namespace exports
{
template< typename T > struct tuple_decay;
template< typename ... Args >
struct tuple_decay< std::tuple< T, Args... > >
{
using type= std::tuple< Stud::decay_t< Args >... >;
};
template< typename T >
using tuple_decay_t= typename tuple_decay< T >::type;
}
}
namespace exports::type_traits
{
using namespace detail::type_traits::tuple_decay;
}
}