#include <iostream>
#include <iomanip>
#include <memory>
using namespace std;
template<typename FROM, typename TO>
class Adapter
{
public:
/**
* Adapts something from one type to a type.
* @param f
* @return
*/
virtual TO adapt(FROM f) = 0;
/**
* Chains adapters.
*
* @param <NEXT>
* @param next
* @return a new adapter that takes the output of this adapter and
* adapts to something of type NEXT.
*/
template<typename NEXT>
std::unique_ptr<Adapter<FROM, NEXT>> chain(Adapter<TO, NEXT> *next)
{
class ChainedAdapter : public Adapter<FROM, NEXT>
{
private:
Adapter<FROM, TO> *x;
Adapter<TO, NEXT> *next;
public:
ChainedAdapter(Adapter<FROM, TO> *x, Adapter<TO, NEXT> *next)
: x(x), next(next) {}
NEXT adapt(FROM f) override {
return next->adapt(x->adapt(f));
}
};
//return std::make_unique<ChainedAdapter>(this, next);
return std::unique_ptr<ChainedAdapter>(new ChainedAdapter(this, next));
}
};
class CharIntAdapter : public Adapter<char, int>
{
public:
int adapt(char f) override {
int ret = static_cast<int>(f);
cout << "char('" << f << "') -> int(" << ret << ")" << endl;
return ret;
}
};
class IntBoolAdapter : public Adapter<int, bool>
{
public:
bool adapt(int f) override {
bool ret = f != 0;
cout << "int(" << f << ") -> bool(" << boolalpha << ret << ")" << endl;
return ret;
}
};
int main() {
CharIntAdapter cia;
cout << cia.adapt('a') << endl;
cout << endl;
IntBoolAdapter iba;
cout << boolalpha << cia.chain(&iba)->adapt('a') << endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPG1lbW9yeT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPHR5cGVuYW1lIEZST00sIHR5cGVuYW1lIFRPPgpjbGFzcyBBZGFwdGVyCnsKcHVibGljOgogICAgLyoqCiAgICAgKiBBZGFwdHMgc29tZXRoaW5nIGZyb20gb25lIHR5cGUgdG8gYSB0eXBlLiAKICAgICAqIEBwYXJhbSBmCiAgICAgKiBAcmV0dXJuCiAgICAgKi8KICAgIHZpcnR1YWwgVE8gYWRhcHQoRlJPTSBmKSA9IDA7CiAgICAKICAgIC8qKgogICAgICogQ2hhaW5zIGFkYXB0ZXJzLiAKICAgICAqIAogICAgICogQHBhcmFtIDxORVhUPgogICAgICogQHBhcmFtIG5leHQgCiAgICAgKiBAcmV0dXJuIGEgbmV3IGFkYXB0ZXIgdGhhdCB0YWtlcyB0aGUgb3V0cHV0IG9mIHRoaXMgYWRhcHRlciBhbmQgCiAgICAgKiBhZGFwdHMgdG8gc29tZXRoaW5nIG9mIHR5cGUgTkVYVC4KICAgICAqLwogICAgdGVtcGxhdGU8dHlwZW5hbWUgTkVYVD4KICAgIHN0ZDo6dW5pcXVlX3B0cjxBZGFwdGVyPEZST00sIE5FWFQ+PiBjaGFpbihBZGFwdGVyPFRPLCBORVhUPiAqbmV4dCkKICAgIHsKICAgIAljbGFzcyBDaGFpbmVkQWRhcHRlciA6IHB1YmxpYyBBZGFwdGVyPEZST00sIE5FWFQ+CiAgICAJewogICAgCXByaXZhdGU6CgkgICAgICAgIEFkYXB0ZXI8RlJPTSwgVE8+ICp4OyAKICAgIAkgICAgQWRhcHRlcjxUTywgTkVYVD4gKm5leHQ7CiAgICAJcHVibGljOgogICAgICAgIAlDaGFpbmVkQWRhcHRlcihBZGFwdGVyPEZST00sIFRPPiAqeCwgQWRhcHRlcjxUTywgTkVYVD4gKm5leHQpCiAgICAgICAgICAgIAk6IHgoeCksIG5leHQobmV4dCkge30KCgkgICAgICAgIE5FWFQgYWRhcHQoRlJPTSBmKSBvdmVycmlkZSB7CiAgICAJICAgICAgICByZXR1cm4gbmV4dC0+YWRhcHQoeC0+YWRhcHQoZikpOwogICAgICAgIAl9CgkgICAgfTsKCgkJLy9yZXR1cm4gc3RkOjptYWtlX3VuaXF1ZTxDaGFpbmVkQWRhcHRlcj4odGhpcywgbmV4dCk7CgkJcmV0dXJuIHN0ZDo6dW5pcXVlX3B0cjxDaGFpbmVkQWRhcHRlcj4obmV3IENoYWluZWRBZGFwdGVyKHRoaXMsIG5leHQpKTsKICAgIH0KfTsKCmNsYXNzIENoYXJJbnRBZGFwdGVyIDogcHVibGljIEFkYXB0ZXI8Y2hhciwgaW50Pgp7CnB1YmxpYzoKCWludCBhZGFwdChjaGFyIGYpIG92ZXJyaWRlIHsKCQlpbnQgcmV0ID0gc3RhdGljX2Nhc3Q8aW50PihmKTsKCQljb3V0IDw8ICJjaGFyKCciIDw8IGYgPDwgIicpIC0+IGludCgiIDw8IHJldCA8PCAiKSIgPDwgZW5kbDsKCQlyZXR1cm4gcmV0OwoJfQp9OwoKY2xhc3MgSW50Qm9vbEFkYXB0ZXIgOiBwdWJsaWMgQWRhcHRlcjxpbnQsIGJvb2w+CnsKcHVibGljOgoJYm9vbCBhZGFwdChpbnQgZikgb3ZlcnJpZGUgewoJCWJvb2wgcmV0ID0gZiAhPSAwOwoJCWNvdXQgPDwgImludCgiIDw8IGYgPDwgIikgLT4gYm9vbCgiIDw8IGJvb2xhbHBoYSA8PCByZXQgPDwgIikiIDw8IGVuZGw7CgkJcmV0dXJuIHJldDsKCX0KfTsKCmludCBtYWluKCkgewoJQ2hhckludEFkYXB0ZXIgY2lhOwoJY291dCA8PCBjaWEuYWRhcHQoJ2EnKSA8PCBlbmRsOwoJCgljb3V0IDw8IGVuZGw7CgkKICAgIEludEJvb2xBZGFwdGVyIGliYTsKCWNvdXQgPDwgYm9vbGFscGhhIDw8IGNpYS5jaGFpbigmaWJhKS0+YWRhcHQoJ2EnKSA8PCBlbmRsOwoKCXJldHVybiAwOwp9