Skip to content

Instantly share code, notes, and snippets.

@Voltra
Created July 10, 2019 12:18
Show Gist options
  • Save Voltra/b82eb50f5a227eb71e7991d1edc40a8d to your computer and use it in GitHub Desktop.
Save Voltra/b82eb50f5a227eb71e7991d1edc40a8d to your computer and use it in GitHub Desktop.
C++ Properties (magic get/set)
#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