SimpleWindow
载入中...
搜索中...
未找到
Reflection.h
1#pragma once
2
3// 定义SW_DISABLE_REFLECTION可以禁用反射相关功能
4// 若该宏被定义,则相关功能会抛出runtime_error异常
5// #define SW_DISABLE_REFLECTION
6
7#include "Delegate.h"
8#include "IComparable.h"
9#include "IToString.h"
10#include "Internal.h"
11#include "Property.h"
12#include <type_traits>
13#include <typeindex>
14
15namespace sw
16{
20 template <typename T, typename = void>
22
27 {
28 private:
32 template <typename, typename>
33 friend class BoxedObject;
34
38 bool _isBoxedObject;
39
40 public:
45 : _isBoxedObject(false)
46 {
47 }
48
53 {
54 }
55
61 {
62 return _isBoxedObject;
63 }
64
70 bool ReferenceEquals(const DynamicObject &other) const noexcept
71 {
72 if (this == &other) {
73 return true;
74 }
75 if (IsBoxedObject() && other.IsBoxedObject()) {
76 return GetBoxedRawPtr() == other.GetBoxedRawPtr();
77 }
78 return false;
79 }
80
85 std::type_index GetType() const noexcept
86 {
87#if defined(SW_DISABLE_REFLECTION)
88 throw std::runtime_error("Reflection is disabled, cannot get type index.");
89#else
90 if (IsBoxedObject()) {
91 return GetBoxedType();
92 } else {
93 return typeid(*this);
94 }
95#endif
96 }
97
104 template <typename T>
105 auto IsType(T **pout = nullptr)
106 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, bool>::type
107 {
108#if defined(SW_DISABLE_REFLECTION)
109 throw std::runtime_error("Reflection is disabled, cannot check type.");
110#else
111 if (pout == nullptr) {
112 return dynamic_cast<T *>(this) != nullptr;
113 } else {
114 *pout = dynamic_cast<T *>(this);
115 return *pout != nullptr;
116 }
117#endif
118 }
119
126 template <typename T>
127 auto IsType(const T **pout = nullptr) const
128 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, bool>::type
129 {
130#if defined(SW_DISABLE_REFLECTION)
131 throw std::runtime_error("Reflection is disabled, cannot check type.");
132#else
133 if (pout == nullptr) {
134 return dynamic_cast<const T *>(this) != nullptr;
135 } else {
136 *pout = dynamic_cast<const T *>(this);
137 return *pout != nullptr;
138 }
139#endif
140 }
141
148 template <typename T>
150 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, T &>::type
151 {
152#if defined(SW_DISABLE_REFLECTION)
153 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
154#else
155 return dynamic_cast<T &>(*this);
156#endif
157 }
158
165 template <typename T>
167 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, const T &>::type
168 {
169#if defined(SW_DISABLE_REFLECTION)
170 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
171#else
172 return dynamic_cast<const T &>(*this);
173#endif
174 }
175
182 template <typename T>
184 -> typename std::enable_if<
185 std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type
186 {
187 return static_cast<T &>(*this);
188 }
189
197 template <typename T>
199 -> typename std::enable_if<
200 std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
201 {
202 return DynamicCast<T>();
203 }
204
211 template <typename T>
213 -> typename std::enable_if<
214 std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
215 {
216 return static_cast<const T &>(*this);
217 }
218
226 template <typename T>
228 -> typename std::enable_if<
229 std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
230 {
231 return DynamicCast<T>();
232 }
233
234 public:
241 template <typename T>
242 auto IsType(T **pout = nullptr)
243 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
244
251 template <typename T>
252 auto IsType(T **pout = nullptr)
253 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
254
261 template <typename T>
262 auto IsType(const T **pout = nullptr) const
263 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
264
273 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
274
283 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, T &>::type;
284
293 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, T &>::type;
294
303 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type;
304
313 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type;
314
323 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type;
324
333 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type;
334
343 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type;
344
353 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type;
354
355 private:
360 virtual std::type_index GetBoxedType() const noexcept
361 {
362 return typeid(void);
363 }
364
369 virtual bool IsBoxedPolymorphic() const noexcept
370 {
371 return false;
372 }
373
378 virtual void *GetBoxedRawPtr() noexcept
379 {
380 return nullptr;
381 }
382
387 virtual const void *GetBoxedRawPtr() const noexcept
388 {
389 return nullptr;
390 }
391 };
392
393 /*================================================================================*/
394
398 template <typename T>
399 class BoxedObject<T, typename std::enable_if<!std::is_base_of<DynamicObject, T>::value>::type> final
400 : public DynamicObject
401 {
405 struct _IsRefParam {
406 bool val;
407 };
408
412 template <typename U, typename = void>
413 union _InternalData {
417 U *refptr;
418
422 alignas(U) uint8_t objbuf[sizeof(U)];
423 };
424
429 template <typename U>
430 union _InternalData<U, typename std::enable_if<std::is_abstract<U>::value>::type> {
434 U *refptr;
435
440 uint8_t objbuf[1];
441 };
442
443 private:
447 bool _isRef;
448
452 _InternalData<T> _data;
453
454 private:
460 : _isRef(isRef.val), _data()
461 {
462 _isBoxedObject = true;
463 }
464
468 void Release() noexcept(std::is_nothrow_destructible<T>::value)
469 {
470 if (!_isRef) {
471 Unbox().~T();
472 }
473 }
474
480 template <typename U = T>
481 auto NotRefCopyConstructImpl(const BoxedObject &other) noexcept(std::is_nothrow_copy_constructible<U>::value)
482 -> typename std::enable_if<std::is_copy_constructible<U>::value>::type
483 {
484 new (_data.objbuf) T(other.Unbox());
485 }
486
492 template <typename U = T>
493 auto NotRefCopyConstructImpl(const BoxedObject &other) noexcept(false)
494 -> typename std::enable_if<!std::is_copy_constructible<U>::value>::type
495 {
496 throw std::logic_error("Type T must be copy constructible to copy construct a non-ref BoxedObject.");
497 }
498
504 template <typename U = T>
505 auto NotRefMoveConstructImpl(BoxedObject &&other) noexcept(std::is_nothrow_move_constructible<U>::value)
506 -> typename std::enable_if<std::is_move_constructible<U>::value>::type
507 {
508 new (_data.objbuf) T(std::move(other.Unbox()));
509 }
510
516 template <typename U = T>
517 auto NotRefMoveConstructImpl(BoxedObject &&other) noexcept(false)
518 -> typename std::enable_if<!std::is_move_constructible<U>::value>::type
519 {
520 throw std::logic_error("Type T must be move constructible to move construct a non-ref BoxedObject.");
521 }
522
528 template <typename U = T>
529 auto NotRefCopyAssignImpl(const BoxedObject &other)
530 -> typename std::enable_if<std::is_copy_assignable<U>::value>::type
531 {
532 if (other._isRef) {
533 Release();
534 _data.refptr = other._data.refptr;
535 _isRef = true;
536 } else {
537 Unbox() = other.Unbox();
538 }
539 }
540
546 template <typename U = T>
547 auto NotRefCopyAssignImpl(const BoxedObject &other)
548 -> typename std::enable_if<!std::is_copy_assignable<U>::value>::type
549 {
550 if (other._isRef) {
551 Release();
552 _data.refptr = other._data.refptr;
553 _isRef = true;
554 } else {
555 throw std::logic_error("Type T must be copy assignable to copy assign a non-ref BoxedObject.");
556 }
557 }
558
564 template <typename U = T>
565 auto NotRefMoveAssignImpl(BoxedObject &&other)
566 -> typename std::enable_if<std::is_move_assignable<U>::value>::type
567 {
568 if (other._isRef) {
569 Release();
570 _data.refptr = other._data.refptr;
571 _isRef = true;
572 other._data.refptr = nullptr;
573 } else {
574 Unbox() = std::move(other.Unbox());
575 }
576 }
577
583 template <typename U = T>
584 auto NotRefMoveAssignImpl(BoxedObject &&other)
585 -> typename std::enable_if<!std::is_move_assignable<U>::value>::type
586 {
587 if (other._isRef) {
588 Release();
589 _data.refptr = other._data.refptr;
590 _isRef = true;
591 other._data.refptr = nullptr;
592 } else {
593 throw std::logic_error("Type T must be move assignable to move assign a non-ref BoxedObject.");
594 }
595 }
596
597 public:
602 template <typename... Args>
605 {
606 new (_data.objbuf) T(std::forward<Args>(args)...);
607 }
608
612 virtual ~BoxedObject()
613 {
614 Release();
615 }
616
622 static BoxedObject<T> MakeRef(T *ptr) noexcept
623 {
625 result._data.refptr = ptr;
626 return result;
627 }
628
634 static BoxedObject<T> MakeRef(T &ref) noexcept
635 {
636 return MakeRef(&ref);
637 }
638
645 template <typename U>
646 static auto MakeRef(BoxedObject<U> &other) noexcept
647 -> typename std::enable_if<_IsStaticCastable<U, T>::value, BoxedObject<T>>::type
648 {
650 result._data.refptr = other.IsNullRef() ? nullptr : static_cast<T *>(&other.Unbox());
651 return result;
652 }
653
659 BoxedObject(const BoxedObject &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
660 : BoxedObject(_IsRefParam{other._isRef})
661 {
662 if (_isRef) {
663 _data.refptr = other._data.refptr;
664 } else {
665 NotRefCopyConstructImpl(other);
666 }
667 }
668
674 BoxedObject(BoxedObject &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
675 : BoxedObject(_IsRefParam{other._isRef})
676 {
677 if (_isRef) {
678 _data.refptr = other._data.refptr;
679 other._data.refptr = nullptr;
680 } else {
681 NotRefMoveConstructImpl(std::move(other));
682 }
683 }
684
693 {
694 if (this == &other)
695 return *this;
696
697 if (_isRef) {
698 if (other._isRef) {
699 _data.refptr = other._data.refptr;
700 } else {
701 auto oldPtr = _data.refptr;
702 try {
703 NotRefCopyConstructImpl(other);
704 _isRef = false;
705 } catch (...) {
706 _data.refptr = oldPtr;
707 throw;
708 }
709 }
710 } else {
711 NotRefCopyAssignImpl(other);
712 }
713 return *this;
714 }
715
724 {
725 if (this == &other)
726 return *this;
727
728 if (_isRef) {
729 if (other._isRef) {
730 _data.refptr = other._data.refptr;
731 other._data.refptr = nullptr;
732 } else {
733 auto oldPtr = _data.refptr;
734 try {
735 NotRefMoveConstructImpl(std::move(other));
736 _isRef = false;
737 } catch (...) {
738 _data.refptr = oldPtr;
739 throw;
740 }
741 }
742 } else {
743 NotRefMoveAssignImpl(std::move(other));
744 }
745 return *this;
746 }
747
753 {
754 return _isRef;
755 }
756
762 {
763 return _isRef && (_data.refptr == nullptr);
764 }
765
771 {
772 return !IsNullRef();
773 }
774
781 {
782 assert(HasValue());
783 return _isRef ? *_data.refptr : *reinterpret_cast<T *>(_data.objbuf);
784 }
785
792 {
793 assert(HasValue());
794 return _isRef ? *_data.refptr : *reinterpret_cast<const T *>(_data.objbuf);
795 }
796
797 private:
802 virtual std::type_index GetBoxedType() const noexcept override
803 {
804 return typeid(T);
805 }
806
811 virtual bool IsBoxedPolymorphic() const noexcept override
812 {
813 return std::is_polymorphic<T>::value;
814 }
815
820 virtual void *GetBoxedRawPtr() noexcept override
821 {
822 // 当T带const时,refptr无法直接转换为void*,需要先转换为const void*再去掉const
823 return const_cast<void *>(
824 _isRef ? static_cast<const void *>(_data.refptr) : static_cast<const void *>(_data.objbuf));
825 }
826
831 virtual const void *GetBoxedRawPtr() const noexcept override
832 {
833 return _isRef ? static_cast<const void *>(_data.refptr) : static_cast<const void *>(_data.objbuf);
834 }
835 };
836
837 /*================================================================================*/
838
845 template <typename T>
846 auto DynamicObject::IsType(T **pout)
847 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
848 {
849#if defined(SW_DISABLE_REFLECTION)
850 throw std::runtime_error("Reflection is disabled, cannot check type.");
851#else
852 if (!_isBoxedObject) {
853 if (pout == nullptr) {
854 return dynamic_cast<T *>(this) != nullptr;
855 } else {
856 *pout = dynamic_cast<T *>(this);
857 return *pout != nullptr;
858 }
859 } else {
860 if (GetBoxedType() == typeid(T)) {
861 if (pout == nullptr) {
862 return GetBoxedRawPtr() != nullptr;
863 } else {
864 *pout = static_cast<T *>(GetBoxedRawPtr());
865 return *pout != nullptr;
866 }
867 } else {
868 if (pout != nullptr) {
869 *pout = nullptr;
870 }
871 return false;
872 }
873 }
874#endif
875 }
876
883 template <typename T>
884 auto DynamicObject::IsType(T **pout)
885 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
886 {
887#if defined(SW_DISABLE_REFLECTION)
888 throw std::runtime_error("Reflection is disabled, cannot check type.");
889#else
890 if (!_isBoxedObject) {
891 if (pout != nullptr) {
892 *pout = nullptr;
893 }
894 return false;
895 } else {
896 if (GetBoxedType() == typeid(T)) {
897 if (pout == nullptr) {
898 return GetBoxedRawPtr() != nullptr;
899 } else {
900 *pout = static_cast<T *>(GetBoxedRawPtr());
901 return *pout != nullptr;
902 }
903 } else {
904 if (pout != nullptr) {
905 *pout = nullptr;
906 }
907 return false;
908 }
909 }
910#endif
911 }
912
919 template <typename T>
920 auto DynamicObject::IsType(const T **pout) const
921 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
922 {
923#if defined(SW_DISABLE_REFLECTION)
924 throw std::runtime_error("Reflection is disabled, cannot check type.");
925#else
926 if (!_isBoxedObject) {
927 if (pout == nullptr) {
928 return dynamic_cast<const T *>(this) != nullptr;
929 } else {
930 *pout = dynamic_cast<const T *>(this);
931 return *pout != nullptr;
932 }
933 } else {
934 if (GetBoxedType() == typeid(T)) {
935 if (pout == nullptr) {
936 return GetBoxedRawPtr() != nullptr;
937 } else {
938 *pout = static_cast<const T *>(GetBoxedRawPtr());
939 return *pout != nullptr;
940 }
941 } else {
942 if (pout != nullptr) {
943 *pout = nullptr;
944 }
945 return false;
946 }
947 }
948#endif
949 }
950
957 template <typename T>
958 auto DynamicObject::IsType(const T **pout) const
959 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
960 {
961#if defined(SW_DISABLE_REFLECTION)
962 throw std::runtime_error("Reflection is disabled, cannot check type.");
963#else
964 if (!_isBoxedObject) {
965 if (pout != nullptr) {
966 *pout = nullptr;
967 }
968 return false;
969 } else {
970 if (GetBoxedType() == typeid(T)) {
971 if (pout == nullptr) {
972 return GetBoxedRawPtr() != nullptr;
973 } else {
974 *pout = static_cast<const T *>(GetBoxedRawPtr());
975 return *pout != nullptr;
976 }
977 } else {
978 if (pout != nullptr) {
979 *pout = nullptr;
980 }
981 return false;
982 }
983 }
984#endif
985 }
986
993 template <typename T>
995 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, T &>::type
996 {
997#if defined(SW_DISABLE_REFLECTION)
998 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
999#else
1000 if (!_isBoxedObject) {
1001 return dynamic_cast<T &>(*this);
1002 } else {
1003 void *rawPtr = GetBoxedRawPtr();
1004 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
1005 throw std::bad_cast();
1006 } else {
1007 return *static_cast<T *>(rawPtr);
1008 }
1009 }
1010#endif
1011 }
1012
1019 template <typename T>
1021 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, T &>::type
1022 {
1023#if defined(SW_DISABLE_REFLECTION)
1024 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
1025#else
1026 if (!_isBoxedObject) {
1027 throw std::bad_cast();
1028 } else {
1029 void *rawPtr = GetBoxedRawPtr();
1030 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
1031 throw std::bad_cast();
1032 } else {
1033 return *static_cast<T *>(rawPtr);
1034 }
1035 }
1036#endif
1037 }
1038
1045 template <typename T>
1046 auto DynamicObject::DynamicCast() const
1047 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type
1048 {
1049#if defined(SW_DISABLE_REFLECTION)
1050 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
1051#else
1052 if (!_isBoxedObject) {
1053 return dynamic_cast<const T &>(*this);
1054 } else {
1055 const void *rawPtr = GetBoxedRawPtr();
1056 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
1057 throw std::bad_cast();
1058 } else {
1059 return *static_cast<const T *>(rawPtr);
1060 }
1061 }
1062#endif
1063 }
1064
1071 template <typename T>
1072 auto DynamicObject::DynamicCast() const
1073 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type
1074 {
1075#if defined(SW_DISABLE_REFLECTION)
1076 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
1077#else
1078 if (!_isBoxedObject) {
1079 throw std::bad_cast();
1080 } else {
1081 const void *rawPtr = GetBoxedRawPtr();
1082 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
1083 throw std::bad_cast();
1084 } else {
1085 return *static_cast<const T *>(rawPtr);
1086 }
1087 }
1088#endif
1089 }
1090
1097 template <typename T>
1099 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type
1100 {
1101 if (!_isBoxedObject) {
1102 return static_cast<T &>(*this);
1103 } else {
1104 return static_cast<BoxedObject<T> &>(*this).Unbox();
1105 }
1106 }
1107
1115 template <typename T>
1117 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
1118 {
1119 if (!_isBoxedObject) {
1120 return DynamicCast<T>();
1121 } else {
1122 return static_cast<BoxedObject<T> &>(*this).Unbox();
1123 }
1124 }
1125
1132 template <typename T>
1133 auto DynamicObject::UnsafeCast() const
1134 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
1135 {
1136 if (!_isBoxedObject) {
1137 return static_cast<const T &>(*this);
1138 } else {
1139 return static_cast<const BoxedObject<T> &>(*this).Unbox();
1140 }
1141 }
1142
1150 template <typename T>
1151 auto DynamicObject::UnsafeCast() const
1152 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
1153 {
1154 if (!_isBoxedObject) {
1155 return DynamicCast<T>();
1156 } else {
1157 return static_cast<const BoxedObject<T> &>(*this).Unbox();
1158 }
1159 }
1160
1161 /*================================================================================*/
1162
1166 struct FieldId : public IToString<FieldId>,
1167 public IComparable<FieldId, FieldId> {
1172
1176 FieldId() = default;
1177
1182 : value(value)
1183 {
1184 }
1185
1189 std::wstring ToString() const
1190 {
1191 return std::to_wstring(value);
1192 }
1193
1199 {
1200 if (value == other.value) {
1201 return 0;
1202 } else {
1203 return value < other.value ? -1 : 1;
1204 }
1205 }
1206 };
1207
1208 /*================================================================================*/
1209
1214 {
1215 public:
1219 Reflection() = delete;
1220
1221 public:
1229 template <typename T, typename TField>
1231 {
1232 auto pfunc = &Reflection::GetFieldId<T, TField>;
1233
1234 uint8_t buffer[sizeof(pfunc) + sizeof(field)];
1235 memcpy(buffer, &pfunc, sizeof(pfunc));
1236 memcpy(buffer + sizeof(pfunc), &field, sizeof(field));
1237
1238 uint32_t prime = 16777619u;
1239 uint32_t hash = 2166136261u;
1240
1241 for (size_t i = 0; i < sizeof(buffer); ++i) {
1242 hash ^= static_cast<uint32_t>(buffer[i]);
1243 hash *= prime;
1244 }
1245
1246 return FieldId{hash};
1247 }
1248
1257 template <typename T, typename TRet, typename... Args>
1258 static auto GetMethod(TRet (T::*method)(Args...)) -> Delegate<TRet(DynamicObject &, Args...)>
1259 {
1260 return [method](DynamicObject &obj, Args... args) -> TRet {
1261 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
1262 };
1263 }
1264
1273 template <typename T, typename TRet, typename... Args>
1274 static auto GetMethod(TRet (T::*method)(Args...) const) -> Delegate<TRet(DynamicObject &, Args...)>
1275 {
1276 return [method](DynamicObject &obj, Args... args) -> TRet {
1277 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
1278 };
1279 }
1280
1288 template <typename T, typename TField>
1290 {
1291 return [field](DynamicObject &obj) -> TField & {
1292 return obj.UnsafeCast<T>().*field;
1293 };
1294 }
1295
1304 template <typename T, typename TProperty>
1306 -> typename std::enable_if<
1308 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
1309 {
1310 return [prop](DynamicObject &obj) -> typename TProperty::TValue {
1311 return (obj.UnsafeCast<T>().*prop).Get();
1312 };
1313 }
1314
1323 template <typename T, typename TProperty>
1325 -> typename std::enable_if<
1327 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
1328 {
1329 return nullptr;
1330 }
1331
1340 template <typename T, typename TProperty>
1342 -> typename std::enable_if<
1344 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
1345 {
1346 return [prop](DynamicObject &obj, typename TProperty::TSetterParam value) {
1347 (obj.UnsafeCast<T>().*prop).Set(std::forward<typename TProperty::TSetterParam>(value));
1348 };
1349 }
1350
1359 template <typename T, typename TProperty>
1361 -> typename std::enable_if<
1363 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
1364 {
1365 return nullptr;
1366 }
1367
1368 public:
1379 template <typename T, typename TFunc, typename... Args>
1380 static auto InvokeMethod(const Delegate<TFunc> &method, T &obj, Args &&...args)
1381 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value,
1382 decltype(method(obj, std::forward<Args>(args)...))>::type
1383 {
1384 assert(method != nullptr);
1385 return method(obj, std::forward<Args>(args)...);
1386 }
1387
1398 template <typename T, typename TFunc, typename... Args>
1399 static auto InvokeMethod(const Delegate<TFunc> &method, T &obj, Args &&...args)
1400 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value,
1401 decltype(method(std::declval<DynamicObject &>(), std::forward<Args>(args)...))>::type
1402 {
1403 assert(method != nullptr);
1404 auto boxed = BoxedObject<T>::MakeRef(obj);
1405 return method(boxed, std::forward<Args>(args)...);
1406 }
1407
1416 template <typename T, typename TField>
1417 static auto AccessField(const Delegate<TField &(DynamicObject &)> &accessor, T &obj)
1418 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, TField &>::type
1419 {
1420 assert(accessor != nullptr);
1421 return accessor(obj);
1422 }
1423
1432 template <typename T, typename TField>
1433 static auto AccessField(const Delegate<TField &(DynamicObject &)> &accessor, T &obj)
1434 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value, TField &>::type
1435 {
1436 assert(accessor != nullptr);
1437 auto boxed = BoxedObject<T>::MakeRef(obj);
1438 return accessor(boxed);
1439 }
1440
1449 template <typename T, typename TValue>
1450 static auto GetProperty(const Delegate<TValue(DynamicObject &)> &getter, T &obj)
1451 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, TValue>::type
1452 {
1453 assert(getter != nullptr);
1454 return getter(obj);
1455 }
1456
1465 template <typename T, typename TValue>
1466 static auto GetProperty(const Delegate<TValue(DynamicObject &)> &getter, T &obj)
1467 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value, TValue>::type
1468 {
1469 assert(getter != nullptr);
1470 auto boxed = BoxedObject<T>::MakeRef(obj);
1471 return getter(boxed);
1472 }
1473
1483 template <typename T, typename TParam, typename TValue>
1484 static auto SetProperty(const Delegate<void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value)
1485 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value>::type
1486 {
1487 assert(setter != nullptr);
1488 setter(obj, std::forward<TValue>(value));
1489 }
1490
1500 template <typename T, typename TParam, typename TValue>
1501 static auto SetProperty(const Delegate<void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value)
1502 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value>::type
1503 {
1504 assert(setter != nullptr);
1505 auto boxed = BoxedObject<T>::MakeRef(obj);
1506 setter(boxed, std::forward<TValue>(value));
1507 }
1508 };
1509}
1510
1511// 为sw::FieldId特化std::hash
1512template <>
1513struct std::hash<sw::FieldId> //
1514{
1515 size_t operator()(sw::FieldId fieldId) const noexcept
1516 {
1517 return static_cast<size_t>(fieldId.value);
1518 }
1519};
BoxedObject(const BoxedObject &other) noexcept(std::is_nothrow_copy_constructible< T >::value)
拷贝构造函数
Definition Reflection.h:659
static auto MakeRef(BoxedObject< U > &other) noexcept -> typename std::enable_if< _IsStaticCastable< U, T >::value, BoxedObject< T > >::type
创建引用类型的装箱对象
Definition Reflection.h:646
BoxedObject(BoxedObject &&other) noexcept(std::is_nothrow_move_constructible< T >::value)
移动构造函数
Definition Reflection.h:674
T & Unbox() noexcept
获取装箱对象中的值
Definition Reflection.h:780
static BoxedObject< T > MakeRef(T *ptr) noexcept
创建引用类型的装箱对象
Definition Reflection.h:622
BoxedObject(Args &&...args)
构造值类型的装箱对象
Definition Reflection.h:603
bool HasValue() const noexcept
判断当前装箱对象是否包含有效值
Definition Reflection.h:770
bool IsRef() const noexcept
判断当前装箱对象是否为引用类型
Definition Reflection.h:752
BoxedObject & operator=(BoxedObject &&other)
移动赋值运算符
Definition Reflection.h:723
static BoxedObject< T > MakeRef(T &ref) noexcept
创建引用类型的装箱对象
Definition Reflection.h:634
bool IsNullRef() const noexcept
判断当前装箱对象是否为空引用
Definition Reflection.h:761
const T & Unbox() const noexcept
获取装箱对象中的值
Definition Reflection.h:791
BoxedObject & operator=(const BoxedObject &other)
拷贝赋值运算符
Definition Reflection.h:692
装箱对象模板类声明
Definition Reflection.h:21
Definition Delegate.h:21
动态对象基类
Definition Reflection.h:27
auto UnsafeCast() -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&_IsStaticCastable< DynamicObject *, T * >::value, T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:183
auto IsType(const T **pout=nullptr) const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, bool >::type
判断对象是否为指定类型
Definition Reflection.h:127
std::type_index GetType() const noexcept
获取对象的类型信息
Definition Reflection.h:85
auto UnsafeCast() -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&!_IsStaticCastable< DynamicObject *, T * >::value, T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:198
auto UnsafeCast() const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&_IsStaticCastable< DynamicObject *, T * >::value, const T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:212
bool ReferenceEquals(const DynamicObject &other) const noexcept
判断与另一DynamicObject是否引用同一对象
Definition Reflection.h:70
auto UnsafeCast() const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&!_IsStaticCastable< DynamicObject *, T * >::value, const T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:227
virtual ~DynamicObject()
析构函数
Definition Reflection.h:52
auto DynamicCast() -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, T & >::type
将对象动态转换为指定类型的引用
Definition Reflection.h:149
auto IsType(const T **pout=nullptr) const -> typename std::enable_if<!std::is_base_of< DynamicObject, T >::value &&_IsDynamicCastable< DynamicObject *, T * >::value, bool >::type
判断对象是否为指定类型
auto DynamicCast() const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, const T & >::type
将对象动态转换为指定类型的常量引用
Definition Reflection.h:166
auto IsType(T **pout=nullptr) -> typename std::enable_if<!std::is_base_of< DynamicObject, T >::value &&_IsDynamicCastable< DynamicObject *, T * >::value, bool >::type
判断对象是否为指定类型
auto IsType(T **pout=nullptr) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, bool >::type
判断对象是否为指定类型
Definition Reflection.h:105
DynamicObject() noexcept
默认构造函数
Definition Reflection.h:44
bool IsBoxedObject() const noexcept
判断对象是否为装箱对象
Definition Reflection.h:60
auto IsType(T **pout=nullptr) -> typename std::enable_if<!std::is_base_of< DynamicObject, T >::value &&!_IsDynamicCastable< DynamicObject *, T * >::value, bool >::type
判断对象是否为指定类型
全序比较接口
Definition IComparable.h:54
为支持ToString方法的类提供统一接口
Definition IToString.h:13
值转换器接口
Definition IValueConverter.h:14
提供反射相关功能
Definition Reflection.h:1214
static auto GetMethod(TRet(T::*method)(Args...)) -> Delegate< TRet(DynamicObject &, Args...)>
获取成员函数的委托
Definition Reflection.h:1258
static auto AccessField(const Delegate< TField &(DynamicObject &)> &accessor, T &obj) -> typename std::enable_if<!std::is_base_of< DynamicObject, T >::value, TField & >::type
访问字段
Definition Reflection.h:1433
static auto InvokeMethod(const Delegate< TFunc > &method, T &obj, Args &&...args) -> typename std::enable_if<!std::is_base_of< DynamicObject, T >::value, decltype(method(std::declval< DynamicObject & >(), std::forward< Args >(args)...))>::type
调用成员函数
Definition Reflection.h:1399
static auto GetFieldAccessor(TField T::*field) -> Delegate< TField &(DynamicObject &)>
获取字段的访问器
Definition Reflection.h:1289
static auto GetPropertySetter(TProperty T::*prop) -> typename std::enable_if< _IsWritableProperty< TProperty >::value, Delegate< void(DynamicObject &, typename TProperty::TSetterParam)> >::type
获取属性的Setter委托
Definition Reflection.h:1341
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< _IsProperty< TProperty >::value &&!_IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:1324
static auto GetProperty(const Delegate< TValue(DynamicObject &)> &getter, T &obj) -> typename std::enable_if<!std::is_base_of< DynamicObject, T >::value, TValue >::type
获取属性值
Definition Reflection.h:1466
static FieldId GetFieldId(TField T::*field) noexcept
获取字段的唯一标识符
Definition Reflection.h:1230
static auto GetProperty(const Delegate< TValue(DynamicObject &)> &getter, T &obj) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, TValue >::type
获取属性值
Definition Reflection.h:1450
static auto AccessField(const Delegate< TField &(DynamicObject &)> &accessor, T &obj) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, TField & >::type
访问字段
Definition Reflection.h:1417
static auto SetProperty(const Delegate< void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value) -> typename std::enable_if<!std::is_base_of< DynamicObject, T >::value >::type
设置属性值
Definition Reflection.h:1501
static auto GetMethod(TRet(T::*method)(Args...) const) -> Delegate< TRet(DynamicObject &, Args...)>
获取常量成员函数的委托
Definition Reflection.h:1274
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< _IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:1305
static auto SetProperty(const Delegate< void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value >::type
设置属性值
Definition Reflection.h:1484
static auto InvokeMethod(const Delegate< TFunc > &method, T &obj, Args &&...args) -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, decltype(method(obj, std::forward< Args >(args)...))>::type
调用成员函数
Definition Reflection.h:1380
static auto GetPropertySetter(TProperty T::*prop) -> typename std::enable_if< _IsProperty< TProperty >::value &&!_IsWritableProperty< TProperty >::value, Delegate< void(DynamicObject &, typename TProperty::TSetterParam)> >::type
获取属性的Setter委托
Definition Reflection.h:1360
Reflection()=delete
静态类,不允许实例化
SimpleWindow框架的顶级命名空间,所有公共类型、控件、枚举和工具函数均定义于此。
Definition Alignment.h:4
_IsExplicitlyConvertable< TFrom, TTo > _IsStaticCastable
用于判断是否可以通过static_cast进行转换
Definition Internal.h:34
表示字段的唯一标识符
Definition Reflection.h:1167
std::wstring ToString() const
获取字段ID的字符串表示形式
Definition Reflection.h:1189
int CompareTo(FieldId other) const
比较字段ID
Definition Reflection.h:1198
uint32_t value
字段ID的数值
Definition Reflection.h:1171
FieldId()=default
默认构造函数
FieldId(uint32_t value)
构造指定值的字段ID
Definition Reflection.h:1181
判断类型是否可以使用dynamic_cast进行转换的辅助模板
Definition Internal.h:40
判断类型是否为属性的辅助模板
Definition Property.h:95
判断类型是否为可读属性的辅助模板
Definition Property.h:133
判断类型是否为可写属性的辅助模板
Definition Property.h:141