#include <functional>
template <typename T>
const T& default_get(T& value)
{ return value; }
template <typename T>
const T& default_set(T& value, const T& rhs)
{ return value = rhs; }
template <typename T,
std::function<const T& (T&)> get = default_get<T>,
std::function<T& (T&, const T&)> set = default_set<T>>
class property
{
public:
operator const T& () const
{ return get(_value); }
T& operator= (const T& rhs)
{ return set(_value, rhs); }
private:
T _value;
};
const int& log(const int& value) { std::cout << value; return value; }
struct S
{
property<int,
// log() used as decorator-style logging wrapper in properties
[] (int& value) { log(default_get<int>(value)); },
[] (int& value, const int& rhs) { log(default_set<int>(value, rhs)); }>
field_name;
};
/*
* The following is already possible with plain old functions, but cumbersome to write.
*/
template <typename T,
const T& (*get)(const T&) = default_get<T>,
T& (*set)(T&, const T&) = default_set<T> >
class property
{
public:
operator const T& () const
{ return get(_value); }
T& operator= (const T& rhs)
{ return set(_value, rhs); }
private:
T _value;
};
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KY29uc3QgVCYgZGVmYXVsdF9nZXQoVCYgdmFsdWUpCnsgcmV0dXJuIHZhbHVlOyB9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KY29uc3QgVCYgZGVmYXVsdF9zZXQoVCYgdmFsdWUsIGNvbnN0IFQmIHJocykKeyByZXR1cm4gdmFsdWUgPSByaHM7IH0KCnRlbXBsYXRlIDx0eXBlbmFtZSBULAogICAgICAgICAgc3RkOjpmdW5jdGlvbjxjb25zdCBUJiAoVCYpPiBnZXQgPSBkZWZhdWx0X2dldDxUPiwKICAgICAgICAgIHN0ZDo6ZnVuY3Rpb248VCYgKFQmLCBjb25zdCBUJik+IHNldCA9IGRlZmF1bHRfc2V0PFQ+PgpjbGFzcyBwcm9wZXJ0eQp7CnB1YmxpYzoKICAgIG9wZXJhdG9yIGNvbnN0IFQmICgpIGNvbnN0CiAgICB7IHJldHVybiBnZXQoX3ZhbHVlKTsgfQoKICAgIFQmIG9wZXJhdG9yPSAoY29uc3QgVCYgcmhzKQogICAgeyByZXR1cm4gc2V0KF92YWx1ZSwgcmhzKTsgfQoKcHJpdmF0ZToKICAgIFQgX3ZhbHVlOwp9OwoKY29uc3QgaW50JiBsb2coY29uc3QgaW50JiB2YWx1ZSkgeyBzdGQ6OmNvdXQgPDwgdmFsdWU7IHJldHVybiB2YWx1ZTsgIH0KCnN0cnVjdCBTCnsKICAgIHByb3BlcnR5PGludCwKICAgICAgICAvLyBsb2coKSB1c2VkIGFzIGRlY29yYXRvci1zdHlsZSBsb2dnaW5nIHdyYXBwZXIgaW4gcHJvcGVydGllcwogICAgICAgIFtdIChpbnQmIHZhbHVlKSB7IGxvZyhkZWZhdWx0X2dldDxpbnQ+KHZhbHVlKSk7IH0sCiAgICAgICAgW10gKGludCYgdmFsdWUsIGNvbnN0IGludCYgcmhzKSB7IGxvZyhkZWZhdWx0X3NldDxpbnQ+KHZhbHVlLCByaHMpKTsgfT4KICAgICAgICAgICAgZmllbGRfbmFtZTsKfTsKCi8qCiAqIFRoZSBmb2xsb3dpbmcgaXMgYWxyZWFkeSBwb3NzaWJsZSB3aXRoIHBsYWluIG9sZCBmdW5jdGlvbnMsIGJ1dCBjdW1iZXJzb21lIHRvIHdyaXRlLgogKi8KCnRlbXBsYXRlIDx0eXBlbmFtZSBULAogICAgICAgICAgY29uc3QgVCYgKCpnZXQpKGNvbnN0IFQmKSA9IGRlZmF1bHRfZ2V0PFQ+LAogICAgICAgICAgVCYgKCpzZXQpKFQmLCBjb25zdCBUJikgPSBkZWZhdWx0X3NldDxUPiA+CmNsYXNzIHByb3BlcnR5CnsKcHVibGljOgogICAgb3BlcmF0b3IgY29uc3QgVCYgKCkgY29uc3QKICAgIHsgcmV0dXJuIGdldChfdmFsdWUpOyB9CgogICAgVCYgb3BlcmF0b3I9IChjb25zdCBUJiByaHMpCiAgICB7IHJldHVybiBzZXQoX3ZhbHVlLCByaHMpOyB9Cgpwcml2YXRlOgogICAgVCBfdmFsdWU7Cn07