CodePorting.Translator Cs2Cpp
CodePorting.Translator.Cs2Cpp.Framework
object_ext.h
1
2#pragma once
3
4#include "defines.h"
5#include <system/object_type.h>
6#include <system/enum.h>
7#include <system/boxed_enum.h>
8#include <system/text/string_builder.h>
9#include <system/details/pointer_collection_helpers.h>
10#include <system/get_hash_code.h>
11
12namespace System { namespace Collections { class IList; } }
13
14namespace System
15{
16
20class ObjectExt : public ObjectType
21{
22public:
27 template <typename T>
28 static int GetHashCode(const T& obj)
29 {
30 return System::GetHashCode<T>(obj);
31 }
32
33 template<typename T, typename T2>
34 static typename std::enable_if<IsExceptionWrapper<T>::value, bool>::type Equals(const T& obj, const T2& another)
35 {
36 if (obj.IsNull())
37 System::Detail::SmartPtrCounter::ThrowNullReferenceException();
38 return obj.Equals(another);
39 }
40
48 template<typename T, typename T2>
49 static typename std::enable_if<IsSmartPtr<T>::value, bool>::type Equals(const T& obj, const T2& another)
50 {
51 return obj->Equals(another);
52 }
53
61 template<typename T, typename T2>
62 static typename std::enable_if<!IsExceptionWrapper<T>::value && !IsSmartPtr<T>::value && !std::is_scalar<T>::value, bool>::type Equals(T obj, const T2& another)
63 {
64 return obj.Equals(another);
65 }
66
74 template<typename T, typename T2>
75 static typename std::enable_if<!IsSmartPtr<T>::value && std::is_scalar<T>::value, bool>::type Equals(const T& obj, const T2& another)
76 {
77 return (obj == another);
78 }
79
86 template<size_t N>
87 static bool Equals(const char_t (&obj)[N], String another)
88 {
89 return another == obj;
90 }
91
92
96 static inline String ToString(const char_t * obj)
97 {
98 return String(obj);
99 }
100
105 template<typename T>
106 static inline String ToString(const Nullable<T> & obj)
107 {
108 return (obj.IsNull() ? u"" : ToString(obj.get_Value()));
109 }
110
115 template<typename T>
116 static typename std::enable_if<std::is_enum<T>::value, String>::type ToString(const T& obj)
117 {
118 String str = Enum<T>::GetName(obj);
119 return !str.IsNullOrEmpty() ? str : System::Convert::ToString(static_cast<typename std::underlying_type<T>::type>(obj));
120 }
121
126 template<typename T>
127 static typename std::enable_if<IsSmartPtr<T>::value, String>::type ToString(const T& obj)
128 {
129 return obj->ToString();
130 }
131
136 template<typename T>
137 static typename std::enable_if<IsSmartPtr<T>::value || std::is_pointer<T>::value || IsExceptionWrapper<T>::value, String>::type ToString(T& obj)
138 {
139 return obj->ToString();
140 }
141
146 template<typename T>
147 static typename std::enable_if<!IsSmartPtr<T>::value && std::is_scalar<T>::value && !std::is_enum<T>::value, String>::type ToString(T& obj)
148 {
149 return System::Convert::ToString(obj);
150 }
151
156 template<typename T>
157 static typename std::enable_if<!IsSmartPtr<T>::value && std::is_scalar<T>::value && !std::is_enum<T>::value, String>::type ToString(T&& obj)
158 {
159 return System::Convert::ToString(obj);
160 }
161
166 template<typename T>
167 static typename std::enable_if<!IsExceptionWrapper<T>::value && !IsSmartPtr<T>::value && !std::is_scalar<T>::value && !IsNullable<T>::value, String>::type ToString(T& obj)
168 {
169 return obj.ToString();
170 }
171
176 template <typename T>
177 static typename std::enable_if<!IsSmartPtr<T>::value && !std::is_scalar<T>::value && !IsNullable<T>::value, String>::type ToString(const T& obj)
178 {
179 return obj.ToString();
180 }
181
186 template<typename T>
187 static typename std::enable_if<!IsSmartPtr<T>::value && !std::is_scalar<T>::value && !IsNullable<T>::value && !std::is_reference<T>::value, String>::type ToString(T&& obj)
188 {
189 return obj.ToString();
190 }
191
197 template<typename T>
198 static typename std::enable_if<std::is_enum<T>::value, System::SmartPtr<System::Object>>::type Box(const T& value)
199 {
200 return System::MakeObject<BoxedEnum<T>>(value);
201 }
202
208 template<typename T>
209 static typename std::enable_if<!std::is_enum<T>::value && !IsNullable<T>::value, System::SmartPtr<System::Object>>::type Box(const T& value)
210 {
211 return System::MakeObject<BoxedValue<T>>(value);
212 }
213
218 template<typename T>
219 static typename std::enable_if <IsNullable<T>::value, System::SmartPtr<System::Object>>::type Box(const T& value)
220 {
221 if (value == nullptr)
222 return nullptr;
223
224 return System::MakeObject<BoxedValue<typename T::ValueType>>(value.get_Value());
225 }
226
232 template<typename T>
233 static typename std::enable_if<std::is_enum<T>::value, T>::type Unbox(const SmartPtr<Object>& obj)
234 {
235 using UT = typename std::underlying_type<T>::type;
236
237 if (obj && obj->Is(BoxedEnum<T>::Type()))
238 {
239 auto boxed = obj.template Cast<BoxedEnum<T>>();
240 return static_cast<T>(boxed->unbox());
241 }
242 using UT = typename std::underlying_type<T>::type;
243 if (obj && obj->Is(ObjectExt::GetType<UT>()))
244 {
245 auto boxed = obj.Cast<BoxedValue<UT>>();
246 return static_cast<T>(boxed->unbox());
247 }
248
249
250 throw InvalidCastException();
251 }
252
258 template<class T>
259 static typename std::enable_if<!std::is_enum<T>::value && detail::has_operator_equal<T>::value, T>::type Unbox(const SmartPtr<Object>& obj)
260 {
261 if (obj)
262 {
263 if (obj->Is(ObjectExt::GetType<T>()))
264 {
265 auto boxed = obj.template Cast<BoxedValue<T>>();
266 return boxed->unbox();
267 }
268
269 throw InvalidCastException();
270 }
271 throw NullReferenceException();
272 }
273
279 template<class T>
280 static typename std::enable_if<!std::is_enum<T>::value && !detail::has_operator_equal<T>::value, T>::type Unbox(const SmartPtr<Object>& obj)
281 {
282
283 if (obj && obj->Is(BoxedValue<T>::Type()))
284 {
285 auto boxed = obj.template Cast<BoxedValue<T>>();
286 return boxed->unbox();
287 }
288
289 throw InvalidCastException();
290 }
291
297 template<class T, class E>
298 static typename std::enable_if<std::is_enum<E>::value && std::numeric_limits<T>::is_integer, T>::type Unbox(E e)
299 {
300 return static_cast<T>(e);
301 }
302
308 template<class T, class E>
309 static typename std::enable_if<std::is_enum<E>::value && std::is_enum<T>::value, T>::type Unbox(E e)
310 {
311 return static_cast<T>(e);
312 }
313
318 static ASPOSECPP_SHARED_API String UnboxStringSafe(const SmartPtr<Object>& obj);
319
325 template<class T>
326 static Nullable<T> UnboxToNullable(const SmartPtr<Object>& obj, bool safe = true)
327 {
328 if (obj)
329 {
330 if (obj->Is(ObjectExt::GetType<T>()))
331 {
332 auto boxed = obj.template Cast<BoxedValue<T>>();
333 return Nullable<T>(boxed->unbox());
334 }
335 }
336
337 if (!obj || safe)
338 return Nullable<T>(nullptr);
339
340 throw InvalidCastException();
341 }
342
348 template <class T>
349 static typename std::enable_if<System::IsBoxable<T>::value, bool>::type Is(const T& obj)
350 {
351 return true;
352 }
353
360 template<class T, class U>
361 static typename std::enable_if<std::is_convertible<T, Object>::value && std::is_final<T>::value &&
363 bool>::type Is(const U& obj)
364 {
365 if (obj == nullptr)
366 return false;
367
368 return typeid(*obj.get()) == typeid(T);
369 }
370
377 template<class T, class U>
378 static typename std::enable_if<std::is_convertible<T, Object>::value&& !std::is_final<T>::value &&
380 bool>::type Is(const U& obj)
381 {
382 if (!obj)
383 return false;
384
385 return dynamic_cast<T*>(obj.get()) != nullptr;
386 }
387
393 template<class T>
394 static typename std::enable_if<std::is_convertible<T, Object>::value,
395 bool>::type Is(const Object& obj)
396 {
397 return obj.Is(T::Type());
398 }
399
405 template<class T>
406 static typename std::enable_if<!std::is_convertible<T, Object>::value,
407 bool>::type Is(const Object& obj)
408 {
409 return false;
410 }
411
417 template<class T, class U>
418 static typename std::enable_if<IsSmartPtr<T>::value, bool>::type Is(const SmartPtr<U>& obj)
419 {
420 if (!obj)
421 return false;
422
423 return dynamic_cast<typename T::Pointee_*>(obj.get()) != nullptr;
424 }
425
431 template<class T, class U>
432 static typename std::enable_if<IsExceptionWrapper<T>::value, bool>::type Is(const ExceptionWrapper<U>& obj)
433 {
434 if (obj == nullptr)
435 return false;
436
437 return Is<SmartPtr<typename T::ExceptionType>>(obj.Get());
438 }
439
445 template<class T>
446 static typename std::enable_if<IsNullable<T>::value, bool>::type Is(const SmartPtr<Object>& obj)
447 {
448 if (!obj)
449 return false;
450
451 if (obj->Is(System::ObjectExt::GetType<typename T::ValueType>()))
452 return true;
453
454 return false;
455 }
456
462 template<class T>
463 static typename std::enable_if<
465 bool
466 >::type Is(const SmartPtr<Object>& obj)
467 {
468 if (!obj)
469 return false;
470
471 if (obj->Is(System::ObjectExt::GetType<T>()))
472 {
473 return true;
474 }
475
476 if (obj->Is(Nullable<T>::Type()))
477 {
478 auto boxed = obj.Cast<BoxedValue<Nullable<T>>>();
479 return !boxed->unbox().IsNull();
480 }
481
482 return false;
483 }
484
490 template<class T>
491 static typename std::enable_if<
493 bool
494 >::type Is(const SmartPtr<Object>& obj)
495 {
496 if (!obj)
497 return false;
498
499 if (obj->Is(TypeInfo::BoxedValueType<T>()))
500 {
501 return true;
502 }
503
504 return false;
505 }
506
513 template <class T, class V>
514 static typename std::enable_if<
515 System::IsBoxable<T>::value && !IsNullable<T>::value && !std::is_enum<T>::value && !std::is_same<V, Object>::value,
516 bool>::type Is(const SmartPtr<V>& obj)
517 {
518 return dynamic_cast<T*>(obj.get()) != nullptr;
519 }
520
527 template<class T, class U>
528 static typename std::enable_if<std::is_enum<T>::value, bool>::type Is(const SmartPtr<U>& obj)
529 {
530 if (!obj)
531 return false;
532
533 if (obj->Is(TypeInfo::BoxedValueType<T>()))
534 return Enum<T>::IsDefined(Unbox<T>(obj));
535
536 return false;
537 }
538
545 template<class T, class U>
546 static typename std::enable_if<std::is_enum<T>::value, bool>::type Is(const WeakPtr<U>& obj)
547 {
548 if (!obj)
549 return false;
550
551 if (obj->Is(TypeInfo::BoxedValueType<T>()))
552 return Enum<T>::IsDefined(Unbox<T>(obj));
553
554 return false;
555 }
556
557private:
562 template<class T, class U>
563 static bool IsImpl()
564 {
565 TypeInfo typeU = ObjectExt::GetType<U>();
566 TypeInfo typeT = ObjectExt::GetType<T>();
567 return typeU == typeT || typeU.IsSubclassOf(typeT);
568 }
569
570public:
576 template<class T, class U>
577 static bool Is(const Nullable<U>& value)
578 {
579 if (value == nullptr)
580 return false;
581
582 return IsImpl<T, U>();
583 }
584
590 template<class T>
591 static bool Is(const char16_t* str)
592 {
593 if (str == nullptr)
594 return false;
595
596 return IsImpl<T, System::String>();
597 }
598
604 template<class T>
605 static bool Is(int32_t value)
606 {
607 ASPOSE_UNUSED(value);
608
609 return IsImpl<T, System::Int32>();
610 }
611
615 static ASPOSECPP_SHARED_API bool IsBoxedValue(const SmartPtr<Object>& obj);
616
621 template<typename T>
622 static typename std::enable_if<IsSmartPtr<T>::value, System::SmartPtr<Object> >::type UnknownToObject(T obj)
623 {
624 return obj.template Cast<Object>();
625 }
626
631 template<typename T>
632 static typename std::enable_if<!IsSmartPtr<T>::value, System::SmartPtr<Object> >::type UnknownToObject(const T& obj)
633 {
634 return Box<T>(obj);
635 }
636
641 template<typename T>
642 static typename std::enable_if<IsSmartPtr<T>::value, T>::type ObjectToUnknown(SmartPtr<Object> obj)
643 {
644 return obj.template Cast<typename T::Pointee_>();
645 }
646
651 template<typename T>
652 static typename std::enable_if<!IsSmartPtr<T>::value, T>::type ObjectToUnknown(SmartPtr<Object> obj)
653 {
654 return System::ObjectExt::Unbox<T>(obj);
655 }
656
662 template<typename T>
663 static typename std::enable_if<!std::is_scalar<T>::value, bool>::type UnknownIsNull(T obj)
664 {
665 return obj == nullptr;
666 }
667
673 template<typename T>
674 static typename std::enable_if<std::is_scalar<T>::value, bool>::type UnknownIsNull(T obj)
675 {
676 return false;
677 }
678
686 template<typename RT1, typename RT2, typename F>
687 static typename std::conditional<std::is_convertible<RT2, RT1>::value, RT1, RT2>::type CoalesceInternal(RT1 value, F func)
688 {
689 return value != nullptr ? value : func();
690 }
691
692
699 template<typename T0, typename T1>
700 static auto Coalesce(T0 value, T1 func)
701 {
702 using retval_t = System::Details::ResultOf<T1>;
703 return CoalesceInternal<T0, retval_t, typename std::function<retval_t()>>(value, func);
704 }
705
712 template<typename T0, typename T1>
713 static T0 Coalesce(System::Nullable<T0> value, T1 func)
714 {
715 return !value.IsNull() ? value.get_Value() : func();
716 }
717
722 template<typename T>
724 {
726 }
727
733 template<typename To, typename ...From>
734 static typename std::enable_if<(std::is_fundamental<To>::value), std::array<To, sizeof...(From)>>::type ArrayInitializerCast(From ...args)
735 {
736 return std::array<To, sizeof...(From)>({ static_cast<To>(args)... });
737 }
738
740
741 template<typename T>
742 static typename std::enable_if<System::IsBoxable<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
743 {
744 return ObjectExt::Box(value);
745 }
746
747 template<typename T>
748 static typename std::enable_if<System::IsSmartPtr<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
749 {
750 return value;
751 }
752};
753
759template<>
760inline bool ObjectExt::Equals<float, float>(const float& obj, const float& another)
761{
762 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
763}
764
770template<>
771inline bool ObjectExt::Equals<double, double>(const double& obj, const double& another)
772{
773 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
774}
775
779template<>
780inline SmartPtr<Object> ObjectExt::Box<String>(const String& value)
781{
782 return value.IsNull() ? nullptr : MakeObject<BoxedValue<String>>(value);
783}
784
788template<>
789inline String ObjectExt::Unbox<String>(const SmartPtr<Object>& obj)
790{
791 if (obj == nullptr)
792 return String();
793
794 if (obj && obj->Is(String::Type()))
795 {
796 auto boxed = obj.Cast<BoxedValue<String>>();
797 return boxed->unbox();
798 }
799
800 throw InvalidCastException();
801}
802
803namespace Details {
804
806template<typename T>
807struct IsObjectArray : std::false_type {};
808template <typename O>
809struct IsObjectArray<System::Array<SmartPtr<O>>> : std::is_base_of<System::Object, O> {};
810template <>
811struct IsObjectArray<System::Array<String>> : std::true_type {};
812template <typename A>
813struct IsObjectArray<SmartPtr<A>> : IsObjectArray<A> {};
814
815
819template <typename Source, typename Result>
820struct CastType
821{
823 static constexpr bool None = std::is_same<Source, Result>::value;
824
826 static constexpr bool StaticArithmetic =
827 (std::is_enum<Source>::value || std::is_arithmetic<Source>::value) &&
828 (std::is_enum<Result>::value || std::is_arithmetic<Result>::value);
830 static constexpr bool StaticIntPtr =
831 (std::is_same<Source, IntPtr>::value && (std::is_arithmetic<Result>::value || std::is_pointer<Result>::value)) ||
832 (std::is_same<Result, IntPtr>::value && (std::is_arithmetic<Source>::value || std::is_pointer<Source>::value));
834 static constexpr bool StaticString = std::is_same<Result, String>::value && std::is_constructible<String, Source>::value;
836 static constexpr bool Static = !None && (StaticArithmetic || StaticIntPtr || StaticString);
837
839 static constexpr bool Exception = !None &&
840 IsExceptionWrapper<Source>::value && IsExceptionWrapper<Result>::value &&
841 (std::is_convertible<Result, Source>::value || std::is_base_of<Result, Source>::value);
843 static constexpr bool ObjectToException = !None &&
844 std::is_same<SharedPtr<System::Object>, Source>::value && IsExceptionWrapper<Result>::value;
845
847 static constexpr bool Array = !None && IsObjectArray<Result>::value && IsObjectArray<Source>::value;
848
850 static constexpr bool ToSmartPointer = std::is_base_of<System::Object, Result>::value &&
851 !IsExceptionWrapper<Result>::value && !IsBoxable<Result>::value;
853 static constexpr bool RawPointer = ToSmartPointer && std::is_pointer<Source>::value &&
854 std::is_base_of<Object, std::remove_pointer_t<Source>>::value;
856 static constexpr bool Pointer = !None && !Array && ToSmartPointer && IsSmartPtr<Source>::value;
858 static constexpr bool PointerToPointer = !None && !Array && IsSmartPtr<Source>::value && IsSmartPtr<Result>::value;
859
861 static constexpr bool UnboxingToNullable =
862 (std::is_same<Source, SmartPtr<Object>>::value || std::is_same<Source, std::nullptr_t>::value) &&
863 IsNullable<Result>::value;
864
866 static constexpr bool InterfaceUnboxingToNullable =
867 !std::is_same<Source, SmartPtr<Object>>::value && IsSmartPtr<Source>::value && IsNullable<Result>::value;
868
870 static constexpr bool InterfaceUnboxing = !std::is_same<Source, SmartPtr<Object>>::value &&
871 IsSmartPtr<Source>::value && !IsNullable<Result>::value &&
872 std::is_base_of<Details::BoxableObjectBase, Result>::value;
873
875 static constexpr bool NullableBoxing = !UnboxingToNullable && (std::is_same<Result, Nullable<Source>>::value ||
876 (IsNullable<Result>::value && std::is_same<Source, std::nullptr_t>::value));
878 static constexpr bool NullableUnboxing = std::is_same<Source, Nullable<Result>>::value;
879
881 static constexpr bool BoxingCommon = !None && (std::is_base_of<Object, Result>::value || IsSmartPtr<Result>::value);
883 static constexpr bool EnumBoxing = BoxingCommon && std::is_enum<Source>::value;
885 static constexpr bool HeapifyBoxing = std::is_same<Result, SharedPtr<Source>>::value;
887 static constexpr bool InterfaceBoxing = BoxingCommon && !HeapifyBoxing && !std::is_same<Result, Object>::value &&
888 std::is_base_of<Details::BoxableObjectBase, Source>::value;
890 static constexpr bool Boxing = BoxingCommon && !EnumBoxing && !HeapifyBoxing && !InterfaceBoxing && IsBoxable<Source>::value;
892 static constexpr bool StringBoxing = BoxingCommon && !Boxing && !Pointer && !std::is_same<Source, std::nullptr_t>::value &&
893 std::is_constructible<String, Source>::value;
894
896 static constexpr bool Unboxing =
897 !UnboxingToNullable && !InterfaceUnboxing && IsSmartPtr<Source>::value && IsBoxable<Result>::value;
898
900 static constexpr bool UnboxingToString = std::is_same<Result, String>::value && std::is_same<Source, SmartPtr<Object>>::value;
901
903 static constexpr bool Null = !Static && !UnboxingToNullable && !NullableBoxing &&
904 std::is_same<Source, std::nullptr_t>::value;
905
907 static constexpr bool InvalidUnboxing = Unboxing && !InterfaceUnboxingToNullable && !InterfaceUnboxing && !std::is_same<Source, SmartPtr<Object>>::value;
908};
909
910} // namespace Details
911
918template <typename Result, typename Source>
919std::enable_if_t<Details::CastType<Source, Result>::None, Result> ExplicitCast(const Source& value)
920{
921 return value;
922}
923
930template <typename Result, typename Source>
931std::enable_if_t<Details::CastType<Source, Result>::Static, Result> ExplicitCast(const Source& value)
932{
933 return Result(value);
934}
935
943template <typename Result, typename Source>
944std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> ExplicitCast(const Source& value)
945{
946 return value.Get().template Cast<typename Result::ExceptionType, std::true_type>() ? Result(value.Get())
947 : Result(nullptr);
948}
949
957template <typename Result, typename Source>
958std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> ExplicitCast(const Source& value)
959{
960 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::true_type>();
961 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::true_type>())
962 : Result(nullptr);
963}
964
972template <typename Result, typename Source>
973std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
974 ExplicitCast(const Source& value)
975{
976 return value.template Cast<Result, std::true_type>();
977}
978
986template <typename Result, typename Source>
987std::enable_if_t<Details::CastType<Source, Result>::RawPointer, typename CastResult<std::remove_pointer_t<Result>>::type>
988 ExplicitCast(Source value)
989{
990 return ExplicitCast<Result>(SmartPtr<std::remove_pointer_t<Source>>(value));
991}
992
1000template <typename Result, typename Source>
1001std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
1002 ExplicitCast(const Source& value)
1003{
1004 return ExplicitCast<typename Result::Pointee_>(value);
1005}
1006
1014template <typename Result, typename Source>
1015std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1016 ExplicitCast(const Source& value)
1017{
1018 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, false);
1019}
1020
1027template <typename Result, typename Source>
1028std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> ExplicitCast(const Source& value)
1029{
1030 return Result(value);
1031}
1032
1040template <typename Result, typename Source>
1041std::enable_if_t<Details::CastType<Source, Result>::NullableUnboxing, Result> ExplicitCast(const Source& value)
1042{
1043 if (value == nullptr)
1044 throw NullReferenceException(u"Can not unbox null value");
1045
1046 return static_cast<Result>(value);
1047}
1048
1055template <typename Result, typename Source>
1056std::enable_if_t<Details::CastType<Source, Result>::EnumBoxing, SmartPtr<BoxedValueBase>>
1057 ExplicitCast(const Source& value)
1058{
1059 return ObjectExt::BoxEnum(value);
1060}
1061
1069template <typename Result, typename Source>
1070std::enable_if_t<Details::CastType<Source, Result>::HeapifyBoxing, typename CastResult<Result>::type>
1071 ExplicitCast(const Source& value)
1072{
1073 return MakeObject<Source>(value).template Cast<typename Result::Pointee_, std::true_type>();
1074}
1075
1082template <typename Result, typename Source>
1083std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1084 ExplicitCast(const Source& value)
1085{
1086 return MakeObject<Source>(value).template Cast<Result, std::true_type>();
1087}
1088
1095template <typename Result, typename Source>
1096std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1097 ExplicitCast(const Source& value)
1098{
1099 return ObjectExt::Box(value);
1100}
1101
1108template <typename Result, typename Source>
1109std::enable_if_t<Details::CastType<Source, Result>::StringBoxing, typename CastResult<Result>::type>
1110 ExplicitCast(const Source& value)
1111{
1112 return ObjectExt::Box<String>(value);
1113}
1114
1121template <typename Result, typename Source>
1122std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxing, Result> ExplicitCast(const Source& value)
1123{
1124 return *(value.template Cast<Result, std::true_type>());
1125}
1126
1133template <typename Result, typename Source>
1134std::enable_if_t<Details::CastType<Source, Result>::Unboxing, Result> ExplicitCast(const Source& value)
1135{
1136 return ObjectExt::Unbox<Result>(value);
1137}
1138
1145template <typename Result, typename Source>
1146std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1147{
1148 return typename CastResult<Result>::type(nullptr);
1149}
1150
1158template <typename Result, typename Source>
1159std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1160{
1161 if (!value)
1162 return nullptr;
1163
1164 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1165 std::transform(value->data().begin(), value->data().end(), result->data().begin(),
1166 [](const auto& value) {return ExplicitCast<typename Result::ValueType>(value);});
1167
1168 return result;
1169}
1170
1177template <typename Result, typename Source>
1178std::enable_if_t<Details::CastType<Source, Result>::Static, Result> AsCast(const Source& value)
1179{
1180 return Result(value);
1181}
1182
1189template <typename Result, typename Source>
1190std::enable_if_t<Details::CastType<Source, Result>::None, Result> AsCast(const Source& value)
1191{
1192 return value;
1193}
1194
1201template <typename Result, typename Source>
1202std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> AsCast(const Source& value)
1203{
1204 return value.Get().template Cast<typename Result::ExceptionType, std::false_type>() ? Result(value.Get())
1205 : Result(nullptr);
1206}
1207
1214template <typename Result, typename Source>
1215std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> AsCast(const Source& value)
1216{
1217 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::false_type>();
1218 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::false_type>())
1219 : Result(nullptr);
1220}
1221
1228template <typename Result, typename Source>
1229std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
1230 AsCast(const Source& value)
1231{
1232 return value.template Cast<Result, std::false_type>();
1233}
1234
1241template <typename Result, typename Source>
1242std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
1243 AsCast(const Source& value)
1244{
1245 return AsCast<typename Result::Pointee_>(value);
1246}
1247
1254template <typename Result, typename Source>
1255std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1256 AsCast(const Source& value)
1257{
1258 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, true);
1259}
1260
1267template <typename Result, typename Source>
1268std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxingToNullable, Result> AsCast(const Source& value)
1269{
1270 Result result;
1271 if (ObjectExt::Is<typename Result::ValueType>(value))
1272 {
1273 result = *(value.template Cast<typename Result::ValueType, std::false_type>());
1274 }
1275 return result;
1276}
1277
1283template <typename Result, typename Source>
1284std::enable_if_t<Details::CastType<Source, Result>::InvalidUnboxing, Result> AsCast(const Source& value)
1285{
1286 return Default<Result>();
1287}
1288
1295template <typename Result, typename Source>
1296std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> AsCast(const Source& value)
1297{
1298 return Result(value);
1299}
1300
1307template <typename Result, typename Source>
1308std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1309 AsCast(const Source& value)
1310{
1311 if (!ObjectExt::Is<Result>(value))
1312 {
1313 return nullptr;
1314 }
1315
1316 return MakeObject<Source>(value).template Cast<Result, std::false_type>();
1317}
1318
1325template <typename Result, typename Source>
1326std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1327 AsCast(const Source& value)
1328{
1329 return ObjectExt::Box(value).template Cast<typename Result::Pointee_, std::false_type>();
1330}
1331
1338template <typename Result, typename Source>
1339std::enable_if_t<Details::CastType<Source, Result>::UnboxingToString, Result> AsCast(const Source& value)
1340{
1341 return ObjectExt::UnboxStringSafe(value);
1342}
1343
1350template <typename Result, typename Source>
1351std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> AsCast(const Source& value)
1352{
1353 return typename CastResult<Result>::type(nullptr);
1354}
1355
1362template <typename Result, typename Source>
1363std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> AsCast(const Source& value)
1364{
1365 if (!value)
1366 return nullptr;
1367
1368 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1369 auto d_it = result->data().begin();
1370 auto s_it = value->data().begin();
1371 while (s_it != value->data().end())
1372 {
1373 auto& source_element = *(s_it++);
1374 auto& result_element = *(d_it++);
1375
1376 result_element = AsCast<typename Result::ValueType>(source_element);
1377
1378 // Fail entire cast if any element fails
1379 if (source_element != nullptr && result_element == nullptr)
1380 return nullptr;
1381 }
1382
1383 return result;
1384}
1385
1392template <typename T0, typename T1>
1393static auto SafeInvoke(T0 expr, T1 func)
1394{
1395 // The type which 'func' actually returns
1396 using retval_t = System::Details::ResultOf<T1, T0>;
1397
1398 // The type which function SafeInvoke will return. Non-nullable types will be wrapped by 'Nullable<>' class template.
1399 using result_t = typename std::conditional<
1400 std::is_base_of<Details::BoxableObjectBase, retval_t>::value || std::is_arithmetic<retval_t>::value || std::is_enum<retval_t>::value,
1402 retval_t>::type;
1403
1404 return expr != nullptr ? result_t(func(expr)) : result_t(nullptr);
1405}
1406
1407} // namespace System
Represents boxed enumeration value. Objects of this class should only be allocated using System::Make...
Definition: boxed_enum.h:27
Represents a boxed value. Objects of this class should only be allocated using System::MakeObject() f...
Definition: boxed_value.h:172
const T & unbox() const
Unboxes the value represented by the current object.
Definition: boxed_value.h:202
Template that represents wrapper of exceptions that are derived from Exception class.
Definition: exception.h:113
Forward declaration.
Definition: nullable.h:75
T get_Value() const
Returns a copy of the value represented by the current object.
Definition: nullable.h:144
bool IsNull() const
Determines if the current object represents a null-value.
Definition: nullable.h:172
Provides static methods that emulate C# Object methods called for non-Object C++ types (strings,...
Definition: object_ext.h:21
static bool Is(int32_t value)
Implements 'is' operator translation. Specialization for integer literal.
Definition: object_ext.h:605
static String ToString(const char_t *obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:96
static std::enable_if< System::IsBoxable< T >::value &&!IsNullable< T >::value &&!std::is_enum< T >::value &&detail::has_operator_equal< T >::value, bool >::type Is(const SmartPtr< Object > &obj)
Implements 'is' operator translation. Specialization for boxable types with == operator defined.
Definition: object_ext.h:466
static std::enable_if<(std::is_fundamental< To >::value), std::array< To, sizeof...(From)> >::type ArrayInitializerCast(From ...args)
Converts array fundamental values (which C# does implicitly but C++ apparently does not).
Definition: object_ext.h:734
static T0 Coalesce(System::Nullable< T0 > value, T1 func)
Implementation of '??' operator translation for nullable types.
Definition: object_ext.h:713
static std::enable_if<!std::is_enum< T >::value &&!IsNullable< T >::value, System::SmartPtr< System::Object > >::type Box(const T &value)
Boxes value types for converting to Object. Implementation for non-enum types.
Definition: object_ext.h:209
static std::enable_if< IsSmartPtr< T >::value, bool >::type Is(const SmartPtr< U > &obj)
Implements 'is' operator translation. Specialization for pointer types.
Definition: object_ext.h:418
static std::enable_if< IsSmartPtr< T >::value, String >::type ToString(const T &obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:127
static std::enable_if<!IsSmartPtr< T >::value &&!std::is_scalar< T >::value &&!IsNullable< T >::value &&!std::is_reference< T >::value, String >::type ToString(T &&obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:187
static std::enable_if<!std::is_convertible< T, Object >::value, bool >::type Is(const Object &obj)
Implements 'is' operator translation. Specialization for unconvertible types.
Definition: object_ext.h:407
static std::enable_if< std::is_enum< E >::value &&std::is_enum< T >::value, T >::type Unbox(E e)
Converts enum types.
Definition: object_ext.h:309
static bool Equals(const char_t(&obj)[N], String another)
Substitution for C# Object.Equals calls working for any type in C++. Overload for string literal with...
Definition: object_ext.h:87
static SmartPtr< System::BoxedValueBase > BoxEnum(T enumValue)
Boxes enum types for being propagated as Object.
Definition: object_ext.h:723
static SmartPtr< System::Collections::IList > CastToIList(const SmartPtr< Object > &obj)
static std::enable_if< std::is_enum< T >::value, bool >::type Is(const SmartPtr< U > &obj)
Implements 'is' operator translation. Specialization for enum types.
Definition: object_ext.h:528
static bool Is(const Nullable< U > &value)
Implements 'is' operator translation. Specialization for Nullable type.
Definition: object_ext.h:577
static std::enable_if<!IsSmartPtr< T >::value &&!std::is_scalar< T >::value &&!IsNullable< T >::value, String >::type ToString(const T &obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:177
static std::enable_if<!std::is_enum< T >::value &&!detail::has_operator_equal< T >::value, T >::type Unbox(const SmartPtr< Object > &obj)
Unboxes value types after converting to Object. Implementation for non-enum & non-nullable types.
Definition: object_ext.h:280
static std::enable_if< std::is_convertible< T, Object >::value &&std::is_final< T >::value &&!System::IsBoxable< T >::value &&System::IsSmartPtr< U >::value, bool >::type Is(const U &obj)
Implements 'is' operator translation. Specialization for pointer types optimized for 'final' classes.
Definition: object_ext.h:363
static std::enable_if< std::is_enum< T >::value, T >::type Unbox(const SmartPtr< Object > &obj)
Unboxes value types after converting to Object. Implementation for enum types.
Definition: object_ext.h:233
static std::enable_if< std::is_convertible< T, Object >::value &&!std::is_final< T >::value &&!System::IsBoxable< T >::value &&System::IsSmartPtr< U >::value, bool >::type Is(const U &obj)
Implements 'is' operator translation. Specialization for pointer types.
Definition: object_ext.h:380
static std::enable_if<!IsSmartPtr< T >::value, T >::type ObjectToUnknown(SmartPtr< Object > obj)
Converts Object to unknown type, handling both smart pointer type and boxed value situations.
Definition: object_ext.h:652
static std::enable_if<!IsSmartPtr< T >::value &&std::is_scalar< T >::value &&!std::is_enum< T >::value, String >::type ToString(T &obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:147
static auto Coalesce(T0 value, T1 func)
Implementation of '??' operator translation for non-nullable types.
Definition: object_ext.h:700
static std::enable_if< std::is_enum< E >::value &&std::numeric_limits< T >::is_integer, T >::type Unbox(E e)
Unboxes enum types to integer.
Definition: object_ext.h:298
static std::enable_if<!std::is_scalar< T >::value, bool >::type UnknownIsNull(T obj)
Checks whether unknown type object is nullptr. Overload for non-scalar types.
Definition: object_ext.h:663
static std::enable_if< std::is_scalar< T >::value, bool >::type UnknownIsNull(T obj)
Checks whether unknown type object is nullptr. Overload for scalar types.
Definition: object_ext.h:674
static std::enable_if< std::is_enum< T >::value, bool >::type Is(const WeakPtr< U > &obj)
Implements 'is' operator translation. Specialization for enum types vs weak pointers.
Definition: object_ext.h:546
static std::enable_if<!IsSmartPtr< T >::value, System::SmartPtr< Object > >::type UnknownToObject(const T &obj)
Converts unknown type to Object, handling both smart pointer type and value type situations.
Definition: object_ext.h:632
static std::enable_if< std::is_enum< T >::value, String >::type ToString(const T &obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:116
static bool Is(const char16_t *str)
Implements 'is' operator translation. Specialization for string literal.
Definition: object_ext.h:591
static std::enable_if<!IsExceptionWrapper< T >::value &&!IsSmartPtr< T >::value &&!std::is_scalar< T >::value &&!IsNullable< T >::value, String >::type ToString(T &obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:167
static std::enable_if<!IsSmartPtr< T >::value &&std::is_scalar< T >::value, bool >::type Equals(const T &obj, const T2 &another)
Substitution for C# Object.Equals calls working for any type in C++. Overload for scalar types.
Definition: object_ext.h:75
static std::enable_if< System::IsBoxable< T >::value, bool >::type Is(const T &obj)
Implements 'is' operator translation. Specialization for boxable (value) types which exactly is that ...
Definition: object_ext.h:349
static int GetHashCode(const T &obj)
Implements GetHashCode() calls; works on both Object subclasses and unrelated types.
Definition: object_ext.h:28
static std::enable_if< IsExceptionWrapper< T >::value, bool >::type Is(const ExceptionWrapper< U > &obj)
Implements 'is' operator translation. Specialization for exception wrapper types.
Definition: object_ext.h:432
static std::enable_if< System::IsBoxable< T >::value &&!IsNullable< T >::value &&!std::is_enum< T >::value &&!std::is_same< V, Object >::value, bool >::type Is(const SmartPtr< V > &obj)
Implements 'is' operator translation. Specialization value types boxed to interfaces.
Definition: object_ext.h:516
static std::enable_if< System::IsBoxable< T >::value &&!IsNullable< T >::value &&!std::is_enum< T >::value &&!detail::has_operator_equal< T >::value, bool >::type Is(const SmartPtr< Object > &obj)
Implements 'is' operator translation. Specialization for boxable types without defined ==.
Definition: object_ext.h:494
static std::conditional< std::is_convertible< RT2, RT1 >::value, RT1, RT2 >::type CoalesceInternal(RT1 value, F func)
Implementation of '??' operator translation for non-nullable types. Overload for case if RT2 is conve...
Definition: object_ext.h:687
static std::enable_if< System::IsBoxable< T >::value, System::SharedPtr< System::Object > >::type ExplicitCastToObject(const T &value)
Definition: object_ext.h:742
static std::enable_if< IsExceptionWrapper< T >::value, bool >::type Equals(const T &obj, const T2 &another)
Definition: object_ext.h:34
static std::enable_if<!IsSmartPtr< T >::value &&std::is_scalar< T >::value &&!std::is_enum< T >::value, String >::type ToString(T &&obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:157
static Nullable< T > UnboxToNullable(const SmartPtr< Object > &obj, bool safe=true)
Unboxes object to nullable type.
Definition: object_ext.h:326
static std::enable_if< IsSmartPtr< T >::value, System::SmartPtr< Object > >::type UnknownToObject(T obj)
Converts unknown type to Object, handling both smart pointer type and value type situations.
Definition: object_ext.h:622
static std::enable_if< IsNullable< T >::value, bool >::type Is(const SmartPtr< Object > &obj)
Implements 'is' operator translation. Specialization for nullable types.
Definition: object_ext.h:446
static std::enable_if< IsSmartPtr< T >::value, bool >::type Equals(const T &obj, const T2 &another)
Substitution for C# Object.Equals calls working for any type in C++. Overload for smart pointer types...
Definition: object_ext.h:49
static bool IsBoxedValue(const SmartPtr< Object > &obj)
Checks if object is a boxed value.
static String ToString(const Nullable< T > &obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:106
static std::enable_if<!std::is_enum< T >::value &&detail::has_operator_equal< T >::value, T >::type Unbox(const SmartPtr< Object > &obj)
Unboxes value types after converting to Object. Implementation for non-enum & non-nullable types.
Definition: object_ext.h:259
static std::enable_if< IsSmartPtr< T >::value, T >::type ObjectToUnknown(SmartPtr< Object > obj)
Converts Object to unknown type, handling both smart pointer type and bpxed value situations.
Definition: object_ext.h:642
static std::enable_if<!IsExceptionWrapper< T >::value &&!IsSmartPtr< T >::value &&!std::is_scalar< T >::value, bool >::type Equals(T obj, const T2 &another)
Substitution for C# Object.Equals calls working for any type in C++. Overload for structure types.
Definition: object_ext.h:62
static std::enable_if< std::is_convertible< T, Object >::value, bool >::type Is(const Object &obj)
Implements 'is' operator translation. Specialization for value types.
Definition: object_ext.h:395
static String UnboxStringSafe(const SmartPtr< Object > &obj)
Unboxes string from boxed value.
static std::enable_if< System::IsSmartPtr< T >::value, System::SharedPtr< System::Object > >::type ExplicitCastToObject(const T &value)
Definition: object_ext.h:748
static std::enable_if< std::is_enum< T >::value, System::SmartPtr< System::Object > >::type Box(const T &value)
Boxes value types for converting to Object. Implementation for enum types.
Definition: object_ext.h:198
static std::enable_if< IsNullable< T >::value, System::SmartPtr< System::Object > >::type Box(const T &value)
Boxes Nullable types for converting to Object.
Definition: object_ext.h:219
static std::enable_if< IsSmartPtr< T >::value||std::is_pointer< T >::value||IsExceptionWrapper< T >::value, String >::type ToString(T &obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:137
Base class that enables using methods available for System.Object class in C#. All non-trivial classe...
Definition: object.h:62
virtual bool Is(const TypeInfo &targetType) const
Check if object represents an instance of type described by targetType. Analog of C# 'is' operator.
Provides static methods that implement object type getters. This is a static type with no instance se...
Definition: object_type.h:26
Pointee_ * get() const
Gets pointed object.
Definition: smart_ptr.h:518
std::enable_if_t< std::is_same< Y, T >::value, SmartPtr< Y > > Cast() const
Casts pointer to its type itself.
Definition: smart_ptr.h:742
bool Is(const System::TypeInfo &target) const
Checks if pointed object is of specific type or its child type. Follows C# 'is' semantics.
Definition: object.h:875
String class used across the library. Is a substitute for C# System.String when translating code....
Definition: string.h:122
bool IsNullOrEmpty() const
Checks if string is empty or is considered null.
bool IsNull() const
Checks if string is considered null. String is null and only if it is constructed via String() constr...
Definition: string.h:285
Represents a particular type and provides information about it.
Definition: type_info.h:109
bool IsSubclassOf(const TypeInfo &type) const
Determines whether the type represented by the current object is a subclass of the specified class.
Subclass of System::SmartPtr which sets itself to weak mode at construction. Please note that this cl...
Definition: weak_ptr.h:18
@ Static
Look through static members.
@ Null
No encryption algorithm is used with a 'Null' cipher algorithm.
Definition: db_command.h:9
static auto SafeInvoke(T0 expr, T1 func)
Implementation of '?.' operator translation.
Definition: object_ext.h:1393
std::enable_if_t< Details::CastType< Source, Result >::Static, Result > AsCast(const Source &value)
Casts the source type to the result type using 'as' operator cast. Used when simple constructor-like ...
Definition: object_ext.h:1178
std::enable_if_t< Details::CastType< Source, Result >::None, Result > ExplicitCast(const Source &value)
Casts the source type to the result type using explicit cast. Used when the source and the result typ...
Definition: object_ext.h:919
class ASPOSECPP_SHARED_CLASS Array
Definition: smart_ptr.h:22
ExceptionWrapper< Details_Exception > Exception
Alias to be used instead of Details::Exception.
Definition: exception.h:369
SmartPtr< TTo > type
An alias for a pointer to an instance of TTo.
Definition: object.h:387
static String ToString(int8_t value)
Converts the specified value to its string representation.
static std::enable_if< std::is_same< T, E >::value||std::is_convertible< T, UnderlyingType >::value, String >::type GetName(T value)
Returns the name of the enumeration constant that has the specified value.
Definition: enum.h:213
static bool IsDefined(E value)
Determines whether the specified value is a member of enumeration type E.
Definition: enum.h:180
Template predicate that checks if boxing of the specified type is supported.
Definition: boxable_traits.h:16
A template predicate that determines if the specified type is a Exception class or its descendant.
Definition: object.h:405
A template predicate that determines if its template argument T in Nullable or its subclass.
Definition: nullable.h:23
Trait class to check if a type is a specialization of SmartPtr class.
Definition: smart_ptr.h:1499
Checks whether operator == exists in specified type. If so, inherits std::true_type,...
Definition: detail.h:122