3#include "INotifyPropertyChanged.h"
33#define _SW_DEFINE_STATIC_GETTER(field) \
34 template <typename T, typename = void> \
35 struct _HasUserGetter_##field : std::false_type { \
37 template <typename T> \
38 struct _HasUserGetter_##field<T, decltype(void(&T::Get_##field))> : std::true_type { \
40 template <typename T> \
41 static auto _Get_##field(T &self) \
42 -> typename std::enable_if<_HasUserGetter_##field<T>::value, decltype(self.Get_##field())>::type \
44 return self.Get_##field(); \
46 template <typename T> \
47 static auto _Get_##field(T &self) \
48 -> typename std::enable_if<!_HasUserGetter_##field<T>::value, decltype(T::field) &>::type \
50 return self.##field; \
56#define _SW_DEFINE_STATIC_SETTER(field) \
57 template <typename T, typename = void> \
58 struct _HasUserSetter_##field : std::false_type { \
60 template <typename T> \
61 struct _HasUserSetter_##field<T, decltype(void(&T::Set_##field))> : std::true_type { \
63 template <typename T, typename U> \
64 static auto _Set_##field(T &self, U &&value) \
65 -> typename std::enable_if<_HasUserSetter_##field<T>::value>::type \
67 self.Set_##field(std::forward<U>(value)); \
69 template <typename T, typename U> \
70 static auto _Set_##field(T &self, U &&value) \
71 -> typename std::enable_if<!_HasUserSetter_##field<T>::value>::type \
73 self.##field = std::forward<U>(value); \
81#define SW_DEFINE_PROPERTY(name, field) \
82 _SW_DEFINE_STATIC_GETTER(field); \
83 _SW_DEFINE_STATIC_SETTER(field); \
84 sw::Property<decltype(field)> name \
86 sw::Property<decltype(field)>::Init(this) \
87 .Getter([](auto self) { \
88 return _Get_##field(*self); \
90 .Setter([](auto self, auto value) { \
91 _Set_##field(*self, value); \
98#define SW_DEFINE_READONLY_PROPERTY(name, field) \
99 _SW_DEFINE_STATIC_GETTER(field); \
100 sw::ReadOnlyProperty<decltype(field)> name \
102 sw::Property<decltype(field)>::Init(this) \
103 .Getter([](auto self) { \
104 return _Get_##field(*self); \
111#define SW_DEFINE_WRITEONLY_PROPERTY(name, field) \
112 _SW_DEFINE_STATIC_SETTER(field); \
113 sw::WriteOnlyProperty<decltype(field)> name \
115 sw::Property<decltype(field)>::Init(this) \
116 .Setter([](auto self, auto value) { \
117 _Set_##field(*self, value); \
125#define SW_DEFINE_NOTIFY_PROPERTY(name, field) \
126 _SW_DEFINE_STATIC_GETTER(field); \
127 template <typename T, typename = void> \
128 struct _HasUserSetter_##field : std::false_type { \
130 template <typename T> \
131 struct _HasUserSetter_##field<T, decltype(void(&T::Set_##field))> : std::true_type { \
133 template <typename T, typename U> \
134 static auto _Set_##field(T &self, U &&value) \
135 -> typename std::enable_if<_HasUserSetter_##field<T>::value>::type \
137 self.Set_##field(std::forward<U>(value)); \
139 template <typename T, typename U> \
140 static auto _Set_##field(T &self, U &&value) \
141 -> typename std::enable_if<!_HasUserSetter_##field<T>::value && sw::_EqOperationHelper<U, U>::value>::type \
143 if (!(_Get_##field(self) == value)) { \
144 self.##field = std::forward<U>(value); \
145 if (self.PropertyChanged) self.PropertyChanged(self, sw::Reflection::GetFieldId(&T::##name)); \
148 template <typename T, typename U> \
149 static auto _Set_##field(T &self, U &&value) \
150 -> typename std::enable_if<!_HasUserSetter_##field<T>::value && !sw::_EqOperationHelper<U, U>::value>::type \
152 self.##field = std::forward<U>(value); \
153 if (self.PropertyChanged) self.PropertyChanged(self, sw::Reflection::GetFieldId(&T::##name)); \
155 sw::Property<decltype(field)> name \
157 sw::Property<decltype(field)>::Init(this) \
158 .Getter([](auto self) { \
159 return _Get_##field(*self); \
161 .Setter([](auto self, auto value) { \
162 _Set_##field(*self, value); \
171#define _SW_DEFINE_EXPR_PROPERTY_VALUETYPE_HELPER(propname) \
172 template <typename TExpr, typename = void> \
173 struct _ExprPropertyValueTypeHelper_##propname { \
174 using type = typename std::decay<TExpr>::type; \
176 template <typename TExpr> \
177 struct _ExprPropertyValueTypeHelper_##propname< \
178 TExpr, typename std::enable_if<sw::_IsProperty<TExpr>::value>::type> { \
179 using type = typename TExpr::TValue; \
185#define _SW_EXPR_PROPERTY_VALUETYPE(propname, expr) \
186 typename _ExprPropertyValueTypeHelper_##propname<decltype(expr)>::type
191#define _SW_DEFINE_EXPR_STATIC_GETTER(propname, expr) \
192 template <typename T, typename U = decltype(expr)> \
193 static auto _Get_##propname(T &self) \
194 -> typename std::enable_if<sw::_IsProperty<U>::value, typename U::TValue>::type \
196 return (self.##expr).Get(); \
198 template <typename T, typename U = decltype(expr)> \
199 static auto _Get_##propname(T &self) \
200 -> typename std::enable_if<!sw::_IsProperty<U>::value, U>::type \
202 return (self.##expr); \
208#define _SW_DEFINE_EXPR_STATIC_SETTER(propname, expr) \
209 template <typename T, typename U, typename V = decltype(expr)> \
210 static auto _Set_##propname(T &self, U &&value) \
211 -> typename std::enable_if<sw::_IsProperty<V>::value>::type \
213 (self.##expr).Set(std::forward<U>(value)); \
215 template <typename T, typename U, typename V = decltype(expr)> \
216 static auto _Set_##propname(T &self, U &&value) \
217 -> typename std::enable_if<!sw::_IsProperty<V>::value>::type \
219 (self.##expr) = std::forward<U>(value); \
228#define SW_DEFINE_EXPR_PROPERTY(name, expr) \
229 _SW_DEFINE_EXPR_PROPERTY_VALUETYPE_HELPER(name); \
230 _SW_DEFINE_EXPR_STATIC_GETTER(name, expr); \
231 _SW_DEFINE_EXPR_STATIC_SETTER(name, expr); \
232 sw::Property<_SW_EXPR_PROPERTY_VALUETYPE(name, expr)> name \
234 sw::Property<_SW_EXPR_PROPERTY_VALUETYPE(name, expr)>::Init(this) \
235 .Getter([](auto self) { \
236 return _Get_##name(*self); \
238 .Setter([](auto self, auto value) { \
239 _Set_##name(*self, value); \
247#define SW_DEFINE_EXPR_READONLY_PROPERTY(name, expr) \
248 _SW_DEFINE_EXPR_PROPERTY_VALUETYPE_HELPER(name); \
249 _SW_DEFINE_EXPR_STATIC_GETTER(name, expr); \
250 sw::ReadOnlyProperty<_SW_EXPR_PROPERTY_VALUETYPE(name, expr)> name \
252 sw::Property<_SW_EXPR_PROPERTY_VALUETYPE(name, expr)>::Init(this) \
253 .Getter([](auto self) { \
254 return _Get_##name(*self); \
262#define SW_DEFINE_EXPR_WRITEONLY_PROPERTY(name, expr) \
263 _SW_DEFINE_EXPR_PROPERTY_VALUETYPE_HELPER(name); \
264 _SW_DEFINE_EXPR_STATIC_SETTER(name, expr); \
265 sw::WriteOnlyProperty<_SW_EXPR_PROPERTY_VALUETYPE(name, expr)> name \
267 sw::Property<_SW_EXPR_PROPERTY_VALUETYPE(name, expr)>::Init(this) \
268 .Setter([](auto self, auto value) { \
269 _Set_##name(*self, value); \
278#define SW_DEFINE_EXPR_NOTIFY_PROPERTY(name, expr) \
279 _SW_DEFINE_EXPR_PROPERTY_VALUETYPE_HELPER(name); \
280 _SW_DEFINE_EXPR_STATIC_GETTER(name, expr); \
281 template <typename T, typename U, typename V = decltype(expr)> \
282 static auto _Set_##name(T &self, U &&value) \
283 -> typename std::enable_if<sw::_IsProperty<V>::value && sw::_EqOperationHelper<U, U>::value>::type \
285 if (!((self.##expr).Get() == value)) { \
286 (self.##expr).Set(std::forward<U>(value)); \
287 if (self.PropertyChanged) self.PropertyChanged(self, sw::Reflection::GetFieldId(&T::##name)); \
290 template <typename T, typename U, typename V = decltype(expr)> \
291 static auto _Set_##name(T &self, U &&value) \
292 -> typename std::enable_if<sw::_IsProperty<V>::value && !sw::_EqOperationHelper<U, U>::value>::type \
294 (self.##expr).Set(std::forward<U>(value)); \
295 if (self.PropertyChanged) self.PropertyChanged(self, sw::Reflection::GetFieldId(&T::##name)); \
297 template <typename T, typename U, typename V = decltype(expr)> \
298 static auto _Set_##name(T &self, U &&value) \
299 -> typename std::enable_if<!sw::_IsProperty<V>::value && sw::_EqOperationHelper<U, U>::value>::type \
301 if (!((self.##expr) == value)) { \
302 (self.##expr) = std::forward<U>(value); \
303 if (self.PropertyChanged) self.PropertyChanged(self, sw::Reflection::GetFieldId(&T::##name)); \
306 template <typename T, typename U, typename V = decltype(expr)> \
307 static auto _Set_##name(T &self, U &&value) \
308 -> typename std::enable_if<!sw::_IsProperty<V>::value && !sw::_EqOperationHelper<U, U>::value>::type \
310 (self.##expr) = std::forward<U>(value); \
311 if (self.PropertyChanged) self.PropertyChanged(self, sw::Reflection::GetFieldId(&T::##name)); \
313 sw::Property<_SW_EXPR_PROPERTY_VALUETYPE(name, expr)> name \
315 sw::Property<_SW_EXPR_PROPERTY_VALUETYPE(name, expr)>::Init(this) \
316 .Getter([](auto self) { \
317 return _Get_##name(*self); \
319 .Setter([](auto self, auto value) { \
320 _Set_##name(*self, value); \