Photon microGUI widgets library 0.6.0
property.hpp
1#ifndef CPP_PROPERTY_HPP
2#define CPP_PROPERTY_HPP
3
4#include "stdex/include/type_traits.hpp"
5
6namespace cppproperties
7{
8 namespace detail
9 {
10 struct property_flag
11 {
12 enum e_property_flag
13 {
14 ro,
15 wo,
16 rw
17 };
18 };
19
20 template<class T, T Val>
21 struct integral_constant
22 { // convenient template for integral constant types
23 static const T value = Val;
24
25 typedef const T value_type;
26 typedef integral_constant<T, Val> type;
27
28 operator value_type() const
29 { // return stored value
30 return (value);
31 }
32
33 value_type operator()() const
34 { // return stored value
35 return (value);
36 }
37 };
38
39 typedef integral_constant<bool, true> true_type;
40 typedef integral_constant<bool, false> false_type;
41
42 template<class T>
43 struct remove_reference
44 {
45 typedef T type;
46 };
47
48 template<class T>
49 struct remove_reference<T&>
50 {
51 typedef T type;
52 };
53
54 template<class T>
55 struct remove_const
56 {
57 typedef T type;
58 };
59
60 template<class T>
61 struct remove_const<const T>
62 {
63 typedef T type;
64 };
65
66 template <bool, class T>
67 struct enable_if
68 {
69 private:
70 struct enable_if_dummy;
71 public:
72 //typedef enable_if_dummy(&type)[1];
73 };
74
75 template <class T>
76 struct enable_if<true, T>
77 {
78 typedef T type;
79 };
80
81 typedef char yes_type;
82 struct no_type
83 {
84 char padding[8];
85 };
86
87 template<class T>
88 T& declref();
89
90 template<class T>
91 T declval();
92
93 struct any { template <class T> any(T const&); };
94
95 struct void_type {};
96
97 template<int>
98 struct sizeof_void_t
99 {
100 typedef void_type type;
101 };
102
103 template<class LhsT, class RhsT, class T = void_type>
104 struct has_equal_test:
105 false_type
106 {};
107
108 template<class LhsT, class RhsT>
109 struct has_equal_test<LhsT, RhsT,
110 typename sizeof_void_t<sizeof(declval<LhsT>() ==/*op*/ declval<RhsT>())>::type>:
111 true_type
112 {};
113
114 template<class LhsT, class RhsT, class T = void_type>
115 struct has_not_equal_test:
116 false_type
117 {};
118
119 template<class LhsT, class RhsT>
120 struct has_not_equal_test<LhsT, RhsT,
121 typename sizeof_void_t<sizeof(declval<LhsT>() !=/*op*/ declval<RhsT>())>::type>:
122 true_type
123 {};
124
125 template<class LhsT, class RhsT, class T = void_type>
126 struct has_less_test:
127 false_type
128 {};
129
130 template<class LhsT, class RhsT>
131 struct has_less_test<LhsT, RhsT,
132 typename sizeof_void_t<sizeof(declval<LhsT>() </*op*/ declval<RhsT>())>::type>:
133 true_type
134 {};
135
136 template<class LhsT, class RhsT, class T = void_type>
137 struct has_greater_test:
138 false_type
139 {};
140
141 template<class LhsT, class RhsT>
142 struct has_greater_test<LhsT, RhsT,
143 typename sizeof_void_t<sizeof(declval<LhsT>() >/*op*/ declval<RhsT>())>::type>:
144 true_type
145 {};
146
147 template<class LhsT, class RhsT, class T = void_type>
148 struct has_less_equal_test:
149 false_type
150 {};
151
152 template<class LhsT, class RhsT>
153 struct has_less_equal_test<LhsT, RhsT,
154 typename sizeof_void_t<sizeof(declval<LhsT>() <=/*op*/ declval<RhsT>())>::type>:
155 true_type
156 {};
157
158 template<class LhsT, class RhsT, class T = void_type>
159 struct has_greater_equal_test:
160 false_type
161 {};
162
163 template<class LhsT, class RhsT>
164 struct has_greater_equal_test<LhsT, RhsT,
165 typename sizeof_void_t<sizeof(declval<LhsT>() >=/*op*/ declval<RhsT>())>::type>:
166 true_type
167 {};
168
169 template <class LhsT, class RhsT>
170 struct has_equal
171 {
172 static const bool value =
173 has_equal_test<LhsT, RhsT>::value;
174 };
175
176 template <class LhsT, class RhsT>
177 struct has_not_equal
178 {
179 static const bool value =
180 has_not_equal_test<LhsT, RhsT>::value;
181 };
182
183 template <class LhsT, class RhsT>
184 struct has_less
185 {
186 static const bool value =
187 has_less_test<LhsT, RhsT>::value;
188 };
189
190 template <class LhsT, class RhsT>
191 struct has_greater
192 {
193 static const bool value =
194 has_greater_test<LhsT, RhsT>::value;
195 };
196
197 template <class LhsT, class RhsT>
198 struct has_less_equal
199 {
200 static const bool value =
201 has_less_equal_test<LhsT, RhsT>::value;
202 };
203
204 template <class LhsT, class RhsT>
205 struct has_greater_equal
206 {
207 static const bool value =
208 has_greater_equal_test<LhsT, RhsT>::value;
209 };
210
211
212 template<unsigned N> struct priority_tag : priority_tag < N - 1 > {};
213 template<> struct priority_tag<0> {};
214
215 template<class T>
216 yes_type is_convertable_tester(T, priority_tag<1>);
217 template<class T>
218 yes_type is_convertable_tester(any, priority_tag<0>);
219
220 template<class FromT, class ToT>
221 struct is_convertable
222 {
223 static const bool value =
224 sizeof(is_convertable_tester<ToT>(declval<FromT>(), priority_tag<1>())) == sizeof(yes_type);
225 };
226
227 template <typename ValueT, typename CValueT>
228 struct flag_chooser_helper
229 {
230 static const property_flag::e_property_flag flag = property_flag::rw;
231 };
232
233 template <typename ValueT>
234 struct flag_chooser_helper<ValueT, ValueT>
235 {
236 static const property_flag::e_property_flag flag = property_flag::ro;
237 };
238
239 template <typename ValueT>
240 struct flag_chooser_helper<ValueT, void>
241 {
242 static const property_flag::e_property_flag flag = property_flag::wo;
243 };
244
245 template <>
246 struct flag_chooser_helper<void, void>
247 {
248 };
249
250 template<class T1>
251 struct flag_chooser :
252 public flag_chooser_helper<T1, const T1>
253 {
254 };
255
256 template<class T1>
257 struct flag_chooser<T1&> :
258 public flag_chooser_helper<T1, const T1>
259 {
260 };
261
262 template<class ValueT, class ParentT = void_type>
263 struct property_info
264 {
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;
268
269 typedef ParentT parent_t;
270 typedef value_type(parent_t::* getter_t)()const;
271 typedef void(parent_t::* setter_t)(value_type);
272
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;}
275 };
276
277 template<>
278 struct property_info<void, void>
279 {
280 typedef void value_type;
281
282 typedef void_type parent_t;
283 typedef const int getter_t;
284 typedef const int setter_t;
285
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;}
288 };
289
290 template<class ValueT>
291 struct property_info<ValueT, void>
292 {
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;
296
297 typedef value_type(*getter_t)();
298 typedef void(*setter_t)(value_type);
299
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;}
302 };
303
304 template<class ParentT>
305 struct property_info<void, ParentT> :
306 public property_info<void, void>
307 { };
308
309 template<class ParentT>
310 struct property_info<void_type, ParentT> :
311 public property_info<void, void>
312 { };
313
314 template<class ValueT>
315 struct property_info<ValueT, void_type> :
316 public property_info<ValueT, void>
317 { };
318 }
319
320 template<class ValueT>
321 struct Ipropertyr
322 {
323 typedef ValueT value_type;
324 virtual value_type get() const = 0;
325 };
326
327 template<class ValueT>
328 struct Ipropertyr<ValueT&>
329 {
330 typedef const ValueT & value_type;
331 virtual value_type get() const = 0;
332
333 protected:
334 typedef typename detail::property_info<ValueT>::reference backdoor_type;
335 virtual backdoor_type backdoor() = 0;
336 };
337
338 template<class ValueT>
339 struct Ipropertyr<const ValueT&>
340 {
341 typedef const ValueT & value_type;
342 virtual value_type get() const = 0;
343 };
344
345 template<class ValueT>
346 struct Ipropertyr_without_backdoor:
347 public Ipropertyr<ValueT>
348 {};
349
350 template<class ValueT>
351 struct Ipropertyr_without_backdoor<ValueT&>:
352 public Ipropertyr<const ValueT&>
353 {};
354
355 template<class ValueT>
356 struct Ipropertyw
357 {
358 typedef ValueT value_type;
359 virtual void set(ValueT) = 0;
360 };
361
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 {};
366
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)>
370 class property;
371
372 //property<void>:
373 template<>
374 class property<void, detail::property_flag::ro>:
375 public detail::property_flag
376 {
377 public:
378 typedef detail::property_flag flags;
379 };
380
381 template<>
382 class property<void, detail::property_flag::wo>:
383 public detail::property_flag
384 {
385 public:
386 typedef detail::property_flag flags;
387 };
388
389 template<>
390 class property<void, detail::property_flag::rw>:
391 public detail::property_flag
392 {
393 public:
394 typedef detail::property_flag flags;
395 };
396
397 //property<Value>:
398 template<class ValueT>
399 class property<ValueT, detail::property_flag::ro>: //ValueT == const...
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>
404 {
405 typedef Ipropertyr_without_backdoor<typename detail::property_info<ValueT>::value_type> Ipropertyr_without_backdoor_type;
406 public:
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;
410
411 template<class ParentT, typename detail::property_info<ValueT, ParentT>::getter_t Getter>
412 class bind:
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>
415 {
416 typedef typename detail::remove_const<ParentT>::type const parent_type;
417
418 public:
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;
422
423 inline
424 explicit bind(parent_type *parent) :
425 _obj(parent)
426 {}
427
428 inline
429 value_type get() const
430 {
431 return (_obj->*Getter)();
432 }
433
434 inline
435 operator value_type() const { return get(); }
436
437 inline
438 value_type operator()(void) const { return get(); }
439
440 private:
441 parent_type *_obj;
442
443 bind(const bind &rhs);
444
445 bind &operator=(value_type);
446 bind &operator=(bind const &);
447
448
449 };
450
451 template<typename detail::property_info<ValueT, void>::getter_t Getter>
452 class bind_static:
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>
455 {
456 public:
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;
460
461 bind_static()
462 {}
463
464 inline
465 value_type get() const
466 {
467 return (*Getter)();
468 }
469
470 inline
471 operator value_type() const { return get(); }
472
473 inline
474 value_type operator()(void) const { return get(); }
475
476 private:
477
478 bind_static(const bind_static &rhs);
479
480 inline
481 bind_static &operator=(value_type);
482 inline
483 bind_static &operator=(bind_static const &);
484
485
486 };
487
488 property(value_type value) :
489 _val(value)
490 {}
491
492 inline
493 const_reference get() const
494 {
495 return _val;
496 }
497
498 inline
499 operator const_reference() const { return get(); }
500
501 inline
502 const_reference operator()(void) const { return get(); }
503
504 private:
505
506 value_type _val;
507
508 property &operator=(const_reference);
509 property &operator=(property const &);
510
511
512 };
513
514
515 template<class ValueT>
516 class property<ValueT, detail::property_flag::rw>: //ValueT != const...
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>
522 {
523 public:
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;
527
528 template<class ParentT, typename detail::property_info<ValueT, ParentT>::getter_t Getter, typename detail::property_info<ValueT, ParentT>::setter_t Setter>
529 class bind:
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>
533 {
534 typedef typename detail::remove_const<ParentT>::type parent_type;
535 public:
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;
539
540 explicit bind(parent_type *parent) :
541 _obj(parent)
542 {}
543
544 bind(parent_type *parent, value_type value) :
545 _obj(parent)
546 {
547 set(value);
548 }
549
550 inline
551 void set(value_type value)
552 {
553 (_obj->*Setter)(value);
554 }
555
556 inline
557 value_type get() const
558 {
559 return (_obj->*Getter)();
560 }
561
562 inline
563 operator value_type() const { return get(); }
564
565 inline
566 bind &operator=(value_type value) { set(value); return *this; }
567
568 inline
569 value_type operator()(void) const { return get(); }
570
571 inline
572 void operator()(value_type value) { set(value); }
573
574 private:
575 parent_type *_obj;
576
577 bind(const bind &);
578
579 value_type backdoor() {return (_obj->*Getter)();}
580 };
581
582 property()
583 {}
584
585 property(value_type value) :
586 _val(value)
587 {}
588
589 inline
590 void set(value_type value)
591 {
592 _val = value;
593 }
594
595 inline
596 const_reference get() const
597 {
598 return _val;
599 }
600
601 inline
602 property &operator=(value_type value) { set(value); return *this; }
603
604 inline
605 operator const_reference() const { return get(); }
606
607 inline
608 const_reference operator()(void) const { return get(); }
609
610 inline
611 void operator()(value_type value) { set(value); }
612
613 private:
614
615 value_type _val;
616
617 typedef Ipropertyr<typename detail::property_info<ValueT>::reference> Ipropertyr_base;
618
619 typename
620 Ipropertyr_base::backdoor_type backdoor() {return _val;}
621 };
622
623 template<class ValueT>
624 class property<ValueT, detail::property_flag::wo>: //ValueT != const...
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>
627 {
628 public:
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;
632
633 template<class ParentT, typename detail::property_info<ValueT, ParentT>::setter_t Setter>
634 class bind:
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>
637 {
638 typedef typename detail::remove_const<ParentT>::type parent_type;
639 public:
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;
643
644 explicit bind(parent_type *parent) :
645 _obj(parent)
646 {}
647
648 bind(parent_type *parent, value_type value) :
649 _obj(parent)
650 {
651 set(value);
652 }
653
654 inline
655 void set(value_type value)
656 {
657 (_obj->*Setter)(value);
658 }
659
660 inline
661 bind &operator=(value_type value) { set(value); return *this; }
662
663 inline
664 void operator()(value_type value) { set(value); }
665 private:
666 parent_type *_obj;
667
668 bind(const bind &);
669 };
670
671 property()
672 {}
673
674 property(value_type value) :
675 _val(value)
676 {}
677
678 inline
679 void set(value_type value)
680 {
681 _val = value;
682 }
683
684 inline
685 property &operator=(value_type value) { set(value); return *this; }
686
687 inline
688 void operator()(value_type value) { set(value); }
689
690 private:
691
692 value_type _val;
693 };
694
695 template<class ValueT, class OtherValueT>
696 typename
697 detail::enable_if<
698 (
699 detail::has_equal<ValueT, OtherValueT>::value/* ||
700 (
701 detail::is_convertable<OtherValueT, ValueT>::value &&
702 detail::has_equal<ValueT, ValueT>::value
703 )*/
704 )
705 ,
706 bool
707 >::type operator==(
708 const Ipropertyr<ValueT> &lhs,
709 const OtherValueT &rhs)
710 {
711 return lhs.get() == rhs;
712 }
713
714 template<class ValueT, class OtherValueT>
715 typename
716 detail::enable_if<
717 (
718 detail::has_not_equal<ValueT, OtherValueT>::value/* ||
719 (
720 detail::is_convertable<OtherValueT, ValueT>::value &&
721 detail::has_not_equal<ValueT, ValueT>::value
722 )*/
723 )
724 ,
725 bool
726 >::type operator!=(
727 const Ipropertyr<ValueT> &lhs,
728 const OtherValueT &rhs)
729 {
730 return lhs.get() != rhs;
731 }
732
733 template<class ValueT, class OtherValueT>
734 typename
735 detail::enable_if<
736 (
737 detail::has_less<ValueT, OtherValueT>::value/* ||
738 (
739 detail::is_convertable<OtherValueT, ValueT>::value &&
740 detail::has_less<ValueT, ValueT>::value
741 )*/
742 )
743 ,
744 bool
745 >::type operator<(
746 const Ipropertyr<ValueT> &lhs,
747 const OtherValueT &rhs)
748 {
749 return lhs.get() < rhs;
750 }
751
752 template<class ValueT, class OtherValueT>
753 typename
754 detail::enable_if<
755 (
756 detail::has_greater<ValueT, OtherValueT>::value/* ||
757 (
758 detail::is_convertable<OtherValueT, ValueT>::value &&
759 detail::has_greater<ValueT, ValueT>::value
760 )*/
761 )
762 ,
763 bool
764 >::type operator>(
765 const Ipropertyr<ValueT> &lhs,
766 const OtherValueT &rhs)
767 {
768 return lhs.get() > rhs;
769 }
770
771 template<class ValueT, class OtherValueT>
772 typename
773 detail::enable_if<
774 (
775 detail::has_less_equal<ValueT, OtherValueT>::value/* ||
776 (
777 detail::is_convertable<OtherValueT, ValueT>::value &&
778 detail::has_less_equal<ValueT, ValueT>::value
779 )*/
780 )
781 ,
782 bool
783 >::type operator<=(
784 const Ipropertyr<ValueT> &lhs,
785 const OtherValueT &rhs)
786 {
787 return lhs.get() <= rhs;
788 }
789
790 template<class ValueT, class OtherValueT>
791 typename
792 detail::enable_if<
793 (
794 detail::has_greater_equal<ValueT, OtherValueT>::value/* ||
795 (
796 detail::is_convertable<OtherValueT, ValueT>::value &&
797 detail::has_greater_equal<ValueT, ValueT>::value
798 )*/
799 )
800 ,
801 bool
802 >::type operator>=(
803 const Ipropertyr<ValueT> &lhs,
804 const OtherValueT &rhs)
805 {
806 return lhs.get() >= rhs;
807 }
808
809 /*template<class ValueT, class OtherValueT>
810 typename
811 detail::enable_if<
812 !detail::has_equal<OtherValueT, property<ValueT, property<>::wo> >::value &&
813 (
814 detail::has_equal<OtherValueT, ValueT>::value ||
815 (
816 detail::is_convertable<ValueT, OtherValueT>::value &&
817 detail::has_equal<OtherValueT, OtherValueT>::value
818 )
819 )
820 ,
821 bool
822 >::type operator==(
823 const OtherValueT &lhs,
824 const property<ValueT, property<>::wo> &rhs)
825 {
826 return lhs == rhs._val;
827 }
828
829 template<class ValueT, class OtherValueT>
830 typename
831 detail::enable_if<
832 !detail::has_not_equal<OtherValueT, property<ValueT, property<>::wo> >::value &&
833 (
834 detail::has_not_equal<OtherValueT, ValueT>::value ||
835 (
836 detail::is_convertable<ValueT, OtherValueT>::value &&
837 detail::has_not_equal<OtherValueT, OtherValueT>::value
838 )
839 )
840 ,
841 bool
842 >::type operator!=(
843 const OtherValueT &lhs,
844 const property<ValueT, property<>::wo> &rhs)
845 {
846 return lhs != rhs._val;
847 }
848
849 template<class ValueT, class OtherValueT>
850 typename
851 detail::enable_if<
852 !detail::has_less<OtherValueT, property<ValueT, property<>::wo> >::value &&
853 (
854 detail::has_less<OtherValueT, ValueT>::value ||
855 (
856 detail::is_convertable<ValueT, OtherValueT>::value &&
857 detail::has_less<OtherValueT, OtherValueT>::value
858 )
859 )
860 ,
861 bool
862 >::type operator<(
863 const OtherValueT &lhs,
864 const property<ValueT, property<>::wo> &rhs)
865 {
866 return lhs < rhs._val;
867 }*/
868
869 namespace detail
870 {
871 template<class Enable, class T = void_type>
872 struct enable_if_type
873 { typedef T type; };
874
875 template<class T, class Enabled = void_type>
876 struct has_size_type
877 {
878 static const bool value = false;
879 };
880
881 template<class T>
882 struct has_size_type<
883 T,
884 typename enable_if_type<typename T::size_type>::type
885 >
886 {
887 static const bool value = true;
888 };
889
890 template<class T, class Enabled = void_type>
891 struct has_const_iterator
892 {
893 static const bool value = false;
894 };
895
896 template<class T>
897 struct has_const_iterator<
898 T,
899 typename enable_if_type<typename T::const_iterator>::type
900 >
901 {
902 static const bool value = true;
903 };
904
905 template<class T, class Enabled = void_type>
906 struct has_iterator
907 {
908 static const bool value = false;
909 };
910
911 template<class T>
912 struct has_iterator<
913 T,
914 typename enable_if_type<typename T::iterator>::type
915 >
916 {
917 static const bool value = true;
918 };
919
920 template<class T, bool Enabled>
921 struct size_property_trait_impl
922 { };
923
924 template<class T>
925 struct size_property_trait_impl<T, true>:
926 public virtual Ipropertyr<T>
927 {
928 private:
929 typedef typename remove_reference<T>::type clear_type;
930 typedef Ipropertyr<T> base_type;
931 using base_type::get;
932 public:
933 typedef typename clear_type::size_type size_type;
934
935 size_type size() const
936 {
937 return get().size();
938 }
939 };
940
941 template<class T, bool Enabled>
942 struct const_begin_end_property_trait_impl
943 { };
944
945 template<class T>
946 struct const_begin_end_property_trait_impl<T, true>:
947 public virtual Ipropertyr<T>
948 {
949 private:
950 typedef typename remove_reference<T>::type clear_type;
951 typedef Ipropertyr<T> base_type;
952 using base_type::get;
953 public:
954 typedef typename clear_type::const_iterator const_iterator;
955
956 const_iterator begin() const
957 {
958 return get().begin();
959 }
960
961 const_iterator end() const
962 {
963 return get().end();
964 }
965
966 const_iterator cbegin() const
967 {
968 return get().begin();
969 }
970
971 const_iterator cend() const
972 {
973 return get().end();
974 }
975 };
976
977 template<class T, bool Enabled>
978 struct begin_end_property_trait_impl
979 { };
980
981 template<class T>
982 struct begin_end_property_trait_impl<T, true>:
983 public virtual Ipropertyr<T>
984 {
985 private:
986 typedef typename remove_reference<T>::type clear_type;
987 typedef Ipropertyr<T> base_type;
988 using base_type::backdoor;
989 public:
990 typedef typename clear_type::iterator iterator;
991
992 iterator begin()
993 {
994 return backdoor().begin();
995 }
996
997 iterator end()
998 {
999 return backdoor().end();
1000 }
1001 };
1002
1003 template<class T, bool HasImpl, bool HasConstImpl>
1004 struct begin_end_property_trait_impl1
1005 { };
1006
1007 template<class T>
1008 struct begin_end_property_trait_impl1<T, true, false>:
1009 begin_end_property_trait_impl<T, true>
1010 { };
1011
1012 template<class T>
1013 struct begin_end_property_trait_impl1<T, false, true>:
1014 const_begin_end_property_trait_impl<T, true>
1015 { };
1016
1017 template<class T>
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>
1021 {
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;
1026 };
1027
1028 template<class T, bool Enabled>
1029 struct dereference_member_property_trait_impl
1030 { };
1031
1032 template<class T>
1033 struct dereference_member_property_trait_impl<T*, true>:
1034 public virtual Ipropertyr<T*>
1035 {
1036 private:
1037 typedef Ipropertyr<T*> base_type;
1038 using base_type::get;
1039 public:
1040 T* operator->() const
1041 {
1042 return get();
1043 }
1044 };
1045
1046 template<class T>
1047 struct dereference_member_property_trait_impl<T*&, true>:
1048 public virtual Ipropertyr<T*&>
1049 {
1050 private:
1051 typedef Ipropertyr<T*&> base_type;
1052 using base_type::get;
1053 public:
1054 T* operator->() const
1055 {
1056 return get();
1057 }
1058 };
1059
1060 template<class T>
1061 struct dereference_property_trait_impl
1062 { };
1063
1064 template<class T>
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>
1068 {
1069 private:
1070 typedef Ipropertyr<T*> base_type;
1071 using base_type::get;
1072 public:
1073 T& operator*() const
1074 {
1075 return *get();
1076 }
1077 };
1078
1079 template<class T>
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>
1083 {
1084 private:
1085 typedef Ipropertyr<T*&> base_type;
1086 using base_type::get;
1087 public:
1088 T& operator*() const
1089 {
1090 return *get();
1091 }
1092 };
1093
1094 template<class ChildT, class ValueT, bool>
1095 struct arithmetic_property_trait_impl
1096 {
1097 inline
1098 ChildT& operator+() const
1099 {
1100 ChildT &that = *(ChildT*)(this);
1101 return that;
1102 }
1103
1104 inline
1105 ChildT& operator-() const
1106 {
1107 ChildT &that = *(ChildT*)(this);
1108 typename ChildT::value_type tmp =
1109 that.get();
1110 that.set(-tmp);
1111 return that;
1112 }
1113
1114 inline
1115 ChildT &operator++()
1116 {
1117 ChildT &that = *(ChildT*)(this);
1118 typename ChildT::value_type tmp =
1119 that.get();
1120 tmp++;
1121 that.set(tmp);
1122 return that;
1123 }
1124
1125 inline
1126 ChildT& operator++(int)
1127 { return ++(*this); }
1128
1129 inline
1130 ChildT &operator--()
1131 {
1132 ChildT &that = *(ChildT*)(this);
1133 typename ChildT::value_type tmp =
1134 that.get();
1135 tmp--;
1136 that.set(tmp);
1137 return that;
1138 }
1139
1140 inline
1141 ChildT& operator--(int)
1142 { return --(*this); }
1143
1144 inline
1145 ChildT &operator+=(ValueT value)
1146 {
1147 ChildT &that = *(ChildT*)(this);
1148 typename ChildT::value_type tmp =
1149 that.get();
1150 tmp += value;
1151 that.set(tmp);
1152 return that;
1153 }
1154
1155 inline
1156 ChildT &operator-=(ValueT value)
1157 {
1158 ChildT &that = *(ChildT*)(this);
1159 typename ChildT::value_type tmp =
1160 that.get();
1161 tmp -= value;
1162 that.set(tmp);
1163 return that;
1164 }
1165
1166
1167 inline
1168 ChildT &operator*=(const ValueT value)
1169 {
1170 ChildT &that = *(ChildT*)(this);
1171 typename ChildT::value_type tmp =
1172 that.get();
1173 tmp *= value;
1174 that.set(tmp);
1175 return that;
1176 }
1177
1178
1179 inline
1180 ChildT &operator/=(const ValueT value)
1181 {
1182 ChildT &that = *(ChildT*)(this);
1183 typename ChildT::value_type tmp =
1184 that.get();
1185 tmp /= value;
1186 that.set(tmp);
1187 return that;
1188 }
1189
1190
1191 /*inline
1192 ChildT &operator%=(
1193 typename
1194 conditional<
1195 bool( stdex::is_floating_point<typename ChildT::value_type>::value == bool(false) ),
1196 const typename ChildT::value_type&,
1197 class _disabled1&
1198 >::type value
1199 )
1200 {
1201 ChildT &that = *(ChildT*)(this);
1202 typename ChildT::value_type tmp =
1203 that.get();
1204 tmp %= value;
1205 that.set(tmp);
1206 return that;
1207 }*/
1208 };
1209
1210 template<class ChildT, class ValueT>
1211 struct arithmetic_property_trait_impl<ChildT, ValueT, false> {};
1212
1213 template<class T>
1214 struct size_property_trait:
1215 size_property_trait_impl<T, has_size_type<typename remove_reference<T>::type>::value>
1216 { };
1217
1218 template<class T>
1219 struct const_begin_end_property_trait
1220 { };
1221
1222 template<class T>
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>
1225 { };
1226
1227 template<class T>
1228 struct begin_end_property_trait
1229 { };
1230
1231 template<class T>
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>
1234 { };
1235
1236 template<class T>
1237 struct dereference_property_trait
1238 { };
1239
1240 template<class T>
1241 struct dereference_property_trait<T*>:
1242 dereference_property_trait_impl<T*>
1243 { };
1244
1245 template<class T>
1246 struct dereference_property_trait<T*&>:
1247 dereference_property_trait_impl<T*&>
1248 { };
1249
1250 template<class ChildT, class ValueT>
1251 struct arithmetic_property_trait
1252 : public arithmetic_property_trait_impl<ChildT, ValueT, stdex::is_arithmetic<ValueT>::value>
1253 {
1254
1255 };
1256 }
1257
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>
1263 { };
1264
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>
1271 { };
1272
1273
1274 /*template<typename ValueT, typename ParentT = void, typename detail::get_parent_func<ValueT, ParentT>::getter_t Getter = 0, typename detail::get_parent_func<ValueT, ParentT>::setter_t Setter = 0,
1275 const detail::property_flag::e_property_flag Flag = (const detail::property_flag::e_property_flag)(detail::flag_chooser<ValueT>::flag)
1276 >
1277
1278 class property:
1279 public detail::property_base<ValueT, ParentT, detail::property_flag::e_property_flag(Flag)>
1280 {
1281 public:
1282
1283 property(ParentT *parent) :
1284 detail::property_base<ValueT, ParentT, Flag>(parent, Getter, Setter)
1285 {}
1286
1287 private:
1288
1289 property(const property &rhs);
1290 };
1291
1292
1293 //property<void>:
1294 template<detail::property_flag::e_property_flag Flag>
1295 class property<void, void, 0, 0, Flag>
1296 {
1297 public:
1298 typedef detail::property_flag flags;
1299 };
1300
1301
1302 //property<Value>:
1303 template<typename ValueT>
1304 class property<ValueT, void, 0, 0, detail::property_flag::r>//ValueT == const...
1305 {
1306 public:
1307
1308 property(ValueT const &value) :
1309 _val(value)
1310 {}
1311
1312 inline const ValueT &get() const
1313 {
1314 return _val;
1315 }
1316
1317 operator const ValueT&() const { return get(); }
1318
1319 private:
1320
1321 const ValueT _val;
1322
1323 property &operator=(ValueT const &);
1324 };
1325
1326
1327 template<typename ValueT>
1328 class property<ValueT, void, 0, 0, detail::property_flag::rw>//ValueT != const...
1329 {
1330 public:
1331
1332 property()
1333 {}
1334
1335 property(const ValueT &value) :
1336 _val(value)
1337 {}
1338
1339 inline void set(ValueT const &value)
1340 {
1341 _val = value;
1342 }
1343
1344 inline const ValueT &get() const
1345 {
1346 return _val;
1347 }
1348
1349 property &operator=(ValueT const &value) { set(value); return *this; }
1350
1351 operator const ValueT&() const { return get(); }
1352
1353 private:
1354
1355 ValueT _val;
1356
1357 };
1358
1359 template<typename ValueT>
1360 class property<ValueT, void, 0, 0, detail::property_flag::w>//ValueT != const...
1361 {
1362 public:
1363
1364 property()
1365 {}
1366
1367 property(const ValueT &value) :
1368 _val(value)
1369 {}
1370
1371 inline void set(ValueT const &value)
1372 {
1373 _val = value;
1374 }
1375
1376 property &operator=(ValueT const &value) { set(value); return *this; }
1377
1378 private:
1379
1380 ValueT _val;
1381 };
1382
1383
1384 //property<Value, ParentT>:
1385 template<typename ValueT, typename ParentT>
1386 class property<ValueT, ParentT, detail::get_parent_func<void, void>::default_getter(), detail::get_parent_func<void, void>::default_setter(), detail::property_flag::w>//ValueT == const...
1387 {
1388 public:
1389
1390 property(ParentT *parent, ValueT(ParentT::*getter)()const) :
1391 _obj(parent),
1392 _getter(getter)
1393 {}
1394
1395 inline ValueT get() const
1396 {
1397 return (_obj->*_getter)();
1398 }
1399
1400 operator ValueT() const { return get(); }
1401
1402 private:
1403 ParentT *_obj;
1404 ValueT(ParentT::*_getter)()const;
1405
1406 property &operator=(ValueT const &);
1407 };
1408
1409 template<typename ValueT, typename ParentT, typename ValueT(ParentT::*Getter)()const, typename void(ParentT::*Setter)(ValueT const &), detail::e_get_set_state Active>
1410 class property<ValueT, ParentT, Getter, Setter, detail::property_flag::rw, Active>//ValueT != const...
1411 {
1412 public:
1413
1414 property(ParentT *parent, const ValueT(ParentT::*getter)()const, void(ParentT::*setter)(ValueT const &), ValueT const & value) :
1415 _obj(parent),
1416 _getter(getter),
1417 _setter(setter)
1418 {
1419 set(value);
1420 }
1421
1422 property(ParentT *parent, const ValueT(ParentT::*getter)()const, void(ParentT::*setter)(ValueT const &)) :
1423 _obj(parent),
1424 _getter(getter),
1425 _setter(setter)
1426 {
1427 }
1428
1429 inline void set(ValueT const & value)
1430 {
1431 (_obj->*_setter)(value);
1432 }
1433
1434 inline const ValueT &get() const
1435 {
1436 return (_obj->*_getter)();
1437 }
1438
1439 property &operator=(ValueT const & value) { set(value); return *this; }
1440 private:
1441
1442 ParentT *_obj;
1443 const ValueT(ParentT::*_getter)()const;
1444 void(ParentT::*_setter)(ValueT const &);
1445
1446 };
1447
1448
1449 //property<Value, ParentT, ValueT(ParentT::*Getter)()>:
1450 template<typename ValueT, typename ParentT, typename detail::get_parent_func<ValueT, ParentT>::getter_t Getter, detail::property_flag::e_property_flag Flag>
1451 class property<ValueT, ParentT, Getter, 0, Flag> //typename detail::get_parent_func<typename ValueT, typename ParentT>::default_setter()
1452 {
1453 public:
1454
1455 property(ParentT *parent) :
1456 _obj(parent)
1457 {}
1458
1459 inline ValueT get() const
1460 {
1461 return (_obj->*Getter)();
1462 }
1463
1464 operator ValueT() const { return get(); }
1465
1466 private:
1467
1468 property &operator=(ValueT const &);
1469 };
1470
1471 //property<Value, ParentT, 0, ValueT(ParentT::*Setter)(ValueT const &)>:
1472 template<typename ValueT, typename ParentT, typename void(ParentT::*Setter)(ValueT const &), detail::e_get_set_state Active>
1473 class property<ValueT, ParentT, 0, Setter, detail::property_flag::r, Active>//ValueT == const...
1474 {
1475 property();//Invalid class: value is const but no Getter is provided!
1476
1477 property(const property &rhs);
1478 };
1479
1480 template<typename ValueT, typename ParentT, typename void(ParentT::*Setter)(ValueT const &), detail::property_flag::e_property_flag Flag, detail::e_get_set_state Active>
1481 class property<ValueT, ParentT, 0, Setter, Flag, Active>//ValueT != const...
1482 {
1483 public:
1484
1485 property()
1486 {}
1487
1488 property(ValueT const & value)
1489 {
1490 set(value);
1491 }
1492
1493 ValueT set(ValueT const & value)
1494 {
1495 return (_obj->*Setter)(value);
1496 }
1497
1498 property &operator=(ValueT const & value) { set(value); return *this; }
1499
1500 private:
1501 ParentT *_obj;
1502
1503 property(const property &rhs);
1504
1505 };
1506 */
1507
1508}
1509
1510#endif