#include <iostream>
using namespace std;
class RigidBody{
float position=1;
public: float getPosition()const{ return position;}
public: void setPosition(float ppos){ position=ppos;}
};
class Adaptor{
RigidBody const& body;
int offset;
Adaptor(RigidBody body, int offset=2)
: body(body),
offset(offset)
{}
protected:
RigidBody& get_body() { return const_cast<RigidBody&>(body); }
RigidBody const& get_body() const { return body; }
public:
static Adaptor *adapt(RigidBody& body, int offset = 2) { return new Adaptor{ body, offset }; }
static Adaptor const *adapt(RigidBody const& body, int offset = 2) { return new Adaptor{ body, offset }; }
float getPosition() const
{
// this uses the const get_body()
return get_body().getPosition() + offset;
}
void setPosition(float ppos)
{
// this uses the mutable get_body()
get_body().setPosition(ppos-offset);
}
};
int main()
{
{
RigidBody b;
auto *a = Adaptor::adapt(b);
a->setPosition(15.);
a->getPosition();
}
/*{
RigidBody const b;
auto *a = Adaptor::adapt(b);
a->setPosition(15.); // error: passing ‘const Adaptor’ as ‘this’ argument discards qualifiers
a->getPosition();
}*/
}
I2luY2x1ZGUgPGlvc3RyZWFtPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwpjbGFzcyBSaWdpZEJvZHl7CiAgICBmbG9hdCBwb3NpdGlvbj0xOwogICAgcHVibGljOiBmbG9hdCBnZXRQb3NpdGlvbigpY29uc3R7IHJldHVybiBwb3NpdGlvbjt9CiAgICBwdWJsaWM6IHZvaWQgc2V0UG9zaXRpb24oZmxvYXQgcHBvcyl7IHBvc2l0aW9uPXBwb3M7fQp9OwpjbGFzcyBBZGFwdG9yewogICAgUmlnaWRCb2R5IGNvbnN0JiBib2R5OwogICAgaW50IG9mZnNldDsKCiAgICBBZGFwdG9yKFJpZ2lkQm9keSBib2R5LCBpbnQgb2Zmc2V0PTIpCiAgICAgICAgOiBib2R5KGJvZHkpLAogICAgICAgICAgb2Zmc2V0KG9mZnNldCkKICAgIHt9CiAgICBwcm90ZWN0ZWQ6CiAgICBSaWdpZEJvZHkmIGdldF9ib2R5KCkgeyByZXR1cm4gY29uc3RfY2FzdDxSaWdpZEJvZHkmPihib2R5KTsgfQogICAgUmlnaWRCb2R5IGNvbnN0JiBnZXRfYm9keSgpIGNvbnN0IHsgcmV0dXJuIGJvZHk7IH0KICAgIHB1YmxpYzoKICAgIHN0YXRpYyBBZGFwdG9yICphZGFwdChSaWdpZEJvZHkmIGJvZHksIGludCBvZmZzZXQgPSAyKSB7IHJldHVybiBuZXcgQWRhcHRvcnsgYm9keSwgb2Zmc2V0IH07IH0KICAgIHN0YXRpYyBBZGFwdG9yIGNvbnN0ICphZGFwdChSaWdpZEJvZHkgY29uc3QmIGJvZHksIGludCBvZmZzZXQgPSAyKSB7IHJldHVybiBuZXcgQWRhcHRvcnsgYm9keSwgb2Zmc2V0IH07IH0KICAgICBmbG9hdCBnZXRQb3NpdGlvbigpIGNvbnN0CiAgICB7CiAgICAgICAgLy8gdGhpcyB1c2VzIHRoZSBjb25zdCBnZXRfYm9keSgpCiAgICAgICAgcmV0dXJuIGdldF9ib2R5KCkuZ2V0UG9zaXRpb24oKSArIG9mZnNldDsKICAgIH0KCiAgICB2b2lkIHNldFBvc2l0aW9uKGZsb2F0IHBwb3MpCiAgICB7CiAgICAgICAgLy8gdGhpcyB1c2VzIHRoZSBtdXRhYmxlIGdldF9ib2R5KCkKICAgICAgICBnZXRfYm9keSgpLnNldFBvc2l0aW9uKHBwb3Mtb2Zmc2V0KTsKICAgIH0KfTsKCmludCBtYWluKCkKewogICAgewogICAgICAgIFJpZ2lkQm9keSBiOwogICAgICAgIGF1dG8gKmEgPSBBZGFwdG9yOjphZGFwdChiKTsKICAgICAgICBhLT5zZXRQb3NpdGlvbigxNS4pOwogICAgICAgIGEtPmdldFBvc2l0aW9uKCk7CiAgICB9CgogICAgLyp7CiAgICAgICAgUmlnaWRCb2R5IGNvbnN0IGI7CiAgICAgICAgYXV0byAqYSA9IEFkYXB0b3I6OmFkYXB0KGIpOwogICAgICAgIGEtPnNldFBvc2l0aW9uKDE1Lik7ICAgICAvLyBlcnJvcjogcGFzc2luZyDigJhjb25zdCBBZGFwdG9y4oCZIGFzIOKAmHRoaXPigJkgYXJndW1lbnQgZGlzY2FyZHMgcXVhbGlmaWVycwogICAgICAgIGEtPmdldFBvc2l0aW9uKCk7CiAgICB9Ki8KfQo=