forked from Alepha/Alepha
Add IStreamable helper.
This commit is contained in:
@ -19,6 +19,7 @@ link_libraries( alepha )
|
|||||||
# The subdirs to build
|
# The subdirs to build
|
||||||
add_subdirectory( Meta )
|
add_subdirectory( Meta )
|
||||||
add_subdirectory( Proof )
|
add_subdirectory( Proof )
|
||||||
|
add_subdirectory( IOStreams )
|
||||||
add_subdirectory( Reflection )
|
add_subdirectory( Reflection )
|
||||||
add_subdirectory( Testing )
|
add_subdirectory( Testing )
|
||||||
add_subdirectory( Utility )
|
add_subdirectory( Utility )
|
||||||
|
|||||||
1
IOStreams/CMakeLists.txt
Normal file
1
IOStreams/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
add_subdirectory( IStreamable.test )
|
||||||
60
IOStreams/IStreamable.h
Normal file
60
IOStreams/IStreamable.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
static_assert( __cplusplus > 2020'00 );
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Alepha/Alepha.h>
|
||||||
|
|
||||||
|
#include <istream>
|
||||||
|
|
||||||
|
#include <Alepha/Capabilities.h>
|
||||||
|
#include <Alepha/template_for_each.h>
|
||||||
|
#include <Alepha/string_algorithms.h>
|
||||||
|
#include <Alepha/Concepts.h>
|
||||||
|
|
||||||
|
#include <Alepha/Reflection/tuplizeAggregate.h>
|
||||||
|
|
||||||
|
namespace Alepha::Hydrogen::IOStreams ::detail:: istreamable_module
|
||||||
|
{
|
||||||
|
inline namespace exports
|
||||||
|
{
|
||||||
|
struct IStreamable {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
concept IStreamableAggregate= Aggregate< T > and Capability< T, IStreamable >;
|
||||||
|
|
||||||
|
|
||||||
|
std::istream &
|
||||||
|
operator >> ( std::istream &is, IStreamableAggregate auto &istreamable )
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::getline( is, line );
|
||||||
|
const auto commentChar= line.find( "#" );
|
||||||
|
if( commentChar != std::string::npos ) line= line.substr( line.find( "#" ) );
|
||||||
|
|
||||||
|
const auto tokens= split( line, '\t' );
|
||||||
|
|
||||||
|
auto decomposed= Alepha::Reflection::tuplizeAggregate( istreamable );
|
||||||
|
|
||||||
|
if( tokens.size() != std::tuple_size_v< std::decay_t< decltype( decomposed ) > > )
|
||||||
|
{
|
||||||
|
throw 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index= 0;
|
||||||
|
// TODO: Consider the lens system here... but the basic use case seems to be for
|
||||||
|
// aggregates, so we'll go with this simple case for now...
|
||||||
|
tuple_for_each( decomposed ) <=[&]( auto &element )
|
||||||
|
{
|
||||||
|
std::istringstream iss{ tokens.at( index++ ) };
|
||||||
|
iss >> element;
|
||||||
|
};
|
||||||
|
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Alepha::Hydrogen::IOStreams::inline exports::inline istreamable_module
|
||||||
|
{
|
||||||
|
using namespace detail::istreamable_module::exports;
|
||||||
|
}
|
||||||
52
IOStreams/IStreamable.test/0.cc
Normal file
52
IOStreams/IStreamable.test/0.cc
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
static_assert( __cplusplus > 2020'00 );
|
||||||
|
|
||||||
|
#include "../IStreamable.h"
|
||||||
|
|
||||||
|
#include <Alepha/Testing/TableTest.h>
|
||||||
|
#include <Alepha/Testing/test.h>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template< typename= Alepha::Capabilities< Alepha::IOStreams::IStreamable > >
|
||||||
|
struct Agg_core
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
|
||||||
|
friend bool operator == ( const Agg_core &lhs, const Agg_core &rhs )= default;
|
||||||
|
friend std::ostream &
|
||||||
|
operator << ( std::ostream &os, const Agg_core &agg )
|
||||||
|
{
|
||||||
|
return os << "{ " << agg.x << ", " << agg.y << ", " << agg.z << " }";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using Agg= Agg_core<>;
|
||||||
|
static_assert( Alepha::Aggregate< Agg > );
|
||||||
|
static_assert( Alepha::Capability< Agg, Alepha::IOStreams::IStreamable > );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto
|
||||||
|
buildFromString( const std::string text )
|
||||||
|
{
|
||||||
|
Agg rv;
|
||||||
|
std::istringstream iss{ text };
|
||||||
|
iss >> rv;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto init= Alepha::Utility::enroll <=[]
|
||||||
|
{
|
||||||
|
using namespace Alepha::Testing::exports;
|
||||||
|
using namespace Alepha::Testing::literals::test_literals;
|
||||||
|
|
||||||
|
"Simple IStream"_test <=TableTest< buildFromString >
|
||||||
|
::Cases
|
||||||
|
{
|
||||||
|
{ "smoke test", { "1\t2\t3" }, { 1, 2, 3 } },
|
||||||
|
};
|
||||||
|
};
|
||||||
2
IOStreams/IStreamable.test/CMakeLists.txt
Normal file
2
IOStreams/IStreamable.test/CMakeLists.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
link_libraries( unit-test )
|
||||||
|
unit_test( 0 )
|
||||||
Reference in New Issue
Block a user