From 08971abb0631b62b0fee6aabc4d2eb90a37fd1e5 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Sun, 22 Oct 2023 04:43:25 -0400 Subject: [PATCH] Add IStreamable helper. --- CMakeLists.txt | 1 + IOStreams/CMakeLists.txt | 1 + IOStreams/IStreamable.h | 60 +++++++++++++++++++++++ IOStreams/IStreamable.test/0.cc | 52 ++++++++++++++++++++ IOStreams/IStreamable.test/CMakeLists.txt | 2 + 5 files changed, 116 insertions(+) create mode 100644 IOStreams/CMakeLists.txt create mode 100644 IOStreams/IStreamable.h create mode 100644 IOStreams/IStreamable.test/0.cc create mode 100644 IOStreams/IStreamable.test/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ce0158..2ce4949 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ link_libraries( alepha ) # The subdirs to build add_subdirectory( Meta ) add_subdirectory( Proof ) +add_subdirectory( IOStreams ) add_subdirectory( Reflection ) add_subdirectory( Testing ) add_subdirectory( Utility ) diff --git a/IOStreams/CMakeLists.txt b/IOStreams/CMakeLists.txt new file mode 100644 index 0000000..f44cb48 --- /dev/null +++ b/IOStreams/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory( IStreamable.test ) diff --git a/IOStreams/IStreamable.h b/IOStreams/IStreamable.h new file mode 100644 index 0000000..54010f7 --- /dev/null +++ b/IOStreams/IStreamable.h @@ -0,0 +1,60 @@ +static_assert( __cplusplus > 2020'00 ); + +#pragma once + +#include + +#include + +#include +#include +#include +#include + +#include + +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; +} diff --git a/IOStreams/IStreamable.test/0.cc b/IOStreams/IStreamable.test/0.cc new file mode 100644 index 0000000..8b4537a --- /dev/null +++ b/IOStreams/IStreamable.test/0.cc @@ -0,0 +1,52 @@ +static_assert( __cplusplus > 2020'00 ); + +#include "../IStreamable.h" + +#include +#include + +#include + +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 } }, + }; +}; diff --git a/IOStreams/IStreamable.test/CMakeLists.txt b/IOStreams/IStreamable.test/CMakeLists.txt new file mode 100644 index 0000000..d31c4a6 --- /dev/null +++ b/IOStreams/IStreamable.test/CMakeLists.txt @@ -0,0 +1,2 @@ +link_libraries( unit-test ) +unit_test( 0 )