Connecting Tech Pros Worldwide Forums | Help | Site Map

Piping between Functions

christopher diggins
Guest
 
Posts: n/a
#1: Jul 23 '05
I just wanted to share this technique for piping the cout from one function
to the cin of another, using the pipe operator:

#include <iostream>
#include <sstream>

using namespace std;

typedef void(*procedure)();

class filter {
public:
filter(procedure x) : proc(x) { }
void operator()(istream& in, ostream& out) {
streambuf* inbuf = cin.rdbuf();
streambuf* outbuf = cout.rdbuf();
cin.rdbuf(in.rdbuf());
cout.rdbuf(out.rdbuf());
proc();
cin.rdbuf(inbuf);
cout.rdbuf(outbuf);
}
private:
procedure proc;
};

void operator|(filter f1, filter f2) {
stringstream s;
f1(cin, s);
s.seekg(0);
f2(s, cout);
}

void HelloWorld() {
cout << "hello world" << endl;
}

void CountChars() {
string s;
s = cin.getline();
cout << static_cast<int>(s.size()) << endl;
}

int main() {
filter(HelloWorld) | filter(CountChars);
return 0;
}

Any comments or suggestions?

I am working on a version which allows passing of arguments to functions,
and which allows arbitrary chaining.

--
Christopher Diggins
http://www.cdiggins.com
http://www.heron-language.com



Alex Vinokur
Guest
 
Posts: n/a
#2: Jul 23 '05

re: Piping between Functions



"christopher diggins" <cdiggins@videotron.ca> wrote in message news:sAYDd.32984$Y61.1203911@wagner.videotron.net. ..[color=blue]
> I just wanted to share this technique for piping the cout from one function
> to the cin of another, using the pipe operator:
>
> #include <iostream>
> #include <sstream>
>
> using namespace std;
>
> typedef void(*procedure)();
>
> class filter {
> public:
> filter(procedure x) : proc(x) { }
> void operator()(istream& in, ostream& out) {
> streambuf* inbuf = cin.rdbuf();
> streambuf* outbuf = cout.rdbuf();
> cin.rdbuf(in.rdbuf());
> cout.rdbuf(out.rdbuf());
> proc();
> cin.rdbuf(inbuf);
> cout.rdbuf(outbuf);
> }
> private:
> procedure proc;
> };
>
> void operator|(filter f1, filter f2) {
> stringstream s;
> f1(cin, s);
> s.seekg(0);
> f2(s, cout);
> }
>
> void HelloWorld() {
> cout << "hello world" << endl;
> }
>
> void CountChars() {
> string s;[/color]
--------------------------------[color=blue]
> s = cin.getline();[/color]
// Compiler g++ 3.3.3
In function `void CountChars()':
error: no matching function for call to `std::basic_istream<char,
std::char_traits<char> >::getline()'
/usr/include/c++/3.3.3/bits/istream.tcc:594: error: candidates are:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::getline(_CharT*, int, _CharT) [with _CharT = char, _Traits =
std::char_traits<char>]
/usr/include/c++/3.3.3/istream:401: error:
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::getline(_CharT*, int) [with _CharT = char, _Traits =
std::char_traits<char>]
--------------------------------[color=blue]
> cout << static_cast<int>(s.size()) << endl;
> }
>
> int main() {
> filter(HelloWorld) | filter(CountChars);
> return 0;
> }
>
> Any comments or suggestions?
>
> I am working on a version which allows passing of arguments to functions,
> and which allows arbitrary chaining.
>[/color]
[snip]

--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn



christopher diggins
Guest
 
Posts: n/a
#3: Jul 23 '05

re: Piping between Functions


Thanks for pointing that out Alex. My apologies for the error. Please
update:

void CountChars() {
string s;
s = cin.getline();
cout << static_cast<int>(s.size()) << endl;
}

to

void CountChars() {
string s;
getline(cin, s);
cout << static_cast<int>(s.size()) << endl;
}

--
Christopher Diggins
http://www.cdiggins.com
http://www.heron-language.com


Alex Vinokur
Guest
 
Posts: n/a
#4: Jul 23 '05

re: Piping between Functions



"christopher diggins" <cdiggins@videotron.ca> wrote in message news:LNdEd.18441$SB6.191659@wagner.videotron.net.. .[color=blue]
> Thanks for pointing that out Alex. My apologies for the error. Please
> update:
>
> void CountChars() {
> string s;
> s = cin.getline();
> cout << static_cast<int>(s.size()) << endl;
> }
>
> to
>
> void CountChars() {
> string s;
> getline(cin, s);
> cout << static_cast<int>(s.size()) << endl;
> }
>[/color]
[snip]

Piping between functions looks very nice.

How do you mean to use that?

Are there any list of samples/applications?


--
Alex Vinokur
email: alex DOT vinokur AT gmail DOT com
http://mathforum.org/library/view/10978.html
http://sourceforge.net/users/alexvn







christopher diggins
Guest
 
Posts: n/a
#5: Jul 23 '05

re: Piping between Functions


"Alex Vinokur" <alexvn@big-foot.com> wrote in message
news:34fkpkF4bad5sU1@individual.net...[color=blue]
>
> "christopher diggins" <cdiggins@videotron.ca> wrote in message
> news:LNdEd.18441$SB6.191659@wagner.videotron.net.. .[color=green]
>> Thanks for pointing that out Alex. My apologies for the error. Please
>> update:
>>
>> void CountChars() {
>> string s;
>> s = cin.getline();
>> cout << static_cast<int>(s.size()) << endl;
>> }
>>
>> to
>>
>> void CountChars() {
>> string s;
>> getline(cin, s);
>> cout << static_cast<int>(s.size()) << endl;
>> }
>>[/color]
> [snip]
>
> Piping between functions looks very nice.
>
> How do you mean to use that?
>
> Are there any list of samples/applications?[/color]

I am using the techniuq to develop my applications in a more reusable
manner. For instance I can write many of my applications (currently
primarily text parsing tools) as filters. I can then string them together to
create new functions/applications. My plan is to code C++ as if I was
writing unix shell scripts. It basically reduces the amount of code I need
for my applications, which I always like.

--
Christopher Diggins
Object Oriented Template Library (OOTL)
http://www.ootl.org


Closed Thread


Similar C / C++ bytes