1#ifndef CPP_PROPERTY_HPP
2#define CPP_PROPERTY_HPP
4#include "stdex/include/type_traits.hpp"
20 template<
class T, T Val>
21 struct integral_constant
23 static const T value = Val;
25 typedef const T value_type;
26 typedef integral_constant<T, Val> type;
28 operator value_type()
const
33 value_type operator()()
const
39 typedef integral_constant<bool, true> true_type;
40 typedef integral_constant<bool, false> false_type;
43 struct remove_reference
49 struct remove_reference<T&>
61 struct remove_const<const T>
66 template <
bool,
class T>
70 struct enable_if_dummy;
76 struct enable_if<true, T>
81 typedef char yes_type;
93 struct any {
template <
class T> any(T
const&); };
100 typedef void_type type;
103 template<
class LhsT,
class RhsT,
class T =
void_type>
104 struct has_equal_test:
108 template<
class LhsT,
class RhsT>
109 struct has_equal_test<LhsT, RhsT,
110 typename sizeof_void_t<sizeof(declval<LhsT>() == declval<RhsT>())>::type>:
114 template<
class LhsT,
class RhsT,
class T =
void_type>
115 struct has_not_equal_test:
119 template<
class LhsT,
class RhsT>
120 struct has_not_equal_test<LhsT, RhsT,
121 typename sizeof_void_t<sizeof(declval<LhsT>() != declval<RhsT>())>::type>:
125 template<
class LhsT,
class RhsT,
class T =
void_type>
126 struct has_less_test:
130 template<
class LhsT,
class RhsT>
131 struct has_less_test<LhsT, RhsT,
132 typename sizeof_void_t<sizeof(declval<LhsT>() < declval<RhsT>())>::type>:
136 template<
class LhsT,
class RhsT,
class T =
void_type>
137 struct has_greater_test:
141 template<
class LhsT,
class RhsT>
142 struct has_greater_test<LhsT, RhsT,
143 typename sizeof_void_t<sizeof(declval<LhsT>() > declval<RhsT>())>::type>:
147 template<
class LhsT,
class RhsT,
class T =
void_type>
148 struct has_less_equal_test:
152 template<
class LhsT,
class RhsT>
153 struct has_less_equal_test<LhsT, RhsT,
154 typename sizeof_void_t<sizeof(declval<LhsT>() <= declval<RhsT>())>::type>:
158 template<
class LhsT,
class RhsT,
class T =
void_type>
159 struct has_greater_equal_test:
163 template<
class LhsT,
class RhsT>
164 struct has_greater_equal_test<LhsT, RhsT,
165 typename sizeof_void_t<sizeof(declval<LhsT>() >= declval<RhsT>())>::type>:
169 template <
class LhsT,
class RhsT>
172 static const bool value =
173 has_equal_test<LhsT, RhsT>::value;
176 template <
class LhsT,
class RhsT>
179 static const bool value =
180 has_not_equal_test<LhsT, RhsT>::value;
183 template <
class LhsT,
class RhsT>
186 static const bool value =
187 has_less_test<LhsT, RhsT>::value;
190 template <
class LhsT,
class RhsT>
193 static const bool value =
194 has_greater_test<LhsT, RhsT>::value;
197 template <
class LhsT,
class RhsT>
198 struct has_less_equal
200 static const bool value =
201 has_less_equal_test<LhsT, RhsT>::value;
204 template <
class LhsT,
class RhsT>
205 struct has_greater_equal
207 static const bool value =
208 has_greater_equal_test<LhsT, RhsT>::value;
212 template<
unsigned N>
struct priority_tag : priority_tag < N - 1 > {};
213 template<>
struct priority_tag<0> {};
216 yes_type is_convertable_tester(T, priority_tag<1>);
218 yes_type is_convertable_tester(any, priority_tag<0>);
220 template<
class FromT,
class ToT>
221 struct is_convertable
223 static const bool value =
224 sizeof(is_convertable_tester<ToT>(declval<FromT>(), priority_tag<1>())) ==
sizeof(yes_type);
227 template <
typename ValueT,
typename CValueT>
228 struct flag_chooser_helper
230 static const property_flag::e_property_flag flag = property_flag::rw;
233 template <
typename ValueT>
234 struct flag_chooser_helper<ValueT, ValueT>
236 static const property_flag::e_property_flag flag = property_flag::ro;
239 template <
typename ValueT>
240 struct flag_chooser_helper<ValueT, void>
242 static const property_flag::e_property_flag flag = property_flag::wo;
246 struct flag_chooser_helper<void, void>
251 struct flag_chooser :
252 public flag_chooser_helper<T1, const T1>
257 struct flag_chooser<T1&> :
258 public flag_chooser_helper<T1, const T1>
262 template<
class ValueT,
class ParentT =
void_type>
265 typedef ValueT value_type;
266 typedef typename remove_reference<typename remove_const<value_type>::type>::type & reference;
267 typedef typename remove_reference<typename remove_const<value_type>::type>::type
const & const_reference;
269 typedef ParentT parent_t;
270 typedef value_type(parent_t::* getter_t)()
const;
271 typedef void(parent_t::* setter_t)(value_type);
273 static const getter_t &default_getter() {
static getter_t getter = getter_t(0);
return getter;}
274 static const setter_t &default_setter() {
static setter_t setter = setter_t(0);
return setter;}
278 struct property_info<void, void>
280 typedef void value_type;
282 typedef void_type parent_t;
283 typedef const int getter_t;
284 typedef const int setter_t;
286 static const getter_t &default_getter() {
static getter_t getter = 0;
return getter;}
287 static const setter_t &default_setter() {
static setter_t setter = 0;
return setter;}
290 template<
class ValueT>
291 struct property_info<ValueT, void>
293 typedef ValueT value_type;
294 typedef typename remove_reference<typename remove_const<value_type>::type>::type & reference;
295 typedef typename remove_reference<typename remove_const<value_type>::type>::type
const & const_reference;
297 typedef value_type(*getter_t)();
298 typedef void(*setter_t)(value_type);
300 static const getter_t &default_getter() {
static getter_t getter = getter_t(0);
return getter;}
301 static const setter_t &default_setter() {
static setter_t setter = setter_t(0);
return setter;}
304 template<
class ParentT>
305 struct property_info<void, ParentT> :
306 public property_info<void, void>
309 template<
class ParentT>
310 struct property_info<void_type, ParentT> :
311 public property_info<void, void>
314 template<
class ValueT>
315 struct property_info<ValueT, void_type> :
316 public property_info<ValueT, void>
320 template<
class ValueT>
323 typedef ValueT value_type;
324 virtual value_type get()
const = 0;
327 template<
class ValueT>
328 struct Ipropertyr<ValueT&>
330 typedef const ValueT & value_type;
331 virtual value_type get()
const = 0;
334 typedef typename detail::property_info<ValueT>::reference backdoor_type;
335 virtual backdoor_type backdoor() = 0;
338 template<
class ValueT>
339 struct Ipropertyr<const ValueT&>
341 typedef const ValueT & value_type;
342 virtual value_type get()
const = 0;
345 template<
class ValueT>
346 struct Ipropertyr_without_backdoor:
347 public Ipropertyr<ValueT>
350 template<
class ValueT>
351 struct Ipropertyr_without_backdoor<ValueT&>:
352 public Ipropertyr<const ValueT&>
355 template<
class ValueT>
358 typedef ValueT value_type;
359 virtual void set(ValueT) = 0;
362 template<
class ChildT,
class ValueT,
363 const detail::property_flag::e_property_flag Flag =
364 static_cast<const detail::property_flag::e_property_flag
>(detail::flag_chooser<typename ChildT::value_type>::flag)>
365 struct property_traits {};
367 template<
class ValueT = void,
368 const detail::property_flag::e_property_flag Flag =
369 static_cast<const detail::property_flag::e_property_flag
>(detail::flag_chooser<ValueT>::flag)>
374 class property<void, detail::property_flag::ro>:
375 public detail::property_flag
378 typedef detail::property_flag flags;
382 class property<void, detail::property_flag::wo>:
383 public detail::property_flag
386 typedef detail::property_flag flags;
390 class property<void, detail::property_flag::rw>:
391 public detail::property_flag
394 typedef detail::property_flag flags;
398 template<
class ValueT>
399 class property<ValueT, detail::property_flag::ro>:
400 public virtual Ipropertyr<typename detail::property_info<ValueT>::const_reference>,
401 public property_traits<
402 property<ValueT, detail::property_flag::ro>,
403 typename detail::property_info<ValueT>::const_reference, detail::property_flag::ro>
405 typedef Ipropertyr_without_backdoor<typename detail::property_info<ValueT>::value_type> Ipropertyr_without_backdoor_type;
407 typedef typename detail::property_info<ValueT>::value_type value_type;
408 typedef typename detail::property_info<ValueT>::reference reference;
409 typedef typename detail::property_info<ValueT>::const_reference const_reference;
411 template<class ParentT, typename detail::property_info<ValueT, ParentT>::getter_t Getter>
413 public virtual Ipropertyr_without_backdoor_type,
414 public property_traits<bind<ParentT, Getter>, typename Ipropertyr_without_backdoor_type::value_type, detail::property_flag::ro>
416 typedef typename detail::remove_const<ParentT>::type
const parent_type;
419 typedef typename Ipropertyr_without_backdoor_type::value_type value_type;
420 typedef typename detail::property_info<ValueT, ParentT>::reference reference;
421 typedef typename detail::property_info<ValueT, ParentT>::const_reference const_reference;
424 explicit bind(parent_type *parent) :
429 value_type get()
const
431 return (_obj->*Getter)();
435 operator value_type()
const {
return get(); }
438 value_type operator()(
void)
const {
return get(); }
443 bind(
const bind &rhs);
445 bind &operator=(value_type);
446 bind &operator=(bind
const &);
451 template<typename detail::property_info<ValueT, void>::getter_t Getter>
453 public virtual Ipropertyr_without_backdoor_type,
454 public property_traits<bind_static<Getter>, typename Ipropertyr_without_backdoor_type::value_type, detail::property_flag::ro>
457 typedef typename Ipropertyr_without_backdoor_type::value_type value_type;
458 typedef typename detail::property_info<ValueT>::reference reference;
459 typedef typename detail::property_info<ValueT>::const_reference const_reference;
465 value_type get()
const
471 operator value_type()
const {
return get(); }
474 value_type operator()(
void)
const {
return get(); }
478 bind_static(
const bind_static &rhs);
481 bind_static &operator=(value_type);
483 bind_static &operator=(bind_static
const &);
488 property(value_type value) :
493 const_reference get()
const
499 operator const_reference()
const {
return get(); }
502 const_reference operator()(
void)
const {
return get(); }
508 property &operator=(const_reference);
509 property &operator=(property
const &);
515 template<
class ValueT>
516 class property<ValueT, detail::property_flag::rw>:
517 public virtual Ipropertyr<typename detail::property_info<ValueT>::reference>,
518 public Ipropertyw<typename detail::property_info<ValueT>::value_type>,
519 public property_traits<
520 property<ValueT, detail::property_flag::rw>,
521 typename detail::property_info<ValueT>::reference, detail::property_flag::rw>
524 typedef typename detail::property_info<ValueT>::value_type value_type;
525 typedef typename detail::property_info<ValueT>::reference reference;
526 typedef typename detail::property_info<ValueT>::const_reference const_reference;
528 template<class ParentT, typename detail::property_info<ValueT, ParentT>::getter_t Getter,
typename detail::property_info<ValueT, ParentT>::setter_t Setter>
530 public virtual Ipropertyr<typename detail::property_info<ValueT>::value_type>,
531 public Ipropertyw<typename detail::property_info<ValueT>::value_type>,
532 public property_traits<bind<ParentT, Getter, Setter>, typename detail::property_info<ValueT>::value_type, detail::property_flag::rw>
534 typedef typename detail::remove_const<ParentT>::type parent_type;
536 typedef typename detail::property_info<ValueT>::value_type value_type;
537 typedef typename detail::property_info<ValueT>::reference reference;
538 typedef typename detail::property_info<ValueT>::const_reference const_reference;
540 explicit bind(parent_type *parent) :
544 bind(parent_type *parent, value_type value) :
551 void set(value_type value)
553 (_obj->*Setter)(value);
557 value_type get()
const
559 return (_obj->*Getter)();
563 operator value_type()
const {
return get(); }
566 bind &operator=(value_type value) { set(value);
return *
this; }
569 value_type operator()(
void)
const {
return get(); }
572 void operator()(value_type value) { set(value); }
579 value_type backdoor() {
return (_obj->*Getter)();}
585 property(value_type value) :
590 void set(value_type value)
596 const_reference get()
const
602 property &operator=(value_type value) { set(value);
return *
this; }
605 operator const_reference()
const {
return get(); }
608 const_reference operator()(
void)
const {
return get(); }
611 void operator()(value_type value) { set(value); }
617 typedef Ipropertyr<typename detail::property_info<ValueT>::reference> Ipropertyr_base;
620 Ipropertyr_base::backdoor_type backdoor() {
return _val;}
623 template<
class ValueT>
624 class property<ValueT, detail::property_flag::wo>:
625 public Ipropertyw<typename detail::property_info<ValueT>::value_type>,
626 public property_traits<property<ValueT, detail::property_flag::wo>, typename detail::property_info<ValueT>::value_type, detail::property_flag::wo>
629 typedef typename detail::property_info<ValueT>::value_type value_type;
630 typedef typename detail::property_info<ValueT>::reference reference;
631 typedef typename detail::property_info<ValueT>::const_reference const_reference;
633 template<class ParentT, typename detail::property_info<ValueT, ParentT>::setter_t Setter>
635 public Ipropertyw<typename detail::property_info<ValueT>::value_type>,
636 public property_traits<bind<ParentT, Setter>, typename detail::property_info<ValueT>::value_type, detail::property_flag::wo>
638 typedef typename detail::remove_const<ParentT>::type parent_type;
640 typedef typename detail::property_info<ValueT>::value_type value_type;
641 typedef typename detail::property_info<ValueT>::reference reference;
642 typedef typename detail::property_info<ValueT>::const_reference const_reference;
644 explicit bind(parent_type *parent) :
648 bind(parent_type *parent, value_type value) :
655 void set(value_type value)
657 (_obj->*Setter)(value);
661 bind &operator=(value_type value) { set(value);
return *
this; }
664 void operator()(value_type value) { set(value); }
674 property(value_type value) :
679 void set(value_type value)
685 property &operator=(value_type value) { set(value);
return *
this; }
688 void operator()(value_type value) { set(value); }
695 template<
class ValueT,
class OtherValueT>
699 detail::has_equal<ValueT, OtherValueT>::value
708 const Ipropertyr<ValueT> &lhs,
709 const OtherValueT &rhs)
711 return lhs.get() == rhs;
714 template<
class ValueT,
class OtherValueT>
718 detail::has_not_equal<ValueT, OtherValueT>::value
727 const Ipropertyr<ValueT> &lhs,
728 const OtherValueT &rhs)
730 return lhs.get() != rhs;
733 template<
class ValueT,
class OtherValueT>
737 detail::has_less<ValueT, OtherValueT>::value
746 const Ipropertyr<ValueT> &lhs,
747 const OtherValueT &rhs)
749 return lhs.get() < rhs;
752 template<
class ValueT,
class OtherValueT>
756 detail::has_greater<ValueT, OtherValueT>::value
765 const Ipropertyr<ValueT> &lhs,
766 const OtherValueT &rhs)
768 return lhs.get() > rhs;
771 template<
class ValueT,
class OtherValueT>
775 detail::has_less_equal<ValueT, OtherValueT>::value
784 const Ipropertyr<ValueT> &lhs,
785 const OtherValueT &rhs)
787 return lhs.get() <= rhs;
790 template<
class ValueT,
class OtherValueT>
794 detail::has_greater_equal<ValueT, OtherValueT>::value
803 const Ipropertyr<ValueT> &lhs,
804 const OtherValueT &rhs)
806 return lhs.get() >= rhs;
871 template<
class Enable,
class T =
void_type>
872 struct enable_if_type
875 template<
class T,
class Enabled =
void_type>
878 static const bool value =
false;
882 struct has_size_type<
884 typename enable_if_type<typename T::size_type>::type
887 static const bool value =
true;
890 template<
class T,
class Enabled =
void_type>
891 struct has_const_iterator
893 static const bool value =
false;
897 struct has_const_iterator<
899 typename enable_if_type<typename T::const_iterator>::type
902 static const bool value =
true;
905 template<
class T,
class Enabled =
void_type>
908 static const bool value =
false;
914 typename enable_if_type<typename T::iterator>::type
917 static const bool value =
true;
920 template<
class T,
bool Enabled>
921 struct size_property_trait_impl
925 struct size_property_trait_impl<T, true>:
926 public virtual Ipropertyr<T>
929 typedef typename remove_reference<T>::type clear_type;
930 typedef Ipropertyr<T> base_type;
931 using base_type::get;
933 typedef typename clear_type::size_type size_type;
935 size_type size()
const
941 template<
class T,
bool Enabled>
942 struct const_begin_end_property_trait_impl
946 struct const_begin_end_property_trait_impl<T, true>:
947 public virtual Ipropertyr<T>
950 typedef typename remove_reference<T>::type clear_type;
951 typedef Ipropertyr<T> base_type;
952 using base_type::get;
954 typedef typename clear_type::const_iterator const_iterator;
956 const_iterator begin()
const
958 return get().begin();
961 const_iterator end()
const
966 const_iterator cbegin()
const
968 return get().begin();
971 const_iterator cend()
const
977 template<
class T,
bool Enabled>
978 struct begin_end_property_trait_impl
982 struct begin_end_property_trait_impl<T, true>:
983 public virtual Ipropertyr<T>
986 typedef typename remove_reference<T>::type clear_type;
987 typedef Ipropertyr<T> base_type;
988 using base_type::backdoor;
990 typedef typename clear_type::iterator iterator;
994 return backdoor().begin();
999 return backdoor().end();
1003 template<
class T,
bool HasImpl,
bool HasConstImpl>
1004 struct begin_end_property_trait_impl1
1008 struct begin_end_property_trait_impl1<T, true, false>:
1009 begin_end_property_trait_impl<T, true>
1013 struct begin_end_property_trait_impl1<T, false, true>:
1014 const_begin_end_property_trait_impl<T, true>
1018 struct begin_end_property_trait_impl1<T, true, true>:
1019 const_begin_end_property_trait_impl<T, true>,
1020 begin_end_property_trait_impl<T, true>
1022 using const_begin_end_property_trait_impl<T,
true>::begin;
1023 using const_begin_end_property_trait_impl<T,
true>::end;
1024 using begin_end_property_trait_impl<T,
true>::begin;
1025 using begin_end_property_trait_impl<T,
true>::end;
1028 template<
class T,
bool Enabled>
1029 struct dereference_member_property_trait_impl
1033 struct dereference_member_property_trait_impl<T*,
true>:
1034 public virtual Ipropertyr<T*>
1037 typedef Ipropertyr<T*> base_type;
1038 using base_type::get;
1040 T* operator->()
const
1047 struct dereference_member_property_trait_impl<T*&,
true>:
1048 public virtual Ipropertyr<T*&>
1051 typedef Ipropertyr<T*&> base_type;
1052 using base_type::get;
1054 T* operator->()
const
1061 struct dereference_property_trait_impl
1065 struct dereference_property_trait_impl<T*>:
1066 public virtual Ipropertyr<T*>,
1067 public dereference_member_property_trait_impl<T*, stdex::is_class<typename stdex::remove_reference<T>::type>::value>
1070 typedef Ipropertyr<T*> base_type;
1071 using base_type::get;
1073 T& operator*()
const
1080 struct dereference_property_trait_impl<T*&>:
1081 public virtual Ipropertyr<T*&>,
1082 public dereference_member_property_trait_impl<T*&, stdex::is_class<T>::value>
1085 typedef Ipropertyr<T*&> base_type;
1086 using base_type::get;
1088 T& operator*()
const
1094 template<
class ChildT,
class ValueT,
bool>
1095 struct arithmetic_property_trait_impl
1098 ChildT& operator+()
const
1100 ChildT &that = *(ChildT*)(
this);
1105 ChildT& operator-()
const
1107 ChildT &that = *(ChildT*)(
this);
1108 typename ChildT::value_type tmp =
1115 ChildT &operator++()
1117 ChildT &that = *(ChildT*)(
this);
1118 typename ChildT::value_type tmp =
1126 ChildT& operator++(
int)
1127 {
return ++(*this); }
1130 ChildT &operator--()
1132 ChildT &that = *(ChildT*)(
this);
1133 typename ChildT::value_type tmp =
1141 ChildT& operator--(
int)
1142 {
return --(*this); }
1145 ChildT &operator+=(ValueT value)
1147 ChildT &that = *(ChildT*)(
this);
1148 typename ChildT::value_type tmp =
1156 ChildT &operator-=(ValueT value)
1158 ChildT &that = *(ChildT*)(
this);
1159 typename ChildT::value_type tmp =
1168 ChildT &operator*=(
const ValueT value)
1170 ChildT &that = *(ChildT*)(
this);
1171 typename ChildT::value_type tmp =
1180 ChildT &operator/=(
const ValueT value)
1182 ChildT &that = *(ChildT*)(
this);
1183 typename ChildT::value_type tmp =
1210 template<
class ChildT,
class ValueT>
1211 struct arithmetic_property_trait_impl<ChildT, ValueT, false> {};
1214 struct size_property_trait:
1215 size_property_trait_impl<T, has_size_type<typename remove_reference<T>::type>::value>
1219 struct const_begin_end_property_trait
1223 struct const_begin_end_property_trait<T&>:
1224 const_begin_end_property_trait_impl<T&, has_const_iterator<typename remove_reference<T>::type>::value>
1228 struct begin_end_property_trait
1232 struct begin_end_property_trait<T&>:
1233 begin_end_property_trait_impl1<T&, has_iterator<typename remove_reference<T>::type>::value, has_const_iterator<typename remove_reference<T>::type>::value>
1237 struct dereference_property_trait
1241 struct dereference_property_trait<T*>:
1242 dereference_property_trait_impl<T*>
1246 struct dereference_property_trait<T*&>:
1247 dereference_property_trait_impl<T*&>
1250 template<
class ChildT,
class ValueT>
1251 struct arithmetic_property_trait
1252 :
public arithmetic_property_trait_impl<ChildT, ValueT, stdex::is_arithmetic<ValueT>::value>
1258 template<
class ChildT,
class ValueT>
1259 struct property_traits<ChildT, ValueT, property<>::ro>:
1260 detail::size_property_trait<ValueT>,
1261 detail::const_begin_end_property_trait<ValueT>,
1262 detail::dereference_property_trait<ValueT>
1265 template<
class ChildT,
class ValueT>
1266 struct property_traits<ChildT, ValueT, property<>::rw>:
1267 detail::size_property_trait<ValueT>,
1268 detail::begin_end_property_trait<ValueT>,
1269 detail::dereference_property_trait<ValueT>,
1270 detail::arithmetic_property_trait<ChildT, ValueT>