#ifndef Core_Property_h
#define Core_Property_h
#include "Util/Util.h"
#include <stdint.h>
#define ENABLE_PROPERTIES(...) typedef __VA_ARGS__ _core_property_h_thisClass_
#define TYPE() type
#define GETTER(type, name) type Get##name()
#define SETTER(type, name) type & Set##name(type & value)
#define PROPERTY(type, name, ...) \
__VA_ARGS__ \
typedef type _core_property_h_##name##type; \
class UNIQUE_TOKEN(_core_property_h_property_class_) \
{ \
public: \
UNIQUE_TOKEN(_core_property_h_property_class_) (type& initialValue) { GetContainingInstance()->Set##name(initialValue); } \
operator type() { return GetContainingInstance()->Get##name(); } \
template<typename T> \
T& operator =(T& other) { GetContainingInstance()->Set##name(other); return other; } \
private: \
_core_property_h_thisClass_* GetContainingInstance() { return (_core_property_h_thisClass_*)((int8_t*)(this) - offsetof(_core_property_h_thisClass_, UNIQUE_TOKEN(_core_property_h_property_datamember_))); } \
}; \
UNIQUE_TOKEN(_core_property_h_property_class_) UNIQUE_TOKEN(_core_property_h_property_datamember_) \
//For non Standard-Layout classes as per C++11. Requires initialization because offsetof is not permitted
#define NON_STANDARD_LAYOUT_PROPERTY(type, name, ...) \
__VA_ARGS__ \
class UNIQUE_TOKEN(_core_property_h_property_class_) \
{ \
public: \
UNIQUE_TOKEN(_core_property_h_property_class_) (_core_property_h_thisClass_& container, type& initialValue) : container(container) { container.Set##name(initialValue); } \
operator type() { return container.Get##name(); } \
template<typename T> \
T& operator =(T& other) { container.Set##name(other); return other; } \
private: \
_core_property_h_thisClass_& container; \
}; \
UNIQUE_TOKEN(_core_property_h_property_class_) UNIQUE_TOKEN(_core_property_h_property_datamember_) \
#endif