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 (IsBoxedObject() && other.IsBoxedObject())
73 return GetBoxedRawPtr() == other.GetBoxedRawPtr();
74 return this == &other;
75 }
76
81 std::type_index GetType() const
82 {
83#if defined(SW_DISABLE_REFLECTION)
84 throw std::runtime_error("Reflection is disabled, cannot get type index.");
85#else
86 return typeid(*this);
87#endif
88 }
89
96 template <typename T>
97 auto IsType(T **pout = nullptr)
98 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, bool>::type
99 {
100#if defined(SW_DISABLE_REFLECTION)
101 throw std::runtime_error("Reflection is disabled, cannot check type.");
102#else
103 if (pout == nullptr) {
104 return dynamic_cast<T *>(this) != nullptr;
105 } else {
106 *pout = dynamic_cast<T *>(this);
107 return *pout != nullptr;
108 }
109#endif
110 }
111
118 template <typename T>
119 auto IsType(const T **pout = nullptr) const
120 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, bool>::type
121 {
122#if defined(SW_DISABLE_REFLECTION)
123 throw std::runtime_error("Reflection is disabled, cannot check type.");
124#else
125 if (pout == nullptr) {
126 return dynamic_cast<const T *>(this) != nullptr;
127 } else {
128 *pout = dynamic_cast<const T *>(this);
129 return *pout != nullptr;
130 }
131#endif
132 }
133
140 template <typename T>
142 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, T &>::type
143 {
144#if defined(SW_DISABLE_REFLECTION)
145 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
146#else
147 return dynamic_cast<T &>(*this);
148#endif
149 }
150
157 template <typename T>
159 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, const T &>::type
160 {
161#if defined(SW_DISABLE_REFLECTION)
162 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
163#else
164 return dynamic_cast<const T &>(*this);
165#endif
166 }
167
174 template <typename T>
176 -> typename std::enable_if<
177 std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type
178 {
179 return static_cast<T &>(*this);
180 }
181
189 template <typename T>
191 -> typename std::enable_if<
192 std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
193 {
194 return DynamicCast<T>();
195 }
196
203 template <typename T>
205 -> typename std::enable_if<
206 std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
207 {
208 return static_cast<const T &>(*this);
209 }
210
218 template <typename T>
220 -> typename std::enable_if<
221 std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
222 {
223 return DynamicCast<T>();
224 }
225
226 public:
233 template <typename T>
234 auto IsType(T **pout = nullptr)
235 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
236
243 template <typename T>
244 auto IsType(T **pout = nullptr)
245 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
246
253 template <typename T>
254 auto IsType(const T **pout = nullptr) const
255 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
256
265 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
266
275 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, T &>::type;
276
285 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, T &>::type;
286
295 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type;
296
305 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type;
306
315 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type;
316
325 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type;
326
335 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type;
336
345 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type;
346
347 private:
352 virtual std::type_index GetBoxedType() const noexcept
353 {
354 return typeid(void);
355 }
356
361 virtual bool IsBoxedPolymorphic() const noexcept
362 {
363 return false;
364 }
365
370 virtual void *GetBoxedRawPtr() noexcept
371 {
372 return nullptr;
373 }
374
379 virtual const void *GetBoxedRawPtr() const noexcept
380 {
381 return nullptr;
382 }
383 };
384
385 /*================================================================================*/
386
390 template <typename T>
391 class BoxedObject<T, typename std::enable_if<!std::is_base_of<DynamicObject, T>::value>::type> final
392 : public DynamicObject
393 {
397 struct _IsRefParam {
398 bool val;
399 };
400
404 template <typename U, typename = void>
405 union _InternalData {
409 U *refptr;
410
414 alignas(U) uint8_t objbuf[sizeof(U)];
415 };
416
421 template <typename U>
422 union _InternalData<U, typename std::enable_if<std::is_abstract<U>::value>::type> {
426 U *refptr;
427
432 uint8_t objbuf[1];
433 };
434
435 private:
439 bool _isRef;
440
444 _InternalData<T> _data;
445
446 private:
452 : _isRef(isRef.val), _data()
453 {
454 _isBoxedObject = true;
455 }
456
460 void Release() noexcept(std::is_nothrow_destructible<T>::value)
461 {
462 if (!_isRef) {
463 Unbox().~T();
464 }
465 }
466
467 public:
472 template <typename... Args>
475 {
476 new (_data.objbuf) T(std::forward<Args>(args)...);
477 }
478
482 virtual ~BoxedObject()
483 {
484 Release();
485 }
486
492 static BoxedObject<T> MakeRef(T *ptr) noexcept
493 {
495 result._data.refptr = ptr;
496 return result;
497 }
498
505 template <typename U>
506 static auto MakeRef(BoxedObject<U> &other) noexcept
507 -> typename std::enable_if<_IsStaticCastable<U, T>::value, BoxedObject<T>>::type
508 {
510 result._data.refptr = other.IsNullRef() ? nullptr : static_cast<T *>(&other.Unbox());
511 return result;
512 }
513
518 BoxedObject(const BoxedObject &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
519 : BoxedObject(_IsRefParam{other._isRef})
520 {
521 if (_isRef) {
522 _data.refptr = other._data.refptr;
523 } else {
524 new (_data.objbuf) T(other.Unbox());
525 }
526 }
527
532 BoxedObject(BoxedObject &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
533 : BoxedObject(_IsRefParam{other._isRef})
534 {
535 if (_isRef) {
536 _data.refptr = other._data.refptr;
537 other._data.refptr = nullptr;
538 } else {
539 new (_data.objbuf) T(std::move(other.Unbox()));
540 }
541 }
542
549 {
550 if (this == &other)
551 return *this;
552
553 if (_isRef) {
554 if (other._isRef) {
555 _data.refptr = other._data.refptr;
556 } else {
557 auto oldPtr = _data.refptr;
558 try {
559 new (_data.objbuf) T(other.Unbox());
560 _isRef = false;
561 } catch (...) {
562 _data.refptr = oldPtr;
563 throw;
564 }
565 }
566 } else {
567 if (other._isRef) {
568 Release();
569 _data.refptr = other._data.refptr;
570 _isRef = true;
571 } else {
572 Unbox() = other.Unbox();
573 }
574 }
575 return *this;
576 }
577
584 {
585 if (this == &other)
586 return *this;
587
588 if (_isRef) {
589 if (other._isRef) {
590 _data.refptr = other._data.refptr;
591 other._data.refptr = nullptr;
592 } else {
593 auto oldPtr = _data.refptr;
594 try {
595 new (_data.objbuf) T(std::move(other.Unbox()));
596 _isRef = false;
597 } catch (...) {
598 _data.refptr = oldPtr;
599 throw;
600 }
601 }
602 } else {
603 if (other._isRef) {
604 Release();
605 _data.refptr = other._data.refptr;
606 _isRef = true;
607 other._data.refptr = nullptr;
608 } else {
609 Unbox() = std::move(other.Unbox());
610 }
611 }
612 return *this;
613 }
614
620 {
621 return _isRef;
622 }
623
629 {
630 return _isRef && (_data.refptr == nullptr);
631 }
632
638 {
639 return !IsNullRef();
640 }
641
648 {
649 assert(HasValue());
650 return _isRef ? *_data.refptr : *reinterpret_cast<T *>(_data.objbuf);
651 }
652
659 {
660 assert(HasValue());
661 return _isRef ? *_data.refptr : *reinterpret_cast<const T *>(_data.objbuf);
662 }
663
664 private:
669 virtual std::type_index GetBoxedType() const noexcept override
670 {
671 return typeid(T);
672 }
673
678 virtual bool IsBoxedPolymorphic() const noexcept override
679 {
680 return std::is_polymorphic<T>::value;
681 }
682
687 virtual void *GetBoxedRawPtr() noexcept override
688 {
689 return _isRef ? static_cast<void *>(_data.refptr) : static_cast<void *>(_data.objbuf);
690 }
691
696 virtual const void *GetBoxedRawPtr() const noexcept override
697 {
698 return _isRef ? static_cast<const void *>(_data.refptr) : static_cast<const void *>(_data.objbuf);
699 }
700 };
701
702 /*================================================================================*/
703
710 template <typename T>
711 auto DynamicObject::IsType(T **pout)
712 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
713 {
714#if defined(SW_DISABLE_REFLECTION)
715 throw std::runtime_error("Reflection is disabled, cannot check type.");
716#else
717 if (!_isBoxedObject) {
718 if (pout == nullptr) {
719 return dynamic_cast<T *>(this) != nullptr;
720 } else {
721 *pout = dynamic_cast<T *>(this);
722 return *pout != nullptr;
723 }
724 } else {
725 if (GetBoxedType() == typeid(T)) {
726 if (pout == nullptr) {
727 return GetBoxedRawPtr() != nullptr;
728 } else {
729 *pout = static_cast<T *>(GetBoxedRawPtr());
730 return *pout != nullptr;
731 }
732 } else {
733 if (pout != nullptr) {
734 *pout = nullptr;
735 }
736 return false;
737 }
738 }
739#endif
740 }
741
748 template <typename T>
749 auto DynamicObject::IsType(T **pout)
750 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
751 {
752#if defined(SW_DISABLE_REFLECTION)
753 throw std::runtime_error("Reflection is disabled, cannot check type.");
754#else
755 if (!_isBoxedObject) {
756 if (pout != nullptr) {
757 *pout = nullptr;
758 }
759 return false;
760 } else {
761 if (GetBoxedType() == typeid(T)) {
762 if (pout == nullptr) {
763 return GetBoxedRawPtr() != nullptr;
764 } else {
765 *pout = static_cast<T *>(GetBoxedRawPtr());
766 return *pout != nullptr;
767 }
768 } else {
769 if (pout != nullptr) {
770 *pout = nullptr;
771 }
772 return false;
773 }
774 }
775#endif
776 }
777
784 template <typename T>
785 auto DynamicObject::IsType(const T **pout) const
786 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
787 {
788#if defined(SW_DISABLE_REFLECTION)
789 throw std::runtime_error("Reflection is disabled, cannot check type.");
790#else
791 if (!_isBoxedObject) {
792 if (pout == nullptr) {
793 return dynamic_cast<const T *>(this) != nullptr;
794 } else {
795 *pout = dynamic_cast<const T *>(this);
796 return *pout != nullptr;
797 }
798 } else {
799 if (GetBoxedType() == typeid(T)) {
800 if (pout == nullptr) {
801 return GetBoxedRawPtr() != nullptr;
802 } else {
803 *pout = static_cast<const T *>(GetBoxedRawPtr());
804 return *pout != nullptr;
805 }
806 } else {
807 if (pout != nullptr) {
808 *pout = nullptr;
809 }
810 return false;
811 }
812 }
813#endif
814 }
815
822 template <typename T>
823 auto DynamicObject::IsType(const T **pout) const
824 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
825 {
826#if defined(SW_DISABLE_REFLECTION)
827 throw std::runtime_error("Reflection is disabled, cannot check type.");
828#else
829 if (!_isBoxedObject) {
830 if (pout != nullptr) {
831 *pout = nullptr;
832 }
833 return false;
834 } else {
835 if (GetBoxedType() == typeid(T)) {
836 if (pout == nullptr) {
837 return GetBoxedRawPtr() != nullptr;
838 } else {
839 *pout = static_cast<const T *>(GetBoxedRawPtr());
840 return *pout != nullptr;
841 }
842 } else {
843 if (pout != nullptr) {
844 *pout = nullptr;
845 }
846 return false;
847 }
848 }
849#endif
850 }
851
858 template <typename T>
860 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, T &>::type
861 {
862#if defined(SW_DISABLE_REFLECTION)
863 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
864#else
865 if (!_isBoxedObject) {
866 return dynamic_cast<T &>(*this);
867 } else {
868 void *rawPtr = GetBoxedRawPtr();
869 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
870 throw std::bad_cast();
871 } else {
872 return *static_cast<T *>(rawPtr);
873 }
874 }
875#endif
876 }
877
884 template <typename T>
886 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, T &>::type
887 {
888#if defined(SW_DISABLE_REFLECTION)
889 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
890#else
891 if (!_isBoxedObject) {
892 throw std::bad_cast();
893 } else {
894 void *rawPtr = GetBoxedRawPtr();
895 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
896 throw std::bad_cast();
897 } else {
898 return *static_cast<T *>(rawPtr);
899 }
900 }
901#endif
902 }
903
910 template <typename T>
911 auto DynamicObject::DynamicCast() const
912 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type
913 {
914#if defined(SW_DISABLE_REFLECTION)
915 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
916#else
917 if (!_isBoxedObject) {
918 return dynamic_cast<const T &>(*this);
919 } else {
920 const void *rawPtr = GetBoxedRawPtr();
921 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
922 throw std::bad_cast();
923 } else {
924 return *static_cast<const T *>(rawPtr);
925 }
926 }
927#endif
928 }
929
936 template <typename T>
937 auto DynamicObject::DynamicCast() const
938 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type
939 {
940#if defined(SW_DISABLE_REFLECTION)
941 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
942#else
943 if (!_isBoxedObject) {
944 throw std::bad_cast();
945 } else {
946 const void *rawPtr = GetBoxedRawPtr();
947 if (rawPtr == nullptr || GetBoxedType() != typeid(T)) {
948 throw std::bad_cast();
949 } else {
950 return *static_cast<const T *>(rawPtr);
951 }
952 }
953#endif
954 }
955
962 template <typename T>
964 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type
965 {
966 if (!_isBoxedObject) {
967 return static_cast<T &>(*this);
968 } else {
969 return static_cast<BoxedObject<T> &>(*this).Unbox();
970 }
971 }
972
980 template <typename T>
982 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
983 {
984 if (!_isBoxedObject) {
985 return DynamicCast<T>();
986 } else {
987 return static_cast<BoxedObject<T> &>(*this).Unbox();
988 }
989 }
990
997 template <typename T>
998 auto DynamicObject::UnsafeCast() const
999 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
1000 {
1001 if (!_isBoxedObject) {
1002 return static_cast<const T &>(*this);
1003 } else {
1004 return static_cast<const BoxedObject<T> &>(*this).Unbox();
1005 }
1006 }
1007
1015 template <typename T>
1016 auto DynamicObject::UnsafeCast() const
1017 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
1018 {
1019 if (!_isBoxedObject) {
1020 return DynamicCast<T>();
1021 } else {
1022 return static_cast<const BoxedObject<T> &>(*this).Unbox();
1023 }
1024 }
1025
1026 /*================================================================================*/
1027
1031 struct FieldId : public IToString<FieldId>,
1032 public IComparable<FieldId, FieldId> {
1037
1041 FieldId() = default;
1042
1047 : value(value)
1048 {
1049 }
1050
1054 std::wstring ToString() const
1055 {
1056 return std::to_wstring(value);
1057 }
1058
1064 {
1065 if (value == other.value) {
1066 return 0;
1067 } else {
1068 return value < other.value ? -1 : 1;
1069 }
1070 }
1071 };
1072
1073 /*================================================================================*/
1074
1079 {
1080 public:
1084 Reflection() = delete;
1085
1086 public:
1094 template <typename T, typename TField>
1096 {
1097 auto pfunc = &Reflection::GetFieldId<T, TField>;
1098
1099 uint8_t buffer[sizeof(pfunc) + sizeof(field)];
1100 memcpy(buffer, &pfunc, sizeof(pfunc));
1101 memcpy(buffer + sizeof(pfunc), &field, sizeof(field));
1102
1103 uint32_t prime = 16777619u;
1104 uint32_t hash = 2166136261u;
1105
1106 for (size_t i = 0; i < sizeof(buffer); ++i) {
1107 hash ^= static_cast<uint32_t>(buffer[i]);
1108 hash *= prime;
1109 }
1110
1111 return FieldId{hash};
1112 }
1113
1122 template <typename T, typename TRet, typename... Args>
1123 static auto GetMethod(TRet (T::*method)(Args...)) -> Delegate<TRet(DynamicObject &, Args...)>
1124 {
1125 return [method](DynamicObject &obj, Args... args) -> TRet {
1126 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
1127 };
1128 }
1129
1138 template <typename T, typename TRet, typename... Args>
1139 static auto GetMethod(TRet (T::*method)(Args...) const) -> Delegate<TRet(DynamicObject &, Args...)>
1140 {
1141 return [method](DynamicObject &obj, Args... args) -> TRet {
1142 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
1143 };
1144 }
1145
1153 template <typename T, typename TField>
1155 {
1156 return [field](DynamicObject &obj) -> TField & {
1157 return obj.UnsafeCast<T>().*field;
1158 };
1159 }
1160
1169 template <typename T, typename TProperty>
1171 -> typename std::enable_if<
1173 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
1174 {
1175 return [prop](DynamicObject &obj) -> typename TProperty::TValue {
1176 return (obj.UnsafeCast<T>().*prop).Get();
1177 };
1178 }
1179
1188 template <typename T, typename TProperty>
1190 -> typename std::enable_if<
1192 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
1193 {
1194 return nullptr;
1195 }
1196
1205 template <typename T, typename TProperty>
1207 -> typename std::enable_if<
1209 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
1210 {
1211 return [prop](DynamicObject &obj, typename TProperty::TSetterParam value) {
1212 (obj.UnsafeCast<T>().*prop).Set(std::forward<typename TProperty::TSetterParam>(value));
1213 };
1214 }
1215
1224 template <typename T, typename TProperty>
1226 -> typename std::enable_if<
1228 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
1229 {
1230 return nullptr;
1231 }
1232
1233 public:
1244 template <typename T, typename TFunc, typename... Args>
1245 static auto InvokeMethod(const Delegate<TFunc> &method, T &obj, Args &&...args)
1246 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value,
1247 decltype(method(obj, std::forward<Args>(args)...))>::type
1248 {
1249 assert(method != nullptr);
1250 return method(obj, std::forward<Args>(args)...);
1251 }
1252
1263 template <typename T, typename TFunc, typename... Args>
1264 static auto InvokeMethod(const Delegate<TFunc> &method, T &obj, Args &&...args)
1265 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value,
1266 decltype(method(std::declval<DynamicObject &>(), std::forward<Args>(args)...))>::type
1267 {
1268 assert(method != nullptr);
1269 auto boxed = BoxedObject<T>::MakeRef(&obj);
1270 return method(boxed, std::forward<Args>(args)...);
1271 }
1272
1281 template <typename T, typename TField>
1282 static auto AccessField(const Delegate<TField &(DynamicObject &)> &accessor, T &obj)
1283 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, TField &>::type
1284 {
1285 assert(accessor != nullptr);
1286 return accessor(obj);
1287 }
1288
1297 template <typename T, typename TField>
1298 static auto AccessField(const Delegate<TField &(DynamicObject &)> &accessor, T &obj)
1299 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value, TField &>::type
1300 {
1301 assert(accessor != nullptr);
1302 auto boxed = BoxedObject<T>::MakeRef(&obj);
1303 return accessor(boxed);
1304 }
1305
1314 template <typename T, typename TValue>
1315 static auto GetProperty(const Delegate<TValue(DynamicObject &)> &getter, T &obj)
1316 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, TValue>::type
1317 {
1318 assert(getter != nullptr);
1319 return getter(obj);
1320 }
1321
1330 template <typename T, typename TValue>
1331 static auto GetProperty(const Delegate<TValue(DynamicObject &)> &getter, T &obj)
1332 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value, TValue>::type
1333 {
1334 assert(getter != nullptr);
1335 auto boxed = BoxedObject<T>::MakeRef(&obj);
1336 return getter(boxed);
1337 }
1338
1348 template <typename T, typename TParam, typename TValue>
1349 static auto SetProperty(const Delegate<void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value)
1350 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value>::type
1351 {
1352 assert(setter != nullptr);
1353 setter(obj, std::forward<TValue>(value));
1354 }
1355
1365 template <typename T, typename TParam, typename TValue>
1366 static auto SetProperty(const Delegate<void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value)
1367 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value>::type
1368 {
1369 assert(setter != nullptr);
1370 auto boxed = BoxedObject<T>::MakeRef(&obj);
1371 setter(boxed, std::forward<TValue>(value));
1372 }
1373 };
1374}
1375
1376// 为sw::FieldId特化std::hash
1377template <>
1378struct std::hash<sw::FieldId> //
1379{
1380 size_t operator()(sw::FieldId fieldId) const noexcept
1381 {
1382 return static_cast<size_t>(fieldId.value);
1383 }
1384};
BoxedObject(const BoxedObject &other) noexcept(std::is_nothrow_copy_constructible< T >::value)
拷贝构造函数
Definition Reflection.h:518
static auto MakeRef(BoxedObject< U > &other) noexcept -> typename std::enable_if< _IsStaticCastable< U, T >::value, BoxedObject< T > >::type
创建引用类型的装箱对象
Definition Reflection.h:506
BoxedObject(BoxedObject &&other) noexcept(std::is_nothrow_move_constructible< T >::value)
移动构造函数
Definition Reflection.h:532
T & Unbox() noexcept
获取装箱对象中的值
Definition Reflection.h:647
static BoxedObject< T > MakeRef(T *ptr) noexcept
创建引用类型的装箱对象
Definition Reflection.h:492
BoxedObject(Args &&...args)
构造值类型的装箱对象
Definition Reflection.h:473
bool HasValue() const noexcept
判断当前装箱对象是否包含有效值
Definition Reflection.h:637
bool IsRef() const noexcept
判断当前装箱对象是否为引用类型
Definition Reflection.h:619
BoxedObject & operator=(BoxedObject &&other)
移动赋值运算符
Definition Reflection.h:583
bool IsNullRef() const noexcept
判断当前装箱对象是否为空引用
Definition Reflection.h:628
const T & Unbox() const noexcept
获取装箱对象中的值
Definition Reflection.h:658
BoxedObject & operator=(const BoxedObject &other)
拷贝赋值运算符
Definition Reflection.h:548
装箱对象模板类声明
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:175
auto IsType(const T **pout=nullptr) const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, bool >::type
判断对象是否为指定类型
Definition Reflection.h:119
auto UnsafeCast() -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&!_IsStaticCastable< DynamicObject *, T * >::value, T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:190
auto UnsafeCast() const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&_IsStaticCastable< DynamicObject *, T * >::value, const T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:204
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:219
virtual ~DynamicObject()
析构函数
Definition Reflection.h:52
auto DynamicCast() -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, T & >::type
将对象动态转换为指定类型的引用
Definition Reflection.h:141
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:158
std::type_index GetType() const
获取对象的类型信息
Definition Reflection.h:81
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:97
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:1079
static auto GetMethod(TRet(T::*method)(Args...)) -> Delegate< TRet(DynamicObject &, Args...)>
获取成员函数的委托
Definition Reflection.h:1123
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:1298
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:1264
static auto GetFieldAccessor(TField T::*field) -> Delegate< TField &(DynamicObject &)>
获取字段的访问器
Definition Reflection.h:1154
static auto GetPropertySetter(TProperty T::*prop) -> typename std::enable_if< _IsWritableProperty< TProperty >::value, Delegate< void(DynamicObject &, typename TProperty::TSetterParam)> >::type
获取属性的Setter委托
Definition Reflection.h:1206
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:1189
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:1331
static FieldId GetFieldId(TField T::*field) noexcept
获取字段的唯一标识符
Definition Reflection.h:1095
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:1315
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:1282
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:1366
static auto GetMethod(TRet(T::*method)(Args...) const) -> Delegate< TRet(DynamicObject &, Args...)>
获取常量成员函数的委托
Definition Reflection.h:1139
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< _IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:1170
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:1349
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:1245
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:1225
Reflection()=delete
静态类,不允许实例化
SimpleWindow框架的顶级命名空间,所有公共类型、控件、枚举和工具函数均定义于此。
Definition Alignment.h:4
_IsExplicitlyConvertable< TFrom, TTo > _IsStaticCastable
用于判断是否可以通过static_cast进行转换
Definition Internal.h:34
表示字段的唯一标识符
Definition Reflection.h:1032
std::wstring ToString() const
获取字段ID的字符串表示形式
Definition Reflection.h:1054
int CompareTo(FieldId other) const
比较字段ID
Definition Reflection.h:1063
uint32_t value
字段ID的数值
Definition Reflection.h:1036
FieldId()=default
默认构造函数
FieldId(uint32_t value)
构造指定值的字段ID
Definition Reflection.h:1046
判断类型是否可以使用dynamic_cast进行转换的辅助模板
Definition Internal.h:40
判断类型是否为属性的辅助模板
Definition Property.h:95
判断类型是否为可读属性的辅助模板
Definition Property.h:133
判断类型是否为可写属性的辅助模板
Definition Property.h:141