15 struct void_enable_if {
typedef void type; };
18 struct void_enable_if<false> { };
21 struct remove_cv {
typedef T type; };
24 struct remove_cv<const T> {
typedef typename remove_cv<T>::type type; };
27 struct remove_cv<volatile T> {
typedef typename remove_cv<T>::type type; };
29 template<
class,
class>
31 {
static const bool value =
false; };
35 {
static const bool value =
true; };
37 typedef char yes_type;
38 struct no_type {
char dummy[8];};
40 template<
class ObjectT,
int>
43 template<
class ObjectT>
44 yes_type has_getter_tester(sfinae<ObjectT,
sizeof(&ObjectT::get)>*);
45 template<
class ObjectT>
46 no_type has_getter_tester(...);
51 typedef typename remove_cv<T>::type type;
52 static const bool value =
sizeof(has_getter_tester<type>(0)) ==
sizeof(yes_type);
59 const void*(ObjectT::*Getter)()const,
60 void(ObjectT::*Setter)(const
void*, std::
size_t)
64 template<
unsigned N,
bool = true>
struct priority_tag : priority_tag < N - 1 > {};
65 template<
bool dummy>
struct priority_tag<0, dummy> {};
68 typedef const void* value_type;
70 tag_property(ObjectT *obj) :
75 void set(value_type value, std::size_t size)
83 template<
class T, std::
size_t count>
85 void set(
const T(&value)[count])
87 set_ptr(value, count *
sizeof(T));
94 set_value(value, priority_tag<2>());
98 value_type get()
const
100 return get_ptr( value_type() );
107 typedef const T* type;
108 return get_ptr( type() );
113 operator const T*()
const {
return get<T>(); }
115 template<
class T, std::
size_t count>
117 tag_property &operator=(
const T(&value)[count]) { set(value);
return *
this; }
121 tag_property &operator=(
const T &value) { set(value);
return *
this; }
124 value_type operator()(
void)
const {
return get(); }
127 void operator()(value_type value, std::size_t size) { set(value, size); }
129 template<
class T, std::
size_t count>
131 void operator()(
const T(&value)[count]) { set(value); }
135 void operator()(
const T &value) { set(value); }
139 const void*(OtherObjectT::*OtherGetter)()const,
140 void(OtherObjectT::*OtherSetter)(const
void*, std::
size_t)
143 bool operator==(const tag_property<OtherObjectT, OtherGetter, OtherSetter> &other)
145 value_type tmp = other.get();
146 return (get() == tmp);
151 const void*(OtherObjectT::*OtherGetter)()const,
152 void(OtherObjectT::*OtherSetter)(const
void*, std::
size_t)
155 bool operator!=(const tag_property<OtherObjectT, OtherGetter, OtherSetter> &other)
157 value_type tmp = other.get();
158 return (get() != tmp);
164 tag_property(
const tag_property &);
169 OtherValueT (OtherObjectT::*OtherGetter)()
const,
173 OtherValueT (OtherObjectT::*)()
const
177 void set_value(
const T<OtherObjectT, OtherValueT, OtherGetter> &value, priority_tag<3>)
179 const OtherValueT tmp = value;
180 set_ptr(&tmp,
sizeof(OtherValueT), priority_tag<3>());
186 OtherValueT (OtherObjectT::*OtherGetter)()
const,
187 void (OtherObjectT::*OtherSetter)(OtherValueT),
191 OtherValueT (OtherObjectT::*)()
const,
192 void (OtherObjectT::*)(OtherValueT)
196 void set_value(
const T<OtherObjectT, OtherValueT, OtherGetter, OtherSetter> &value, priority_tag<2>)
198 const OtherValueT tmp = value;
199 set_ptr(&tmp,
sizeof(OtherValueT), priority_tag<3>());
204 void set_value_from_get(T value)
206 set_ptr(&value,
sizeof(T), priority_tag<3>());
211 typename type_traits::void_enable_if<
212 type_traits::has_getter<T>::value
213 >::type set_value(T &value, priority_tag<1>)
215 set_value_from_get(value.get());
220 void set_value(T value, priority_tag<0>)
222 set_ptr(&value,
sizeof(T), priority_tag<3>());
227 void set_ptr(value_type value, std::size_t size, priority_tag<0>)
229 (_obj->*Setter)(value, size);
233 value_type get_ptr(value_type)
const
235 return (_obj->*Getter)();
239 #if !defined(NDEBUG) || defined(_DEBUG) || defined(DEBUG)
240 #define PH_WIDGETS_DEBUG_BUILD
243 #ifdef PH_WIDGETS_DEBUG_BUILD
245 static void type_id_func() {}
247 typedef std::map<value_type, std::set<void (*)()> > map_type;
249 static map_type &tag_pointers()
251 static map_type ptr_map_;
259 typename type_traits::remove_cv<T>
260 ::type get_ptr(T)
const
262 typedef const typename type_traits::remove_cv<T>::type type;
264 value_type value = (_obj->*Getter)();
265 type result =
dynamic_cast<type
>(value);
267 #ifdef PH_WIDGETS_DEBUG_BUILD
269 static map_type &ptr_map = tag_pointers();
271 map_type::iterator it = ptr_map.find(value);
272 if(ptr_map.end() != it)
278 if( it->second.find(&type_id_func<type>) == it->second.end() )
296 typename type_traits::void_enable_if<
297 false == type_traits::is_same<const T*, const void*>::value
298 >::type set_ptr(
const T *value, std::size_t size, priority_tag<1>)
300 typedef const typename type_traits::remove_cv<T>::type type;
302 (_obj->*Setter)(value, size);
304 #ifdef PH_WIDGETS_DEBUG_BUILD
306 value = get_ptr(value);
308 static map_type &ptr_map = tag_pointers();
310 map_type::iterator it = ptr_map.find(value);
312 if(ptr_map.end() != it)
317 it->second.insert(&type_id_func<type>);
323 map_type::mapped_type second;
324 second.insert(&type_id_func<type>);
325 ptr_map.insert(std::make_pair(value, second));
335 const void*(ObjectT::*Getter)()const,
336 void(ObjectT::*Setter)(const
void*, std::
size_t),
340 bool operator==(const tag_property<ObjectT, Getter, Setter> &lhs, const T &rhs) {
const T *tmp = lhs;
return (&rhs == tmp); }
344 const void*(ObjectT::*Getter)()const,
345 void(ObjectT::*Setter)(const
void*, std::
size_t),
349 bool operator==(const T &lhs, const tag_property<ObjectT, Getter, Setter> &rhs) {
const T *tmp = rhs;
return (&lhs == tmp); }
354 const void*(ObjectT::*Getter)()const,
355 void(ObjectT::*Setter)(const
void*, std::
size_t),
359 bool operator!=(const tag_property<ObjectT, Getter, Setter> &lhs, const T &rhs) {
const T *tmp = lhs;
return (&rhs != tmp); }
363 const void*(ObjectT::*Getter)()const,
364 void(ObjectT::*Setter)(const
void*, std::
size_t),
368 bool operator!=(const T &lhs, const tag_property<ObjectT, Getter, Setter> &rhs) {
const T *tmp = rhs;
return (&lhs != tmp); }
371#ifdef PH_WIDGETS_DEBUG_BUILD
372#undef PH_WIDGETS_DEBUG_BUILD