#include <iostream>
#include <string>
template <class In, class Out>
struct Pipe
{
typedef In in_type ;
typedef Out out_type ;
In in_val ;
Pipe (const in_type &in_val = in_type()) : in_val (in_val)
{
}
virtual auto operator () () const -> out_type
{
return out_type () ;
}
};
template <class In, class Out, class Out2>
auto operator>> (const Pipe <In, Out> &lhs, Pipe <Out, Out2> &rhs) -> Pipe <Out, Out2>&
{
rhs = lhs () ;
return rhs ;
}
template <class In, class Out>
auto operator>> (const Pipe <In, Out> &lhs, Out &rhs) -> Out&
{
rhs = lhs () ;
return rhs ;
}
struct StringToInt : public Pipe <std::string, int>
{
StringToInt (const std::string &s = "") : Pipe <in_type, out_type> (s)
{
}
auto operator () () const -> out_type
{
return std::stoi (in_val) ;
}
};
struct IntSquare : public Pipe <int, int>
{
IntSquare (int n = 0) : Pipe <in_type, out_type> (n)
{
}
auto operator () () const -> out_type
{
return in_val * in_val ;
}
};
struct DivideBy42F : public Pipe <int, float>
{
DivideBy42F (int n = 0) : Pipe <in_type, out_type> (n)
{
}
auto operator () () const -> out_type
{
return static_cast <float> (in_val) / 42.0f ;
}
};
int main ()
{
float out = 0 ;
StringToInt ("42") >> IntSquare () >> DivideBy42F () >> out ;
std::cout << out << "\n" ;
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgoKdGVtcGxhdGUgPGNsYXNzIEluLCBjbGFzcyBPdXQ+CnN0cnVjdCBQaXBlCnsKCXR5cGVkZWYgSW4gaW5fdHlwZSA7Cgl0eXBlZGVmIE91dCBvdXRfdHlwZSA7CgoJSW4gaW5fdmFsIDsKCglQaXBlIChjb25zdCBpbl90eXBlICZpbl92YWwgPSBpbl90eXBlKCkpIDogaW5fdmFsIChpbl92YWwpCgl7Cgl9CgoJdmlydHVhbCBhdXRvIG9wZXJhdG9yICgpICgpIGNvbnN0IC0+IG91dF90eXBlCgl7CgkJcmV0dXJuIG91dF90eXBlICgpIDsKCX0KfTsKCnRlbXBsYXRlIDxjbGFzcyBJbiwgY2xhc3MgT3V0LCBjbGFzcyBPdXQyPgphdXRvIG9wZXJhdG9yPj4gKGNvbnN0IFBpcGUgPEluLCBPdXQ+ICZsaHMsIFBpcGUgPE91dCwgT3V0Mj4gJnJocykgLT4gUGlwZSA8T3V0LCBPdXQyPiYKewoJcmhzID0gbGhzICgpIDsKCXJldHVybiByaHMgOwp9Cgp0ZW1wbGF0ZSA8Y2xhc3MgSW4sIGNsYXNzIE91dD4KYXV0byBvcGVyYXRvcj4+IChjb25zdCBQaXBlIDxJbiwgT3V0PiAmbGhzLCBPdXQgJnJocykgLT4gT3V0Jgp7CglyaHMgPSBsaHMgKCkgOwoJcmV0dXJuIHJocyA7Cn0KCnN0cnVjdCBTdHJpbmdUb0ludCA6IHB1YmxpYyBQaXBlIDxzdGQ6OnN0cmluZywgaW50Pgp7CglTdHJpbmdUb0ludCAoY29uc3Qgc3RkOjpzdHJpbmcgJnMgPSAiIikgOiBQaXBlIDxpbl90eXBlLCBvdXRfdHlwZT4gKHMpCgl7Cgl9CgoJYXV0byBvcGVyYXRvciAoKSAoKSBjb25zdCAtPiBvdXRfdHlwZQoJewoJCXJldHVybiBzdGQ6OnN0b2kgKGluX3ZhbCkgOwoJfQp9OwoKc3RydWN0IEludFNxdWFyZSA6IHB1YmxpYyBQaXBlIDxpbnQsIGludD4KewoJSW50U3F1YXJlIChpbnQgbiA9IDApIDogUGlwZSA8aW5fdHlwZSwgb3V0X3R5cGU+IChuKQoJewoJfQoKCWF1dG8gb3BlcmF0b3IgKCkgKCkgY29uc3QgLT4gb3V0X3R5cGUKCXsKCQlyZXR1cm4gaW5fdmFsICogaW5fdmFsIDsKCX0KfTsKCnN0cnVjdCBEaXZpZGVCeTQyRiA6IHB1YmxpYyBQaXBlIDxpbnQsIGZsb2F0Pgp7CglEaXZpZGVCeTQyRiAoaW50IG4gPSAwKSA6IFBpcGUgPGluX3R5cGUsIG91dF90eXBlPiAobikKCXsKCX0KCglhdXRvIG9wZXJhdG9yICgpICgpIGNvbnN0IC0+IG91dF90eXBlCgl7CgkJcmV0dXJuIHN0YXRpY19jYXN0IDxmbG9hdD4gKGluX3ZhbCkgLyA0Mi4wZiA7Cgl9Cn07CgppbnQgbWFpbiAoKQp7CglmbG9hdCBvdXQgPSAwIDsKCVN0cmluZ1RvSW50ICgiNDIiKSA+PiBJbnRTcXVhcmUgKCkgPj4gRGl2aWRlQnk0MkYgKCkgPj4gb3V0IDsKCXN0ZDo6Y291dCA8PCBvdXQgPDwgIlxuIiA7CgoJcmV0dXJuIDAgOwp9Cg==
prog.cpp: In function ‘int main()’:
prog.cpp:75:21: error: no match for ‘operator>>’ (operand types are ‘StringToInt’ and ‘IntSquare’)
StringToInt ("42") >> IntSquare () >> DivideBy42F () >> out ;
^
prog.cpp:75:21: note: candidates are:
prog.cpp:23:6: note: Pipe<Out, Out2>& operator>>(const Pipe<In, Out>&, Pipe<Out, Out2>&) [with In = std::basic_string<char>; Out = int; Out2 = int]
auto operator>> (const Pipe <In, Out> &lhs, Pipe <Out, Out2> &rhs) -> Pipe <Out, Out2>&
^
prog.cpp:23:6: note: no known conversion for argument 2 from ‘IntSquare’ to ‘Pipe<int, int>&’
prog.cpp:30:6: note: template<class In, class Out> Out& operator>>(const Pipe<In, Out>&, Out&)
auto operator>> (const Pipe <In, Out> &lhs, Out &rhs) -> Out&
^
prog.cpp:30:6: note: template argument deduction/substitution failed:
prog.cpp:75:35: note: deduced conflicting types for parameter ‘Out’ (‘int’ and ‘IntSquare’)
StringToInt ("42") >> IntSquare () >> DivideBy42F () >> out ;
^