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
69 std::type_index GetType() const
70 {
71#if defined(SW_DISABLE_REFLECTION)
72 throw std::runtime_error("Reflection is disabled, cannot get type index.");
73#else
74 return typeid(*this);
75#endif
76 }
77
84 template <typename T>
85 auto IsType(T **pout = nullptr)
86 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, bool>::type
87 {
88#if defined(SW_DISABLE_REFLECTION)
89 throw std::runtime_error("Reflection is disabled, cannot check type.");
90#else
91 if (pout == nullptr) {
92 return dynamic_cast<T *>(this) != nullptr;
93 } else {
94 *pout = dynamic_cast<T *>(this);
95 return *pout != nullptr;
96 }
97#endif
98 }
99
106 template <typename T>
107 auto IsType(const T **pout = nullptr) const
108 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, bool>::type
109 {
110#if defined(SW_DISABLE_REFLECTION)
111 throw std::runtime_error("Reflection is disabled, cannot check type.");
112#else
113 if (pout == nullptr) {
114 return dynamic_cast<const T *>(this) != nullptr;
115 } else {
116 *pout = dynamic_cast<const T *>(this);
117 return *pout != nullptr;
118 }
119#endif
120 }
121
128 template <typename T>
130 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, T &>::type
131 {
132#if defined(SW_DISABLE_REFLECTION)
133 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
134#else
135 return dynamic_cast<T &>(*this);
136#endif
137 }
138
145 template <typename T>
147 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, const T &>::type
148 {
149#if defined(SW_DISABLE_REFLECTION)
150 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
151#else
152 return dynamic_cast<const T &>(*this);
153#endif
154 }
155
162 template <typename T>
164 -> typename std::enable_if<
165 std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type
166 {
167 return static_cast<T &>(*this);
168 }
169
177 template <typename T>
179 -> typename std::enable_if<
180 std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
181 {
182 return DynamicCast<T>();
183 }
184
191 template <typename T>
193 -> typename std::enable_if<
194 std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
195 {
196 return static_cast<const T &>(*this);
197 }
198
206 template <typename T>
208 -> typename std::enable_if<
209 std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
210 {
211 return DynamicCast<T>();
212 }
213
214 public:
221 template <typename T>
222 auto IsType(T **pout = nullptr)
223 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
224
231 template <typename T>
232 auto IsType(T **pout = nullptr)
233 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
234
241 template <typename T>
242 auto IsType(const T **pout = nullptr) const
243 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
244
253 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
254
263 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, T &>::type;
264
273 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, T &>::type;
274
283 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type;
284
293 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type;
294
303 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type;
304
313 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type;
314
323 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type;
324
333 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type;
334
335 private:
340 virtual std::type_index GetBoxedType() const noexcept
341 {
342 return typeid(void);
343 }
344
349 virtual bool IsBoxedPolymorphic() const noexcept
350 {
351 return false;
352 }
353
358 virtual void *GetBoxedRawPtr() noexcept
359 {
360 return nullptr;
361 }
362
367 virtual const void *GetBoxedRawPtr() const noexcept
368 {
369 return nullptr;
370 }
371 };
372
373 /*================================================================================*/
374
378 template <typename T>
379 class BoxedObject<T, typename std::enable_if<!std::is_base_of<DynamicObject, T>::value>::type> final
380 : public DynamicObject
381 {
385 struct _IsRefParam {
386 bool val;
387 };
388
392 template <typename U, typename = void>
393 union _InternalData {
397 U *refptr;
398
402 alignas(U) uint8_t objbuf[sizeof(U)];
403 };
404
409 template <typename U>
410 union _InternalData<U, typename std::enable_if<std::is_abstract<U>::value>::type> {
414 U *refptr;
415
420 uint8_t objbuf[1];
421 };
422
423 private:
427 bool _isRef;
428
432 _InternalData<T> _data;
433
434 private:
440 : _isRef(isRef.val), _data()
441 {
442 _isBoxedObject = true;
443 }
444
448 void Release() noexcept(std::is_nothrow_destructible<T>::value)
449 {
450 if (!_isRef) {
451 Unbox().~T();
452 }
453 }
454
455 public:
460 template <typename... Args>
463 {
464 new (_data.objbuf) T(std::forward<Args>(args)...);
465 }
466
470 virtual ~BoxedObject()
471 {
472 Release();
473 }
474
480 static BoxedObject<T> MakeRef(T *ptr) noexcept
481 {
483 result._data.refptr = ptr;
484 return result;
485 }
486
493 template <typename U>
494 static auto MakeRef(BoxedObject<U> &other) noexcept
495 -> typename std::enable_if<_IsStaticCastable<U, T>::value, BoxedObject<T>>::type
496 {
498 result._data.refptr = other.IsNullRef() ? nullptr : static_cast<T *>(&other.Unbox());
499 return result;
500 }
501
506 BoxedObject(const BoxedObject &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
507 : BoxedObject(_IsRefParam{other._isRef})
508 {
509 if (_isRef) {
510 _data.refptr = other._data.refptr;
511 } else {
512 new (_data.objbuf) T(other.Unbox());
513 }
514 }
515
520 BoxedObject(BoxedObject &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
521 : BoxedObject(_IsRefParam{other._isRef})
522 {
523 if (_isRef) {
524 _data.refptr = other._data.refptr;
525 other._data.refptr = nullptr;
526 } else {
527 new (_data.objbuf) T(std::move(other.Unbox()));
528 }
529 }
530
537 {
538 if (this == &other)
539 return *this;
540
541 if (_isRef) {
542 if (other._isRef) {
543 _data.refptr = other._data.refptr;
544 } else {
545 auto oldPtr = _data.refptr;
546 try {
547 new (_data.objbuf) T(other.Unbox());
548 _isRef = false;
549 } catch (...) {
550 _data.refptr = oldPtr;
551 throw;
552 }
553 }
554 } else {
555 if (other._isRef) {
556 Release();
557 _data.refptr = other._data.refptr;
558 _isRef = true;
559 } else {
560 Unbox() = other.Unbox();
561 }
562 }
563 return *this;
564 }
565
572 {
573 if (this == &other)
574 return *this;
575
576 if (_isRef) {
577 if (other._isRef) {
578 _data.refptr = other._data.refptr;
579 other._data.refptr = nullptr;
580 } else {
581 auto oldPtr = _data.refptr;
582 try {
583 new (_data.objbuf) T(std::move(other.Unbox()));
584 _isRef = false;
585 } catch (...) {
586 _data.refptr = oldPtr;
587 throw;
588 }
589 }
590 } else {
591 if (other._isRef) {
592 Release();
593 _data.refptr = other._data.refptr;
594 _isRef = true;
595 other._data.refptr = nullptr;
596 } else {
597 Unbox() = std::move(other.Unbox());
598 }
599 }
600 return *this;
601 }
602
608 {
609 return _isRef;
610 }
611
617 {
618 return _isRef && (_data.refptr == nullptr);
619 }
620
626 {
627 return !IsNullRef();
628 }
629
636 {
637 assert(HasValue());
638 return _isRef ? *_data.refptr : *reinterpret_cast<T *>(_data.objbuf);
639 }
640
647 {
648 assert(HasValue());
649 return _isRef ? *_data.refptr : *reinterpret_cast<const T *>(_data.objbuf);
650 }
651
652 private:
657 virtual std::type_index GetBoxedType() const noexcept override
658 {
659 return typeid(T);
660 }
661
666 virtual bool IsBoxedPolymorphic() const noexcept override
667 {
668 return std::is_polymorphic<T>::value;
669 }
670
675 virtual void *GetBoxedRawPtr() noexcept override
676 {
677 return _isRef ? static_cast<void *>(_data.refptr) : static_cast<void *>(_data.objbuf);
678 }
679
684 virtual const void *GetBoxedRawPtr() const noexcept override
685 {
686 return _isRef ? static_cast<const void *>(_data.refptr) : static_cast<const void *>(_data.objbuf);
687 }
688 };
689
690 /*================================================================================*/
691
698 template <typename T>
699 auto DynamicObject::IsType(T **pout)
700 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
701 {
702#if defined(SW_DISABLE_REFLECTION)
703 throw std::runtime_error("Reflection is disabled, cannot check type.");
704#else
705 if (!_isBoxedObject) {
706 if (pout == nullptr) {
707 return dynamic_cast<T *>(this) != nullptr;
708 } else {
709 *pout = dynamic_cast<T *>(this);
710 return *pout != nullptr;
711 }
712 } else {
713 if (GetBoxedType() == typeid(T)) {
714 if (pout == nullptr) {
715 return GetBoxedRawPtr() != nullptr;
716 } else {
717 *pout = static_cast<T *>(GetBoxedRawPtr());
718 return *pout != nullptr;
719 }
720 } else {
721 if (pout != nullptr) {
722 *pout = nullptr;
723 }
724 return false;
725 }
726 }
727#endif
728 }
729
736 template <typename T>
737 auto DynamicObject::IsType(T **pout)
738 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
739 {
740#if defined(SW_DISABLE_REFLECTION)
741 throw std::runtime_error("Reflection is disabled, cannot check type.");
742#else
743 if (!_isBoxedObject) {
744 if (pout != nullptr) {
745 *pout = nullptr;
746 }
747 return false;
748 } else {
749 if (GetBoxedType() == typeid(T)) {
750 if (pout == nullptr) {
751 return GetBoxedRawPtr() != nullptr;
752 } else {
753 *pout = static_cast<T *>(GetBoxedRawPtr());
754 return *pout != nullptr;
755 }
756 } else {
757 if (pout != nullptr) {
758 *pout = nullptr;
759 }
760 return false;
761 }
762 }
763#endif
764 }
765
772 template <typename T>
773 auto DynamicObject::IsType(const T **pout) const
774 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
775 {
776#if defined(SW_DISABLE_REFLECTION)
777 throw std::runtime_error("Reflection is disabled, cannot check type.");
778#else
779 if (!_isBoxedObject) {
780 if (pout == nullptr) {
781 return dynamic_cast<const T *>(this) != nullptr;
782 } else {
783 *pout = dynamic_cast<const T *>(this);
784 return *pout != nullptr;
785 }
786 } else {
787 if (GetBoxedType() == typeid(T)) {
788 if (pout == nullptr) {
789 return GetBoxedRawPtr() != nullptr;
790 } else {
791 *pout = static_cast<const T *>(GetBoxedRawPtr());
792 return *pout != nullptr;
793 }
794 } else {
795 if (pout != nullptr) {
796 *pout = nullptr;
797 }
798 return false;
799 }
800 }
801#endif
802 }
803
810 template <typename T>
811 auto DynamicObject::IsType(const T **pout) const
812 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
813 {
814#if defined(SW_DISABLE_REFLECTION)
815 throw std::runtime_error("Reflection is disabled, cannot check type.");
816#else
817 if (!_isBoxedObject) {
818 if (pout != nullptr) {
819 *pout = nullptr;
820 }
821 return false;
822 } else {
823 if (GetBoxedType() == typeid(T)) {
824 if (pout == nullptr) {
825 return GetBoxedRawPtr() != nullptr;
826 } else {
827 *pout = static_cast<const T *>(GetBoxedRawPtr());
828 return *pout != nullptr;
829 }
830 } else {
831 if (pout != nullptr) {
832 *pout = nullptr;
833 }
834 return false;
835 }
836 }
837#endif
838 }
839
846 template <typename T>
848 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, T &>::type
849 {
850#if defined(SW_DISABLE_REFLECTION)
851 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
852#else
853 if (!_isBoxedObject) {
854 return dynamic_cast<T &>(*this);
855 } else {
856 void *rawPtr = GetBoxedRawPtr();
857 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
858 throw std::bad_cast();
859 } else {
860 return *static_cast<T *>(rawPtr);
861 }
862 }
863#endif
864 }
865
872 template <typename T>
874 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, T &>::type
875 {
876#if defined(SW_DISABLE_REFLECTION)
877 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
878#else
879 if (!_isBoxedObject) {
880 throw std::bad_cast();
881 } else {
882 void *rawPtr = GetBoxedRawPtr();
883 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
884 throw std::bad_cast();
885 } else {
886 return *static_cast<T *>(rawPtr);
887 }
888 }
889#endif
890 }
891
898 template <typename T>
899 auto DynamicObject::DynamicCast() const
900 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type
901 {
902#if defined(SW_DISABLE_REFLECTION)
903 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
904#else
905 if (!_isBoxedObject) {
906 return dynamic_cast<const T &>(*this);
907 } else {
908 const void *rawPtr = GetBoxedRawPtr();
909 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
910 throw std::bad_cast();
911 } else {
912 return *static_cast<const T *>(rawPtr);
913 }
914 }
915#endif
916 }
917
924 template <typename T>
925 auto DynamicObject::DynamicCast() const
926 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type
927 {
928#if defined(SW_DISABLE_REFLECTION)
929 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
930#else
931 if (!_isBoxedObject) {
932 throw std::bad_cast();
933 } else {
934 const void *rawPtr = GetBoxedRawPtr();
935 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
936 throw std::bad_cast();
937 } else {
938 return *static_cast<const T *>(rawPtr);
939 }
940 }
941#endif
942 }
943
950 template <typename T>
952 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type
953 {
954 if (!_isBoxedObject) {
955 return static_cast<T &>(*this);
956 } else {
957 return static_cast<BoxedObject<T> &>(*this).Unbox();
958 }
959 }
960
968 template <typename T>
970 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
971 {
972 if (!_isBoxedObject) {
973 return DynamicCast<T>();
974 } else {
975 return static_cast<BoxedObject<T> &>(*this).Unbox();
976 }
977 }
978
985 template <typename T>
986 auto DynamicObject::UnsafeCast() const
987 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
988 {
989 if (!_isBoxedObject) {
990 return static_cast<const T &>(*this);
991 } else {
992 return static_cast<const BoxedObject<T> &>(*this).Unbox();
993 }
994 }
995
1003 template <typename T>
1004 auto DynamicObject::UnsafeCast() const
1005 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
1006 {
1007 if (!_isBoxedObject) {
1008 return DynamicCast<T>();
1009 } else {
1010 return static_cast<const BoxedObject<T> &>(*this).Unbox();
1011 }
1012 }
1013
1014 /*================================================================================*/
1015
1019 struct FieldId : public IToString<FieldId>,
1020 public IComparable<FieldId, FieldId> {
1025
1029 FieldId() = default;
1030
1035 : value(value)
1036 {
1037 }
1038
1042 std::wstring ToString() const
1043 {
1044 return std::to_wstring(value);
1045 }
1046
1052 {
1053 if (value == other.value) {
1054 return 0;
1055 } else {
1056 return value < other.value ? -1 : 1;
1057 }
1058 }
1059 };
1060
1061 /*================================================================================*/
1062
1067 {
1068 public:
1072 Reflection() = delete;
1073
1074 public:
1082 template <typename T, typename TField>
1084 {
1085 auto pfunc = &Reflection::GetFieldId<T, TField>;
1086
1087 uint8_t buffer[sizeof(pfunc) + sizeof(field)];
1088 memcpy(buffer, &pfunc, sizeof(pfunc));
1089 memcpy(buffer + sizeof(pfunc), &field, sizeof(field));
1090
1091 uint32_t prime = 16777619u;
1092 uint32_t hash = 2166136261u;
1093
1094 for (size_t i = 0; i < sizeof(buffer); ++i) {
1095 hash ^= static_cast<uint32_t>(buffer[i]);
1096 hash *= prime;
1097 }
1098
1099 return FieldId{hash};
1100 }
1101
1110 template <typename T, typename TRet, typename... Args>
1111 static auto GetMethod(TRet (T::*method)(Args...)) -> Delegate<TRet(DynamicObject &, Args...)>
1112 {
1113 return [method](DynamicObject &obj, Args... args) -> TRet {
1114 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
1115 };
1116 }
1117
1126 template <typename T, typename TRet, typename... Args>
1127 static auto GetMethod(TRet (T::*method)(Args...) const) -> Delegate<TRet(DynamicObject &, Args...)>
1128 {
1129 return [method](DynamicObject &obj, Args... args) -> TRet {
1130 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
1131 };
1132 }
1133
1141 template <typename T, typename TField>
1143 {
1144 return [field](DynamicObject &obj) -> TField & {
1145 return obj.UnsafeCast<T>().*field;
1146 };
1147 }
1148
1157 template <typename T, typename TProperty>
1159 -> typename std::enable_if<
1161 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
1162 {
1163 return [prop](DynamicObject &obj) -> typename TProperty::TValue {
1164 return (obj.UnsafeCast<T>().*prop).Get();
1165 };
1166 }
1167
1176 template <typename T, typename TProperty>
1178 -> typename std::enable_if<
1180 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
1181 {
1182 return nullptr;
1183 }
1184
1193 template <typename T, typename TProperty>
1195 -> typename std::enable_if<
1197 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
1198 {
1199 return [prop](DynamicObject &obj, typename TProperty::TSetterParam value) {
1200 (obj.UnsafeCast<T>().*prop).Set(std::forward<typename TProperty::TSetterParam>(value));
1201 };
1202 }
1203
1212 template <typename T, typename TProperty>
1214 -> typename std::enable_if<
1216 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
1217 {
1218 return nullptr;
1219 }
1220
1221 public:
1232 template <typename T, typename TFunc, typename... Args>
1233 static auto InvokeMethod(const Delegate<TFunc> &method, T &obj, Args &&...args)
1234 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value,
1235 decltype(method(obj, std::forward<Args>(args)...))>::type
1236 {
1237 assert(method != nullptr);
1238 return method(obj, std::forward<Args>(args)...);
1239 }
1240
1251 template <typename T, typename TFunc, typename... Args>
1252 static auto InvokeMethod(const Delegate<TFunc> &method, T &obj, Args &&...args)
1253 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value,
1254 decltype(method(std::declval<DynamicObject &>(), std::forward<Args>(args)...))>::type
1255 {
1256 assert(method != nullptr);
1257 auto boxed = BoxedObject<T>::MakeRef(&obj);
1258 return method(boxed, std::forward<Args>(args)...);
1259 }
1260
1269 template <typename T, typename TField>
1270 static auto AccessField(const Delegate<TField &(DynamicObject &)> &accessor, T &obj)
1271 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, TField &>::type
1272 {
1273 assert(accessor != nullptr);
1274 return accessor(obj);
1275 }
1276
1285 template <typename T, typename TField>
1286 static auto AccessField(const Delegate<TField &(DynamicObject &)> &accessor, T &obj)
1287 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value, TField &>::type
1288 {
1289 assert(accessor != nullptr);
1290 auto boxed = BoxedObject<T>::MakeRef(&obj);
1291 return accessor(boxed);
1292 }
1293
1302 template <typename T, typename TValue>
1303 static auto GetProperty(const Delegate<TValue(DynamicObject &)> &getter, T &obj)
1304 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, TValue>::type
1305 {
1306 assert(getter != nullptr);
1307 return getter(obj);
1308 }
1309
1318 template <typename T, typename TValue>
1319 static auto GetProperty(const Delegate<TValue(DynamicObject &)> &getter, T &obj)
1320 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value, TValue>::type
1321 {
1322 assert(getter != nullptr);
1323 auto boxed = BoxedObject<T>::MakeRef(&obj);
1324 return getter(boxed);
1325 }
1326
1336 template <typename T, typename TParam, typename TValue>
1337 static auto SetProperty(const Delegate<void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value)
1338 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value>::type
1339 {
1340 assert(setter != nullptr);
1341 setter(obj, std::forward<TValue>(value));
1342 }
1343
1353 template <typename T, typename TParam, typename TValue>
1354 static auto SetProperty(const Delegate<void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value)
1355 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value>::type
1356 {
1357 assert(setter != nullptr);
1358 auto boxed = BoxedObject<T>::MakeRef(&obj);
1359 setter(boxed, std::forward<TValue>(value));
1360 }
1361 };
1362}
1363
1364// 为sw::FieldId特化std::hash
1365template <>
1366struct std::hash<sw::FieldId> //
1367{
1368 size_t operator()(sw::FieldId fieldId) const noexcept
1369 {
1370 return static_cast<size_t>(fieldId.value);
1371 }
1372};
BoxedObject(const BoxedObject &other) noexcept(std::is_nothrow_copy_constructible< T >::value)
拷贝构造函数
Definition Reflection.h:506
static auto MakeRef(BoxedObject< U > &other) noexcept -> typename std::enable_if< _IsStaticCastable< U, T >::value, BoxedObject< T > >::type
创建引用类型的装箱对象
Definition Reflection.h:494
BoxedObject(BoxedObject &&other) noexcept(std::is_nothrow_move_constructible< T >::value)
移动构造函数
Definition Reflection.h:520
T & Unbox() noexcept
获取装箱对象中的值
Definition Reflection.h:635
static BoxedObject< T > MakeRef(T *ptr) noexcept
创建引用类型的装箱对象
Definition Reflection.h:480
BoxedObject(Args &&...args)
构造值类型的装箱对象
Definition Reflection.h:461
bool HasValue() const noexcept
判断当前装箱对象是否包含有效值
Definition Reflection.h:625
bool IsRef() const noexcept
判断当前装箱对象是否为引用类型
Definition Reflection.h:607
BoxedObject & operator=(BoxedObject &&other)
移动赋值运算符
Definition Reflection.h:571
bool IsNullRef() const noexcept
判断当前装箱对象是否为空引用
Definition Reflection.h:616
const T & Unbox() const noexcept
获取装箱对象中的值
Definition Reflection.h:646
BoxedObject & operator=(const BoxedObject &other)
拷贝赋值运算符
Definition Reflection.h:536
装箱对象模板类声明
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:163
auto IsType(const T **pout=nullptr) const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, bool >::type
判断对象是否为指定类型
Definition Reflection.h:107
auto UnsafeCast() -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&!_IsStaticCastable< DynamicObject *, T * >::value, T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:178
auto UnsafeCast() const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&_IsStaticCastable< DynamicObject *, T * >::value, const T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:192
auto UnsafeCast() const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&!_IsStaticCastable< DynamicObject *, T * >::value, const T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:207
virtual ~DynamicObject()
析构函数
Definition Reflection.h:52
auto DynamicCast() -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, T & >::type
将对象动态转换为指定类型的引用
Definition Reflection.h:129
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:146
std::type_index GetType() const
获取对象的类型信息
Definition Reflection.h:69
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:85
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:1067
static auto GetMethod(TRet(T::*method)(Args...)) -> Delegate< TRet(DynamicObject &, Args...)>
获取成员函数的委托
Definition Reflection.h:1111
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:1286
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:1252
static auto GetFieldAccessor(TField T::*field) -> Delegate< TField &(DynamicObject &)>
获取字段的访问器
Definition Reflection.h:1142
static auto GetPropertySetter(TProperty T::*prop) -> typename std::enable_if< _IsWritableProperty< TProperty >::value, Delegate< void(DynamicObject &, typename TProperty::TSetterParam)> >::type
获取属性的Setter委托
Definition Reflection.h:1194
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:1177
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:1319
static FieldId GetFieldId(TField T::*field) noexcept
获取字段的唯一标识符
Definition Reflection.h:1083
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:1303
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:1270
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:1354
static auto GetMethod(TRet(T::*method)(Args...) const) -> Delegate< TRet(DynamicObject &, Args...)>
获取常量成员函数的委托
Definition Reflection.h:1127
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< _IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:1158
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:1337
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:1233
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:1213
Reflection()=delete
静态类,不允许实例化
SimpleWindow框架的顶级命名空间,所有公共类型、控件、枚举和工具函数均定义于此。
Definition Alignment.h:4
_IsExplicitlyConvertable< TFrom, TTo > _IsStaticCastable
用于判断是否可以通过static_cast进行转换
Definition Internal.h:34
表示字段的唯一标识符
Definition Reflection.h:1020
std::wstring ToString() const
获取字段ID的字符串表示形式
Definition Reflection.h:1042
int CompareTo(FieldId other) const
比较字段ID
Definition Reflection.h:1051
uint32_t value
字段ID的数值
Definition Reflection.h:1024
FieldId()=default
默认构造函数
FieldId(uint32_t value)
构造指定值的字段ID
Definition Reflection.h:1034
判断类型是否可以使用dynamic_cast进行转换的辅助模板
Definition Internal.h:40
判断类型是否为属性的辅助模板
Definition Property.h:95
判断类型是否为可读属性的辅助模板
Definition Property.h:133
判断类型是否为可写属性的辅助模板
Definition Property.h:141