Created
July 10, 2019 12:18
-
-
Save Voltra/b82eb50f5a227eb71e7991d1edc40a8d to your computer and use it in GitHub Desktop.
C++ Properties (magic get/set)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <functional> | |
#include <utility> | |
using namespace std; | |
template <class T> | |
class property{ | |
public: | |
using setter_type = function<void(T&, const T&)>; | |
using getter_type = function<T&(T&)>; | |
protected: | |
getter_type getter; | |
setter_type setter; | |
T value; | |
public: | |
/*template <class... Args> | |
property(getter_type get, setter_type set, Args&&... args) : getter{get}, setter{set}, value{std::forward<Args>(args)...} { | |
cout << "constructed"; | |
}*/ | |
template <class U> | |
property(getter_type get, setter_type set, U&& arg) : getter{get}, setter{set}, value{std::forward<U>(arg)} { | |
} | |
/*template <class... Args> | |
property(Args&&... args) : property( | |
defaultGetter, | |
defaultSetter, | |
std::forward<Args>(args)... | |
){}*/ | |
operator T&(){ | |
return this->getter(this->value); | |
} | |
property& operator=(const T& rhs){ | |
this->setter(this->value, rhs); | |
return *this; | |
} | |
public: | |
static setter_type noSetter; | |
static getter_type defaultGetter; | |
static setter_type defaultSetter; | |
}; | |
template <class T, class... Args> | |
property<T> make_default_property(Args&&... args){ | |
return property<T>{ | |
property<T>::defaultGetter, | |
property<T>::defaultSetter, | |
T{std::forward<Args>(args)...} | |
}; | |
} | |
template <class T> | |
typename property<T>::setter_type property<T>::noSetter = [](T& value, const T& assignment){}; | |
template <class T> | |
typename property<T>::getter_type property<T>::defaultGetter = [](T& value) -> T& { | |
return value; | |
}; | |
template <class T> | |
typename property<T>::setter_type property<T>::defaultSetter = [](T& value, const T& assignment){ | |
value = assignment; | |
}; | |
property<int>::getter_type logGet = [](int& target) -> int&{ | |
printf("[GET] %i\n", target); | |
return target; | |
}; | |
property<int>::setter_type logSet = [](int& target, const int& assignment) -> void{ | |
printf("[SET] old: %i new: %i\n", target, assignment); | |
}; | |
int main() { | |
property<int> i{logGet, logSet, 0}; | |
std::cout << i << '\n'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment