static_assert( __cplusplus > 2020'99 ); #pragma once #include #include #include namespace Alepha::Hydrogen::IOStreams ::detail:: String_m { inline namespace exports { class String; enum { Str }; enum { FinishString }; std::string stringify( const Alepha::OStreamable auto &item, Alepha::OStreamable auto && ... params ); } class exports::String { private: // TODO: We need the exception throwing capabilities of the // `boost::lexical_cast` operation. But this stream technique // lets us build strings using stream modifiers and manipulators, // which `boost::lexical_cast` doesn't support. std::ostringstream oss; public: String && operator << ( const Alepha::OStreamable auto &t ) && { oss << t; return std::move( *this ); } std::string operator << ( decltype( FinishString ) ) && { return std::move( oss ).str(); } operator std::string () && { return std::move( *this ) << FinishString; } }; inline String operator << ( decltype( Str ), const Alepha::OStreamable auto &t ) { return String{} << t; } inline std::string exports::stringify( const Alepha::OStreamable auto &item, Alepha::OStreamable auto && ... params ) { return ( String{} << ... << params ) << item << FinishString; } } namespace Alepha::Hydrogen::IOStreams::inline exports::inline String_m { using namespace detail::String_m::exports; }