#include <stdio.h>
#include <functional>
/**
* The purpose of a property is to abstract how memory is accessed,
* so it makes sense it would wrap a pointer
*/
template <typename T>
class pointer_property {
private:
// A private pointer to the actual data
T* value;
public:
/**
* Constructor taking the pointer to the wrapped data
*
* @param ptr A pointer to the value
*/
pointer_property(T* ptr) {
value = ptr;
}
/**
* Gets the data
*/
operator T () {
return value[0];
}
/**
* Sets the data
*/
T operator = (const T &i) {
return value[0] = i;
}
};
/**
* The more common way of making a property is to wrap an address in memory with
* get and set logic.
*/
template <typename T>
class lambda_property {
private:
std::function<void(const T&)> setFunction;
std::function<T()> getFunction;
public:
/**
* Constructor taking the pointer to the wrapped data
*
* @param getf A function to set the value
* @param setf A function to get the value
*/
lambda_property(std::function<T()> getf, std::function<void(const T&)> setf) {
getFunction = getf;
setFunction = setf;
}
/**
* Gets the data
*/
operator T () {
return getFunction();
}
/**
* Sets the data
*/
T operator = (const T &i) {
setFunction(i);
return i;
}
};
class ExampleClass {
private:
int _value1 = 1;
int _value2 = 2;
public:
/**
* The getter for value 1
*/
int get_Value1() const { return _value1; }
/**
* The setter for value 1
*/
void set_Value1(int val) { _value1 = val;; }
};
class ExampleClass1 {
private:
int _value1 = 1;
int _value2 = 2;
public:
/**
* Creates a new instance of the example class
*/
ExampleClass1() {};
/**
* The Value property using a pointer
*/
pointer_property<int> Value1 = pointer_property<int>(&(this->_value1));
/**
* The Value property using a lambda
*/
lambda_property<int> Value2 = lambda_property<int>([this]() { return this->_value2; }, [this](int val) {this->_value2 = val; });
};
struct ExampleData{
int Value1 = 1;
int Value2 = 2;
};
class ExampleClass2 {
private:
ExampleData* _values = new ExampleData();
public:
/**
* The Value property using a pointer
*/
pointer_property<int> Value1 = pointer_property<int>(&(this->_values->Value1));
/**
* The Value property using a lambda
*/
lambda_property<int> Value2 = lambda_property<int>([this]() { return this->_values->Value2; }, [this](int val) {this->_values->Value2 = val; });
};
class ExampleClass3 {
private:
ExampleData* _values;
public:
/**
* Creates a new instance of the example class
*
* @param values The values wrapped by the class
*/
ExampleClass3(ExampleData* values) {
_values = values;
// Commenting this line out produces an error
this->Value1 = pointer_property<int>(&(this->_values->Value1));
};
/**
* Creates a new instance of the example class
*/
ExampleClass3() : ExampleClass3(new ExampleData()) {};
/**
* Destructor
*/
~ExampleClass3() {
if (_values == NULL) { return; }
delete _values;
_values = NULL;
}
/**
* The Value property using a pointer
*/
pointer_property<int> Value1 = pointer_property<int>(&(this->_values->Value1));
/**
* The Value property using a lambda
*/
lambda_property<int> Value2 = lambda_property<int>([this]() { return this->_values->Value2; }, [this](int val) {this->_values->Value2 = val; });
};
int main()
{
{
ExampleClass* ex = new ExampleClass();
printf("\nInitial:\n");
printf("ex->get_Value1() = %d\n", (int)ex->get_Value1());
ex->set_Value1(41);
printf("\nAfter set:\n");
printf("ex->get_Value1() = %d\n", (int)ex->get_Value1());
delete ex;
}
{
ExampleClass1* ex1 = new ExampleClass1();
printf("\nInitial:\n");
printf("ex1->Value1 = %d\n", (int)ex1->Value1);
printf("ex1->Value2 = %d\n", (int)ex1->Value2);
ex1->Value1 = 41;
ex1->Value2 = 42;
printf("\nAfter set:\n");
printf("ex1->Value1 = %d\n", (int)ex1->Value1);
printf("ex1->Value2 = %d\n", (int)ex1->Value2);
delete ex1;
}
{
ExampleClass2* ex2 = new ExampleClass2();
printf("\nInitial:\n");
printf("ex2->Value1 = %d\n", (int)ex2->Value1);
printf("ex2->Value2 = %d\n", (int)ex2->Value2);
ex2->Value1 = 41;
ex2->Value2 = 42;
printf("\nAfter set:\n");
printf("ex2->Value1 = %d\n", (int)ex2->Value1);
printf("ex2->Value2 = %d\n", (int)ex2->Value2);
delete ex2;
}
{
ExampleClass3* ex3 = new ExampleClass3();
printf("\nInitial:\n");
printf("ex3->Value1 = %d\n", (int)ex3->Value1);
printf("ex3->Value2 = %d\n", (int)ex3->Value2);
ex3->Value1 = 41;
ex3->Value2 = 42;
printf("\nAfter set:\n");
printf("ex3->Value1 = %d\n", (int)ex3->Value1);
printf("ex3->Value2 = %d\n", (int)ex3->Value2);
delete ex3;
}
return 0;
}