#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <iterator>
using namespace std;
using namespace std::placeholders;
class sequence {
vector<int> data;
public:
typedef vector<int>::const_iterator it;
// add
sequence& operator<<(int rhs) {
data.push_back(rhs);
return *this;
}
// reduce
sequence& operator<<(function<int(int,int)> binary_op) {
if (data.size() > 1) {
const int result = accumulate (data.begin()+1, data.end(), *data.begin(), binary_op);
data.clear();
data.push_back (result);
}
return *this;
}
// map
sequence& operator<<(function<int(int)> unary_op) {
transform(data.begin(), data.end(), data.begin(), unary_op);
return *this;
}
// manipulate
sequence& operator<<(function<void(vector<int>::const_iterator begin, vector<int>::const_iterator end)> manip) {
manip (data.begin(), data.end());
return *this;
}
};
// functional objects
auto sum = plus<int>();
auto prod = multiplies<int>();
// template functor
struct out {
ostream& os_;
out (ostream& os) : os_(os) {}
template <typename Iterator>
void operator ()(Iterator begin, Iterator end) {
copy (begin, end, ostream_iterator<typename Iterator::value_type>(os_," "));
os_ << endl;
}
};
auto out_cout=out(cout);
// lambda
auto change_sign = [](int x)->int { return -x; };
// function
int sqr (int x) { return x*x; }
int main() {
sequence seq;
seq << 1 << 2 << 3 << out_cout
<< sum << out_cout
<< 4 << 5 << prod << out_cout
<< 2 << sqr << out_cout
<< -42 << change_sign << out_cout;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8bnVtZXJpYz4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpdGVyYXRvcj4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdXNpbmcgbmFtZXNwYWNlIHN0ZDo6cGxhY2Vob2xkZXJzOwoKY2xhc3Mgc2VxdWVuY2UgewoKICB2ZWN0b3I8aW50PiBkYXRhOwoKICBwdWJsaWM6CiAgICB0eXBlZGVmIHZlY3RvcjxpbnQ+Ojpjb25zdF9pdGVyYXRvciBpdDsKCiAgICAvLyBhZGQKICAgIHNlcXVlbmNlJiBvcGVyYXRvcjw8KGludCByaHMpIHsgCiAgICAgIGRhdGEucHVzaF9iYWNrKHJocyk7CiAgICAgIHJldHVybiAqdGhpczsKICAgIH0KCiAgICAvLyByZWR1Y2UKICAgIHNlcXVlbmNlJiBvcGVyYXRvcjw8KGZ1bmN0aW9uPGludChpbnQsaW50KT4gYmluYXJ5X29wKSB7CiAgICAgIGlmIChkYXRhLnNpemUoKSA+IDEpIHsKICAgICAgICBjb25zdCBpbnQgcmVzdWx0ID0gYWNjdW11bGF0ZSAoZGF0YS5iZWdpbigpKzEsIGRhdGEuZW5kKCksICpkYXRhLmJlZ2luKCksIGJpbmFyeV9vcCk7CiAgICAgICAgZGF0YS5jbGVhcigpOwogICAgICAgIGRhdGEucHVzaF9iYWNrIChyZXN1bHQpOwogICAgICB9CiAgICAgIHJldHVybiAqdGhpczsKICAgIH0KCiAgICAvLyBtYXAKICAgIHNlcXVlbmNlJiBvcGVyYXRvcjw8KGZ1bmN0aW9uPGludChpbnQpPiB1bmFyeV9vcCkgewogICAgICB0cmFuc2Zvcm0oZGF0YS5iZWdpbigpLCBkYXRhLmVuZCgpLCBkYXRhLmJlZ2luKCksIHVuYXJ5X29wKTsgICAgICAKICAgICAgcmV0dXJuICp0aGlzOwogICAgfQoKICAgIC8vIG1hbmlwdWxhdGUKICAgIHNlcXVlbmNlJiBvcGVyYXRvcjw8KGZ1bmN0aW9uPHZvaWQodmVjdG9yPGludD46OmNvbnN0X2l0ZXJhdG9yIGJlZ2luLCB2ZWN0b3I8aW50Pjo6Y29uc3RfaXRlcmF0b3IgZW5kKT4gbWFuaXApIHsKICAgICAgbWFuaXAgKGRhdGEuYmVnaW4oKSwgZGF0YS5lbmQoKSk7CiAgICAgIHJldHVybiAqdGhpczsKICAgIH0KfTsKCi8vIGZ1bmN0aW9uYWwgb2JqZWN0cwphdXRvIHN1bSA9IHBsdXM8aW50PigpOwphdXRvIHByb2QgPSBtdWx0aXBsaWVzPGludD4oKTsKCi8vIHRlbXBsYXRlIGZ1bmN0b3IKc3RydWN0IG91dCB7CiAgb3N0cmVhbSYgb3NfOwogIG91dCAob3N0cmVhbSYgb3MpIDogb3NfKG9zKSB7fQoKICB0ZW1wbGF0ZSA8dHlwZW5hbWUgSXRlcmF0b3I+CiAgdm9pZCBvcGVyYXRvciAoKShJdGVyYXRvciBiZWdpbiwgSXRlcmF0b3IgZW5kKSB7CiAgICBjb3B5IChiZWdpbiwgZW5kLCBvc3RyZWFtX2l0ZXJhdG9yPHR5cGVuYW1lIEl0ZXJhdG9yOjp2YWx1ZV90eXBlPihvc18sIiAiKSk7ICAKICAgIG9zXyA8PCBlbmRsOwogIH0KfTsKCmF1dG8gb3V0X2NvdXQ9b3V0KGNvdXQpOwoKLy8gbGFtYmRhCmF1dG8gY2hhbmdlX3NpZ24gPSBbXShpbnQgeCktPmludCB7IHJldHVybiAteDsgfTsKCi8vIGZ1bmN0aW9uCmludCBzcXIgKGludCB4KSB7IHJldHVybiB4Kng7IH0KCmludCBtYWluKCkgewoJc2VxdWVuY2Ugc2VxOwogICAgc2VxIDw8IDEgPDwgMiA8PCAzIDw8IG91dF9jb3V0IAogICAgICAgIDw8IHN1bSA8PCBvdXRfY291dAogICAgICAgIDw8IDQgPDwgNSA8PCBwcm9kIDw8IG91dF9jb3V0CiAgICAgICAgPDwgMiA8PCBzcXIgPDwgb3V0X2NvdXQKICAgICAgICA8PCAtNDIgPDwgY2hhbmdlX3NpZ24gPDwgb3V0X2NvdXQ7Cn0K