#pragma once namespace KapitanGame { template class ReadOnlyProperty { protected: C* Owner; T(C::* Getter)(); public: ReadOnlyProperty() : Owner(), Getter() {} ReadOnlyProperty(C* owner, T(C::* getter)()) : Owner(owner), Getter(getter) {} [[nodiscard]] T Get() const { return (Owner->*Getter)(); } // ReSharper disable once CppNonExplicitConversionOperator operator T() const { return Get(); } }; template class Property : public ReadOnlyProperty { void(C::* Setter)(T); public: Property() : ReadOnlyProperty(), Setter() {} Property(C* owner, T(C::* getter)(), void(C::* setter)(T)) : ReadOnlyProperty(owner,getter), Setter(setter) {} void Set(T value) const { (this->Owner->*Setter)(value); } const Property& operator = (T value) const { // NOLINT(misc-unconventional-assign-operator) Set(value); return *this; } const Property& operator -= (T value) const { // NOLINT(misc-unconventional-assign-operator) Set(this->Get() - value); return *this; } const Property& operator += (T value) const { // NOLINT(misc-unconventional-assign-operator) Set(this->Get() + value); return *this; } const Property& operator *= (T value) const { // NOLINT(misc-unconventional-assign-operator) Set(this->Get() * value); return *this; } const Property& operator /= (T value) const { // NOLINT(misc-unconventional-assign-operator) Set(this->Get() / value); return *this; } }; }