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 GetTypeIndex() 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
176 template <typename T>
178 -> typename std::enable_if<
179 std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
180 {
181 return DynamicCast<T>();
182 }
183
190 template <typename T>
192 -> typename std::enable_if<
193 std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
194 {
195 return static_cast<const T &>(*this);
196 }
197
204 template <typename T>
206 -> typename std::enable_if<
207 std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
208 {
209 return DynamicCast<T>();
210 }
211
212 public:
219 template <typename T>
220 auto IsType(T **pout = nullptr)
221 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
222
229 template <typename T>
230 auto IsType(T **pout = nullptr)
231 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
232
239 template <typename T>
240 auto IsType(const T **pout = nullptr) const
241 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
242
250 auto IsType(const T **pout = nullptr) const
251 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type;
252
261 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, T &>::type;
262
271 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, T &>::type;
272
281 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type;
282
291 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type;
292
301 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type;
302
311 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type;
312
321 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type;
322
331 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type;
332 };
333
334 /*================================================================================*/
335
342 {
343 private:
347 bool _isRef;
348
352 union {
357
361 alignas(T) uint8_t objbuf[sizeof(T)];
362 } _data;
363
364 private:
368 struct _IsRefParam {
369 bool val;
370 };
371
376 explicit BoxedObject(_IsRefParam isRef) noexcept
377 : _isRef(isRef.val), _data()
378 {
379 _isBoxedObject = true;
380 }
381
385 void Release() noexcept(std::is_nothrow_destructible<T>::value)
386 {
387 if (!_isRef) {
388 Unbox().~T();
389 }
390 }
391
392 public:
397 template <typename... Args>
400 {
401 new (_data.objbuf) T(std::forward<Args>(args)...);
402 }
403
407 virtual ~BoxedObject()
408 {
409 Release();
410 }
411
417 static BoxedObject<T> MakeRef(T *ptr) noexcept
418 {
419 BoxedObject<T> result{_IsRefParam{true}};
420 result._data.refptr = ptr;
421 return result;
422 }
423
430 template <typename U>
431 static auto MakeRef(BoxedObject<U> &other) noexcept
432 -> typename std::enable_if<_IsStaticCastable<U, T>::value, BoxedObject<T>>::type
433 {
434 BoxedObject<T> result{_IsRefParam{true}};
435 result._data.refptr = other.IsNullRef() ? nullptr : static_cast<T *>(&other.Unbox());
436 return result;
437 }
438
443 BoxedObject(const BoxedObject &other) noexcept(std::is_nothrow_copy_constructible<T>::value)
444 : BoxedObject(_IsRefParam{other._isRef})
445 {
446 if (_isRef) {
447 _data.refptr = other._data.refptr;
448 } else {
449 new (_data.objbuf) T(other.Unbox());
450 }
451 }
452
457 BoxedObject(BoxedObject &&other) noexcept(std::is_nothrow_move_constructible<T>::value)
458 : BoxedObject(_IsRefParam{other._isRef})
459 {
460 if (_isRef) {
461 _data.refptr = other._data.refptr;
462 other._data.refptr = nullptr;
463 } else {
464 new (_data.objbuf) T(std::move(other.Unbox()));
465 }
466 }
467
474 {
475 if (this == &other)
476 return *this;
477
478 if (_isRef) {
479 if (other._isRef) {
480 _data.refptr = other._data.refptr;
481 } else {
482 auto oldPtr = _data.refptr;
483 try {
484 new (_data.objbuf) T(other.Unbox());
485 _isRef = false;
486 } catch (...) {
487 _data.refptr = oldPtr;
488 throw;
489 }
490 }
491 } else {
492 if (other._isRef) {
493 Release();
494 _data.refptr = other._data.refptr;
495 _isRef = true;
496 } else {
497 Unbox() = other.Unbox();
498 }
499 }
500 return *this;
501 }
502
509 {
510 if (this == &other)
511 return *this;
512
513 if (_isRef) {
514 if (other._isRef) {
515 _data.refptr = other._data.refptr;
516 other._data.refptr = nullptr;
517 } else {
518 auto oldPtr = _data.refptr;
519 try {
520 new (_data.objbuf) T(std::move(other.Unbox()));
521 _isRef = false;
522 } catch (...) {
523 _data.refptr = oldPtr;
524 throw;
525 }
526 }
527 } else {
528 if (other._isRef) {
529 Release();
530 _data.refptr = other._data.refptr;
531 _isRef = true;
532 other._data.refptr = nullptr;
533 } else {
534 Unbox() = std::move(other.Unbox());
535 }
536 }
537 return *this;
538 }
539
545 {
546 return _isRef;
547 }
548
554 {
555 return _isRef && (_data.refptr == nullptr);
556 }
557
563 {
564 return !IsNullRef();
565 }
566
573 {
574 assert(HasValue());
575 return _isRef ? *_data.refptr : *reinterpret_cast<T *>(_data.objbuf);
576 }
577
584 {
585 assert(HasValue());
586 return _isRef ? *_data.refptr : *reinterpret_cast<const T *>(_data.objbuf);
587 }
588 };
589
590 /*================================================================================*/
591
598 template <typename T>
599 auto DynamicObject::IsType(T **pout)
600 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
601 {
602#if defined(SW_DISABLE_REFLECTION)
603 throw std::runtime_error("Reflection is disabled, cannot check type.");
604#else
605 if (!_isBoxedObject) {
606 if (pout == nullptr) {
607 return dynamic_cast<T *>(this) != nullptr;
608 } else {
609 *pout = dynamic_cast<T *>(this);
610 return *pout != nullptr;
611 }
612 } else {
613 BoxedObject<T> *obj = nullptr;
614
615 if (!IsType(&obj) || obj->IsNullRef()) {
616 if (pout != nullptr) {
617 *pout = nullptr;
618 }
619 return false;
620 } else {
621 if (pout != nullptr) {
622 *pout = &obj->Unbox();
623 }
624 return true;
625 }
626 }
627#endif
628 }
629
636 template <typename T>
637 auto DynamicObject::IsType(T **pout)
638 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
639 {
640#if defined(SW_DISABLE_REFLECTION)
641 throw std::runtime_error("Reflection is disabled, cannot check type.");
642#else
643 if (!_isBoxedObject) {
644 if (pout != nullptr) {
645 *pout = nullptr;
646 }
647 return false;
648 } else {
649 BoxedObject<T> *obj = nullptr;
650
651 if (!IsType(&obj) || obj->IsNullRef()) {
652 if (pout != nullptr) {
653 *pout = nullptr;
654 }
655 return false;
656 } else {
657 if (pout != nullptr) {
658 *pout = &obj->Unbox();
659 }
660 return true;
661 }
662 }
663#endif
664 }
665
672 template <typename T>
673 auto DynamicObject::IsType(const T **pout) const
674 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, bool>::type
675 {
676#if defined(SW_DISABLE_REFLECTION)
677 throw std::runtime_error("Reflection is disabled, cannot check type.");
678#else
679 if (!_isBoxedObject) {
680 if (pout == nullptr) {
681 return dynamic_cast<const T *>(this) != nullptr;
682 } else {
683 *pout = dynamic_cast<const T *>(this);
684 return *pout != nullptr;
685 }
686 } else {
687 const BoxedObject<T> *obj = nullptr;
688
689 if (!IsType(&obj) || obj->IsNullRef()) {
690 if (pout != nullptr) {
691 *pout = nullptr;
692 }
693 return false;
694 } else {
695 if (pout != nullptr) {
696 *pout = &obj->Unbox();
697 }
698 return true;
699 }
700 }
701#endif
702 }
703
710 template <typename T>
711 auto DynamicObject::IsType(const T **pout) const
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 *pout = nullptr;
720 }
721 return false;
722 } else {
723 const BoxedObject<T> *obj = nullptr;
724
725 if (!IsType(&obj) || obj->IsNullRef()) {
726 if (pout != nullptr) {
727 *pout = nullptr;
728 }
729 return false;
730 } else {
731 if (pout != nullptr) {
732 *pout = &obj->Unbox();
733 }
734 return true;
735 }
736 }
737#endif
738 }
739
746 template <typename T>
748 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, T &>::type
749 {
750#if defined(SW_DISABLE_REFLECTION)
751 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
752#else
753 if (!_isBoxedObject) {
754 return dynamic_cast<T &>(*this);
755 } else {
756 return dynamic_cast<BoxedObject<T> &>(*this).Unbox();
757 }
758#endif
759 }
760
767 template <typename T>
769 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, T &>::type
770 {
771#if defined(SW_DISABLE_REFLECTION)
772 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
773#else
774 if (!_isBoxedObject) {
775 throw std::bad_cast();
776 } else {
777 return dynamic_cast<BoxedObject<T> &>(*this).Unbox();
778 }
779#endif
780 }
781
788 template <typename T>
789 auto DynamicObject::DynamicCast() const
790 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type
791 {
792#if defined(SW_DISABLE_REFLECTION)
793 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
794#else
795 if (!_isBoxedObject) {
796 return dynamic_cast<const T &>(*this);
797 } else {
798 return dynamic_cast<const BoxedObject<T> &>(*this).Unbox();
799 }
800#endif
801 }
802
809 template <typename T>
810 auto DynamicObject::DynamicCast() const
811 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsDynamicCastable<DynamicObject *, T *>::value, const T &>::type
812 {
813#if defined(SW_DISABLE_REFLECTION)
814 throw std::runtime_error("Reflection is disabled, cannot perform dynamic cast.");
815#else
816 if (!_isBoxedObject) {
817 throw std::bad_cast();
818 } else {
819 return dynamic_cast<const BoxedObject<T> &>(*this).Unbox();
820 }
821#endif
822 }
823
830 template <typename T>
832 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, T &>::type
833 {
834 if (!_isBoxedObject) {
835 return static_cast<T &>(*this);
836 } else {
837 return static_cast<BoxedObject<T> &>(*this).Unbox();
838 }
839 }
840
847 template <typename T>
849 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, T &>::type
850 {
851 if (!_isBoxedObject) {
852 return DynamicCast<T>();
853 } else {
854 return static_cast<BoxedObject<T> &>(*this).Unbox();
855 }
856 }
857
864 template <typename T>
865 auto DynamicObject::UnsafeCast() const
866 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && _IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
867 {
868 if (!_isBoxedObject) {
869 return static_cast<const T &>(*this);
870 } else {
871 return static_cast<const BoxedObject<T> &>(*this).Unbox();
872 }
873 }
874
881 template <typename T>
882 auto DynamicObject::UnsafeCast() const
883 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value && !_IsStaticCastable<DynamicObject *, T *>::value, const T &>::type
884 {
885 if (!_isBoxedObject) {
886 return DynamicCast<T>();
887 } else {
888 return static_cast<const BoxedObject<T> &>(*this).Unbox();
889 }
890 }
891
892 /*================================================================================*/
893
897 struct FieldId : public IToString<FieldId>,
898 public IComparable<FieldId, FieldId> {
903
907 FieldId() = default;
908
913 : value(value)
914 {
915 }
916
920 std::wstring ToString() const
921 {
922 return std::to_wstring(value);
923 }
924
930 {
931 if (value == other.value) {
932 return 0;
933 } else {
934 return value < other.value ? -1 : 1;
935 }
936 }
937 };
938
939 /*================================================================================*/
940
945 {
946 public:
950 Reflection() = delete;
951
952 public:
960 template <typename T, typename TField>
962 {
963 auto pfunc = &Reflection::GetFieldId<T, TField>;
964
965 uint8_t buffer[sizeof(pfunc) + sizeof(field)];
966 memcpy(buffer, &pfunc, sizeof(pfunc));
967 memcpy(buffer + sizeof(pfunc), &field, sizeof(field));
968
969 uint32_t prime = 16777619u;
970 uint32_t hash = 2166136261u;
971
972 for (size_t i = 0; i < sizeof(buffer); ++i) {
973 hash ^= static_cast<uint32_t>(buffer[i]);
974 hash *= prime;
975 }
976
977 return FieldId{hash};
978 }
979
988 template <typename T, typename TRet, typename... Args>
989 static auto GetMethod(TRet (T::*method)(Args...)) -> Delegate<TRet(DynamicObject &, Args...)>
990 {
991 return [method](DynamicObject &obj, Args... args) -> TRet {
992 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
993 };
994 }
995
1004 template <typename T, typename TRet, typename... Args>
1005 static auto GetMethod(TRet (T::*method)(Args...) const) -> Delegate<TRet(DynamicObject &, Args...)>
1006 {
1007 return [method](DynamicObject &obj, Args... args) -> TRet {
1008 return (obj.UnsafeCast<T>().*method)(std::forward<Args>(args)...);
1009 };
1010 }
1011
1019 template <typename T, typename TField>
1021 {
1022 return [field](DynamicObject &obj) -> TField & {
1023 return obj.UnsafeCast<T>().*field;
1024 };
1025 }
1026
1035 template <typename T, typename TProperty>
1037 -> typename std::enable_if<
1039 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
1040 {
1041 return [prop](DynamicObject &obj) -> typename TProperty::TValue {
1042 return (obj.UnsafeCast<T>().*prop).Get();
1043 };
1044 }
1045
1054 template <typename T, typename TProperty>
1056 -> typename std::enable_if<
1058 Delegate<typename TProperty::TValue(DynamicObject &)>>::type
1059 {
1060 return nullptr;
1061 }
1062
1071 template <typename T, typename TProperty>
1073 -> typename std::enable_if<
1075 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
1076 {
1077 return [prop](DynamicObject &obj, typename TProperty::TSetterParam value) {
1078 (obj.UnsafeCast<T>().*prop).Set(std::forward<typename TProperty::TSetterParam>(value));
1079 };
1080 }
1081
1090 template <typename T, typename TProperty>
1092 -> typename std::enable_if<
1094 Delegate<void(DynamicObject &, typename TProperty::TSetterParam)>>::type
1095 {
1096 return nullptr;
1097 }
1098
1099 public:
1110 template <typename T, typename TFunc, typename... Args>
1111 static auto InvokeMethod(const Delegate<TFunc> &method, T &obj, Args &&...args)
1112 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value,
1113 decltype(method(obj, std::forward<Args>(args)...))>::type
1114 {
1115 assert(method != nullptr);
1116 return method(obj, std::forward<Args>(args)...);
1117 }
1118
1129 template <typename T, typename TFunc, typename... Args>
1130 static auto InvokeMethod(const Delegate<TFunc> &method, T &obj, Args &&...args)
1131 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value,
1132 decltype(method(std::declval<DynamicObject &>(), std::forward<Args>(args)...))>::type
1133 {
1134 assert(method != nullptr);
1135 auto boxed = BoxedObject<T>::MakeRef(&obj);
1136 return method(boxed, std::forward<Args>(args)...);
1137 }
1138
1147 template <typename T, typename TField>
1148 static auto AccessField(const Delegate<TField &(DynamicObject &)> &accessor, T &obj)
1149 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, TField &>::type
1150 {
1151 assert(accessor != nullptr);
1152 return accessor(obj);
1153 }
1154
1163 template <typename T, typename TField>
1164 static auto AccessField(const Delegate<TField &(DynamicObject &)> &accessor, T &obj)
1165 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value, TField &>::type
1166 {
1167 assert(accessor != nullptr);
1168 auto boxed = BoxedObject<T>::MakeRef(&obj);
1169 return accessor(boxed);
1170 }
1171
1180 template <typename T, typename TValue>
1181 static auto GetProperty(const Delegate<TValue(DynamicObject &)> &getter, T &obj)
1182 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value, TValue>::type
1183 {
1184 assert(getter != nullptr);
1185 return getter(obj);
1186 }
1187
1196 template <typename T, typename TValue>
1197 static auto GetProperty(const Delegate<TValue(DynamicObject &)> &getter, T &obj)
1198 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value, TValue>::type
1199 {
1200 assert(getter != nullptr);
1201 auto boxed = BoxedObject<T>::MakeRef(&obj);
1202 return getter(boxed);
1203 }
1204
1214 template <typename T, typename TParam, typename TValue>
1215 static auto SetProperty(const Delegate<void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value)
1216 -> typename std::enable_if<std::is_base_of<DynamicObject, T>::value>::type
1217 {
1218 assert(setter != nullptr);
1219 setter(obj, std::forward<TValue>(value));
1220 }
1221
1231 template <typename T, typename TParam, typename TValue>
1232 static auto SetProperty(const Delegate<void(DynamicObject &, TParam)> &setter, T &obj, TValue &&value)
1233 -> typename std::enable_if<!std::is_base_of<DynamicObject, T>::value>::type
1234 {
1235 assert(setter != nullptr);
1236 auto boxed = BoxedObject<T>::MakeRef(&obj);
1237 setter(boxed, std::forward<TValue>(value));
1238 }
1239 };
1240}
1241
1242// 为sw::FieldId特化std::hash
1243template <>
1244struct std::hash<sw::FieldId> //
1245{
1246 size_t operator()(sw::FieldId fieldId) const noexcept
1247 {
1248 return static_cast<size_t>(fieldId.value);
1249 }
1250};
BoxedObject(const BoxedObject &other) noexcept(std::is_nothrow_copy_constructible< T >::value)
拷贝构造函数
Definition Reflection.h:443
static auto MakeRef(BoxedObject< U > &other) noexcept -> typename std::enable_if< _IsStaticCastable< U, T >::value, BoxedObject< T > >::type
创建引用类型的装箱对象
Definition Reflection.h:431
BoxedObject(BoxedObject &&other) noexcept(std::is_nothrow_move_constructible< T >::value)
移动构造函数
Definition Reflection.h:457
T & Unbox() noexcept
获取装箱对象中的值
Definition Reflection.h:572
static BoxedObject< T > MakeRef(T *ptr) noexcept
创建引用类型的装箱对象
Definition Reflection.h:417
BoxedObject(Args &&...args)
构造值类型的装箱对象
Definition Reflection.h:398
bool HasValue() const noexcept
判断当前装箱对象是否包含有效值
Definition Reflection.h:562
bool IsRef() const noexcept
判断当前装箱对象是否为引用类型
Definition Reflection.h:544
BoxedObject & operator=(BoxedObject &&other)
移动赋值运算符
Definition Reflection.h:508
bool IsNullRef() const noexcept
判断当前装箱对象是否为空引用
Definition Reflection.h:553
const T & Unbox() const noexcept
获取装箱对象中的值
Definition Reflection.h:583
BoxedObject & operator=(const BoxedObject &other)
拷贝赋值运算符
Definition Reflection.h:473
装箱对象模板类声明
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:177
auto UnsafeCast() const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&_IsStaticCastable< DynamicObject *, T * >::value, const T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:191
auto UnsafeCast() const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value &&!_IsStaticCastable< DynamicObject *, T * >::value, const T & >::type
将对象不安全地转换为指定类型的引用
Definition Reflection.h:205
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
判断对象是否为指定类型
friend class BoxedObject
允许BoxedObject访问_isBoxedObject成员
Definition Reflection.h:33
auto DynamicCast() const -> typename std::enable_if< std::is_base_of< DynamicObject, T >::value, const T & >::type
将对象动态转换为指定类型的常量引用
Definition Reflection.h:146
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
判断对象是否为指定类型
std::type_index GetTypeIndex() const
获取对象的类型索引
Definition Reflection.h:69
全序比较接口
Definition IComparable.h:54
为支持ToString方法的类提供统一接口
Definition IToString.h:13
值转换器接口
Definition IValueConverter.h:14
提供反射相关功能
Definition Reflection.h:945
static auto GetMethod(TRet(T::*method)(Args...)) -> Delegate< TRet(DynamicObject &, Args...)>
获取成员函数的委托
Definition Reflection.h:989
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:1164
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:1130
static auto GetFieldAccessor(TField T::*field) -> Delegate< TField &(DynamicObject &)>
获取字段的访问器
Definition Reflection.h:1020
static auto GetPropertySetter(TProperty T::*prop) -> typename std::enable_if< _IsWritableProperty< TProperty >::value, Delegate< void(DynamicObject &, typename TProperty::TSetterParam)> >::type
获取属性的Setter委托
Definition Reflection.h:1072
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:1055
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:1197
static FieldId GetFieldId(TField T::*field) noexcept
获取字段的唯一标识符
Definition Reflection.h:961
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:1181
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:1148
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:1232
static auto GetMethod(TRet(T::*method)(Args...) const) -> Delegate< TRet(DynamicObject &, Args...)>
获取常量成员函数的委托
Definition Reflection.h:1005
static auto GetPropertyGetter(TProperty T::*prop) -> typename std::enable_if< _IsReadableProperty< TProperty >::value, Delegate< typename TProperty::TValue(DynamicObject &)> >::type
获取属性的Getter委托
Definition Reflection.h:1036
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:1215
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:1111
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:1091
Reflection()=delete
静态类,不允许实例化
表示字段的唯一标识符
Definition Reflection.h:898
std::wstring ToString() const
获取字段ID的字符串表示形式
Definition Reflection.h:920
int CompareTo(FieldId other) const
比较字段ID
Definition Reflection.h:929
uint32_t value
字段ID的数值
Definition Reflection.h:902
FieldId()=default
默认构造函数
FieldId(uint32_t value)
构造指定值的字段ID
Definition Reflection.h:912
判断类型是否可以使用dynamic_cast进行转换的辅助模板
Definition Internal.h:40
判断类型是否为属性的辅助模板
Definition Property.h:95
判断类型是否为可读属性的辅助模板
Definition Property.h:133
判断类型是否为可写属性的辅助模板
Definition Property.h:141