#include <algorithm>
#include <functional>
#include <iterator>
#include <utility>
#include <vector>
template <typename Container, typename F>
Container Map( const F& f, const Container& xs )
{
Container ys;
// For performance reasons one would use
// ys.reserve( xs.size() )
// and std::back_inserter instead of std::inserter
// if ys is a std::vector.
auto it = std::inserter( ys, end( ys ) );
std::transform( begin( xs ), end( xs ), it, f );
return ys;
}
template <typename F, typename T>
auto Curry(F&& f, T&& t)
{
return [f = std::forward<F>(f), t = std::forward<T>(t)]
(auto&&... args)
{ return f(t, std::forward<decltype(args)>(args)...); };
}
int main()
{
auto square = [](int x){ return x*x; };
typedef std::vector<int> Row;
Row row;
Row squaredRow = Map(square, row);
typedef std::vector<Row> Mat;
Mat mat;
auto squareRow = Map<Row, decltype(square)>;
auto squareRowElems = Curry((Map<Row, decltype(square)>), square);
Mat squaredMat = Map(squareRowElems, mat);
}
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxpdGVyYXRvcj4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDx2ZWN0b3I+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgQ29udGFpbmVyLCB0eXBlbmFtZSBGPgpDb250YWluZXIgTWFwKCBjb25zdCBGJiBmLCBjb25zdCBDb250YWluZXImIHhzICkKewogICAgQ29udGFpbmVyIHlzOwogICAgLy8gRm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgb25lIHdvdWxkIHVzZQogICAgLy8geXMucmVzZXJ2ZSggeHMuc2l6ZSgpICkKICAgIC8vIGFuZCBzdGQ6OmJhY2tfaW5zZXJ0ZXIgaW5zdGVhZCBvZiBzdGQ6Omluc2VydGVyCiAgICAvLyBpZiB5cyBpcyBhIHN0ZDo6dmVjdG9yLgogICAgYXV0byBpdCA9IHN0ZDo6aW5zZXJ0ZXIoIHlzLCBlbmQoIHlzICkgKTsKICAgIHN0ZDo6dHJhbnNmb3JtKCBiZWdpbiggeHMgKSwgZW5kKCB4cyApLCBpdCwgZiApOwogICAgcmV0dXJuIHlzOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRiwgdHlwZW5hbWUgVD4KYXV0byBDdXJyeShGJiYgZiwgVCYmIHQpCnsKICAgIHJldHVybiBbZiA9IHN0ZDo6Zm9yd2FyZDxGPihmKSwgdCA9IHN0ZDo6Zm9yd2FyZDxUPih0KV0KICAgICAgICAgICAoYXV0byYmLi4uIGFyZ3MpCiAgICAgICAgICAgeyByZXR1cm4gZih0LCBzdGQ6OmZvcndhcmQ8ZGVjbHR5cGUoYXJncyk+KGFyZ3MpLi4uKTsgfTsKfQoKaW50IG1haW4oKQp7CiAgICBhdXRvIHNxdWFyZSA9IFtdKGludCB4KXsgcmV0dXJuIHgqeDsgfTsKCiAgICB0eXBlZGVmIHN0ZDo6dmVjdG9yPGludD4gUm93OwogICAgUm93IHJvdzsKICAgIFJvdyBzcXVhcmVkUm93ID0gTWFwKHNxdWFyZSwgcm93KTsKCiAgICB0eXBlZGVmIHN0ZDo6dmVjdG9yPFJvdz4gTWF0OwogICAgTWF0IG1hdDsKICAgIGF1dG8gc3F1YXJlUm93ID0gTWFwPFJvdywgZGVjbHR5cGUoc3F1YXJlKT47CiAgICBhdXRvIHNxdWFyZVJvd0VsZW1zID0gQ3VycnkoKE1hcDxSb3csIGRlY2x0eXBlKHNxdWFyZSk+KSwgc3F1YXJlKTsKICAgIE1hdCBzcXVhcmVkTWF0ID0gTWFwKHNxdWFyZVJvd0VsZW1zLCBtYXQpOwp9