Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

structure clash - output driven solution

31 views
Skip to first unread message

Alf P. Steinbach

unread,
Nov 9, 2015, 9:59:06 AM11/9/15
to
#include "cppx.hpp"
//using std::move;
using std::wcin;
using std::wcout;
using cppx::Boxed;
using cppx::hopefully;
using cppx::fail;
using cppx::n_items;
using cppx::String;

#include <functional>
using std::function;

#include <sstream>
using std::wistringstream;

#include <string>
using std::stoi;
using std::getline;

auto std_line_input()
-> Boxed<String>
{ return cppx::input_line(); }

class Word_reader
{
private:
function< Boxed<String>() > input_;
wistringstream line_stream_;

public:
auto next_word()
-> Boxed<String>
{
String word;
if( line_stream_ >> word )
{
return Boxed<String>( move( word ) );
}

Boxed<String> new_line;
do
{
new_line = input_();
} while( (not new_line.is_empty()) and n_items( new_line.item()
) == 0 );

if( not new_line.is_empty() )
{
line_stream_.clear();
line_stream_.str( new_line.item() );
if( line_stream_ >> word )
{
return Boxed<String>( move( word ) );
}
}

return Boxed<String>::empty();
}

Word_reader( function< Boxed<String>() > line_input )
: input_( line_input )
{}
};

class Controllable_word_reader
{
private:
Word_reader reader_;
String inserted_word_;
bool use_inserted_word_;

public:
auto next_word()
-> Boxed<String>
{
if( use_inserted_word_ )
{
use_inserted_word_ = false;
return Boxed<String>( move( inserted_word_ ) );
}
return reader_.next_word();
}

void insert( String word )
{
hopefully( not use_inserted_word_ )
|| fail( "Controllable_word_reader::insert" );
inserted_word_ = move( word );
use_inserted_word_ = true;
}

Controllable_word_reader( function< Boxed<String>() > line_input )
: reader_( line_input )
, use_inserted_word_( false )
{}
};

enum class Status
{
all_finished, more_lines_to_do
};

auto output_one_line(
int const max_line_length,
Controllable_word_reader& reader
)
-> Status
{
auto result = Status::more_lines_to_do;
String line;
for( ;; )
{
Boxed<String> word = reader.next_word();
if( word.is_empty() )
{
result = Status::all_finished;
break;
}

int const previous_length = n_items( line );
if( previous_length == 0 )
{
line = word.item();
}
else if( previous_length + 1 + n_items( word.item() ) >
max_line_length )
{
reader.insert( move( word.item() ) );
break;
}
else
{
line += L' ';
line += word.item();
}
}
if( n_items( line ) > 0 ) { wcout << line << "\n"; }
return result;
}

auto main( int, char** args )
-> int
{
int const w = stoi( args[1] );
Controllable_word_reader reader{ std_line_input };
for( auto status = Status::more_lines_to_do; status !=
Status::all_finished; )
{
status = output_one_line( w, reader );
}
}

Alf P. Steinbach

unread,
Nov 9, 2015, 10:15:07 AM11/9/15
to
On 11/9/2015 3:58 PM, Alf P. Steinbach wrote:
> [snip code]

Well just by posting that code I saw that it erroneously will treat a
non-empty line of whitespace as end-of-file. But that's easy to fix.

Cheers,

- Alf

Christian Gollwitzer

unread,
Nov 17, 2015, 2:05:34 AM11/17/15
to
Am 09.11.15 um 15:58 schrieb Alf P. Steinbach:
> [some code to implement pipelines]

Alf you may be interested in Fiberize:

https://github.com/fiberize/fiberize

a C++ framework for cooperative multitasking.

Christian

Alf P. Steinbach

unread,
Nov 17, 2015, 5:06:44 AM11/17/15
to
Interesting. Apparently this uses the Windows terminology "fiber" =
coroutine. But there's also threading, and it's unclear what
relationship the library establishes between threads and coroutines?

I would guess the dependency on Boost is for the fiber execution state.

Cheers, & thanks,

- Alf

PS. Oh, by the way, the output driven solution (the thread you replied
in here) is not a multitasking solution. It's just an unnatural solution
based on choosing an impractical top level goal for a procedural
stepwise refinement. But interesting as such, keeping in mind Betrand
Meyer's "real systems have no top".

0 new messages