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
724 template <typename T0, typename T1>
725 static auto CoalesceAssign(T0& value, T1 func) -> T0&
726 {
727 if (value == nullptr)
728 {
729 value = func();
730 }
731 return value;
732 }
733
738 template<typename T>
740 {
742 }
743
749 template<typename To, typename ...From>
750 static typename std::enable_if<(std::is_fundamental<To>::value), std::array<To, sizeof...(From)>>::type ArrayInitializerCast(From ...args)
751 {
752 return std::array<To, sizeof...(From)>({ static_cast<To>(args)... });
753 }
754
756
757 template<typename T>
758 static typename std::enable_if<System::IsBoxable<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
759 {
760 return ObjectExt::Box(value);
761 }
762
763 template<typename T>
764 static typename std::enable_if<System::IsSmartPtr<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
765 {
766 return value;
767 }
768};
769
775template<>
776inline bool ObjectExt::Equals<float, float>(const float& obj, const float& another)
777{
778 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
779}
780
786template<>
787inline bool ObjectExt::Equals<double, double>(const double& obj, const double& another)
788{
789 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
790}
791
795template<>
796inline SmartPtr<Object> ObjectExt::Box<String>(const String& value)
797{
798 return value.IsNull() ? nullptr : MakeObject<BoxedValue<String>>(value);
799}
800
804template<>
805inline String ObjectExt::Unbox<String>(const SmartPtr<Object>& obj)
806{
807 if (obj == nullptr)
808 return String();
809
810 if (obj && obj->Is(String::Type()))
811 {
812 auto boxed = obj.Cast<BoxedValue<String>>();
813 return boxed->unbox();
814 }
815
816 throw InvalidCastException();
817}
818
819namespace Details {
820
822template<typename T>
823struct IsObjectArray : std::false_type {};
824template <typename O>
825struct IsObjectArray<System::Array<SmartPtr<O>>> : std::is_base_of<System::Object, O> {};
826template <>
827struct IsObjectArray<System::Array<String>> : std::true_type {};
828template <typename A>
829struct IsObjectArray<SmartPtr<A>> : IsObjectArray<A> {};
830
831
835template <typename Source, typename Result>
836struct CastType
837{
839 static constexpr bool None = std::is_same<Source, Result>::value;
840
842 static constexpr bool StaticArithmetic =
843 (std::is_enum<Source>::value || std::is_arithmetic<Source>::value) &&
844 (std::is_enum<Result>::value || std::is_arithmetic<Result>::value);
846 static constexpr bool StaticIntPtr =
847 (std::is_same<Source, IntPtr>::value && (std::is_arithmetic<Result>::value || std::is_pointer<Result>::value)) ||
848 (std::is_same<Result, IntPtr>::value && (std::is_arithmetic<Source>::value || std::is_pointer<Source>::value));
850 static constexpr bool StaticString = std::is_same<Result, String>::value && std::is_constructible<String, Source>::value;
852 static constexpr bool Static = !None && (StaticArithmetic || StaticIntPtr || StaticString);
853
855 static constexpr bool Exception = !None &&
856 IsExceptionWrapper<Source>::value && IsExceptionWrapper<Result>::value &&
857 (std::is_convertible<Result, Source>::value || std::is_base_of<Result, Source>::value);
859 static constexpr bool ObjectToException = !None &&
860 std::is_same<SharedPtr<System::Object>, Source>::value && IsExceptionWrapper<Result>::value;
861
863 static constexpr bool Array = !None && IsObjectArray<Result>::value && IsObjectArray<Source>::value;
864
866 static constexpr bool ToSmartPointer = std::is_base_of<System::Object, Result>::value &&
867 !IsExceptionWrapper<Result>::value && !IsBoxable<Result>::value;
869 static constexpr bool RawPointer = ToSmartPointer && std::is_pointer<Source>::value &&
870 std::is_base_of<Object, std::remove_pointer_t<Source>>::value;
872 static constexpr bool Pointer = !None && !Array && ToSmartPointer && IsSmartPtr<Source>::value;
874 static constexpr bool PointerToPointer = !None && !Array && IsSmartPtr<Source>::value && IsSmartPtr<Result>::value;
875
877 static constexpr bool UnboxingToNullable =
878 (std::is_same<Source, SmartPtr<Object>>::value || std::is_same<Source, std::nullptr_t>::value) &&
879 IsNullable<Result>::value;
880
882 static constexpr bool InterfaceUnboxingToNullable =
883 !std::is_same<Source, SmartPtr<Object>>::value && IsSmartPtr<Source>::value && IsNullable<Result>::value;
884
886 static constexpr bool InterfaceUnboxing = !std::is_same<Source, SmartPtr<Object>>::value &&
887 IsSmartPtr<Source>::value && !IsNullable<Result>::value &&
888 std::is_base_of<Details::BoxableObjectBase, Result>::value;
889
891 static constexpr bool NullableBoxing = !UnboxingToNullable && (std::is_same<Result, Nullable<Source>>::value ||
892 (IsNullable<Result>::value && std::is_same<Source, std::nullptr_t>::value));
894 static constexpr bool NullableUnboxing = std::is_same<Source, Nullable<Result>>::value;
895
897 static constexpr bool BoxingCommon = !None && (std::is_base_of<Object, Result>::value || IsSmartPtr<Result>::value);
899 static constexpr bool EnumBoxing = BoxingCommon && std::is_enum<Source>::value;
901 static constexpr bool HeapifyBoxing = std::is_same<Result, SharedPtr<Source>>::value;
903 static constexpr bool InterfaceBoxing = BoxingCommon && !HeapifyBoxing && !std::is_same<Result, Object>::value &&
904 std::is_base_of<Details::BoxableObjectBase, Source>::value;
906 static constexpr bool Boxing = BoxingCommon && !EnumBoxing && !HeapifyBoxing && !InterfaceBoxing && IsBoxable<Source>::value;
908 static constexpr bool StringBoxing = BoxingCommon && !Boxing && !Pointer && !std::is_same<Source, std::nullptr_t>::value &&
909 std::is_constructible<String, Source>::value;
910
912 static constexpr bool Unboxing =
913 !UnboxingToNullable && !InterfaceUnboxing && IsSmartPtr<Source>::value && IsBoxable<Result>::value;
914
916 static constexpr bool UnboxingToString = std::is_same<Result, String>::value && std::is_same<Source, SmartPtr<Object>>::value;
917
919 static constexpr bool Null = !Static && !UnboxingToNullable && !NullableBoxing &&
920 std::is_same<Source, std::nullptr_t>::value;
921
923 static constexpr bool InvalidUnboxing = Unboxing && !InterfaceUnboxingToNullable && !InterfaceUnboxing && !std::is_same<Source, SmartPtr<Object>>::value;
924};
925
926} // namespace Details
927
934template <typename Result, typename Source>
935std::enable_if_t<Details::CastType<Source, Result>::None, Result> ExplicitCast(const Source& value)
936{
937 return value;
938}
939
946template <typename Result, typename Source>
947std::enable_if_t<Details::CastType<Source, Result>::Static, Result> ExplicitCast(const Source& value)
948{
949 return Result(value);
950}
951
959template <typename Result, typename Source>
960std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> ExplicitCast(const Source& value)
961{
962 return value.Get().template Cast<typename Result::ExceptionType, std::true_type>() ? Result(value.Get())
963 : Result(nullptr);
964}
965
973template <typename Result, typename Source>
974std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> ExplicitCast(const Source& value)
975{
976 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::true_type>();
977 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::true_type>())
978 : Result(nullptr);
979}
980
988template <typename Result, typename Source>
989std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
990 ExplicitCast(const Source& value)
991{
992 return value.template Cast<Result, std::true_type>();
993}
994
1002template <typename Result, typename Source>
1003std::enable_if_t<Details::CastType<Source, Result>::RawPointer, typename CastResult<std::remove_pointer_t<Result>>::type>
1004 ExplicitCast(Source value)
1005{
1006 return ExplicitCast<Result>(SmartPtr<std::remove_pointer_t<Source>>(value));
1007}
1008
1016template <typename Result, typename Source>
1017std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
1018 ExplicitCast(const Source& value)
1019{
1020 return ExplicitCast<typename Result::Pointee_>(value);
1021}
1022
1030template <typename Result, typename Source>
1031std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1032 ExplicitCast(const Source& value)
1033{
1034 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, false);
1035}
1036
1043template <typename Result, typename Source>
1044std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> ExplicitCast(const Source& value)
1045{
1046 return Result(value);
1047}
1048
1056template <typename Result, typename Source>
1057std::enable_if_t<Details::CastType<Source, Result>::NullableUnboxing, Result> ExplicitCast(const Source& value)
1058{
1059 if (value == nullptr)
1060 throw NullReferenceException(u"Can not unbox null value");
1061
1062 return static_cast<Result>(value);
1063}
1064
1071template <typename Result, typename Source>
1072std::enable_if_t<Details::CastType<Source, Result>::EnumBoxing, SmartPtr<BoxedValueBase>>
1073 ExplicitCast(const Source& value)
1074{
1075 return ObjectExt::BoxEnum(value);
1076}
1077
1085template <typename Result, typename Source>
1086std::enable_if_t<Details::CastType<Source, Result>::HeapifyBoxing, typename CastResult<Result>::type>
1087 ExplicitCast(const Source& value)
1088{
1089 return MakeObject<Source>(value).template Cast<typename Result::Pointee_, std::true_type>();
1090}
1091
1098template <typename Result, typename Source>
1099std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1100 ExplicitCast(const Source& value)
1101{
1102 return MakeObject<Source>(value).template Cast<Result, std::true_type>();
1103}
1104
1111template <typename Result, typename Source>
1112std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1113 ExplicitCast(const Source& value)
1114{
1115 return ObjectExt::Box(value);
1116}
1117
1124template <typename Result, typename Source>
1125std::enable_if_t<Details::CastType<Source, Result>::StringBoxing, typename CastResult<Result>::type>
1126 ExplicitCast(const Source& value)
1127{
1128 return ObjectExt::Box<String>(value);
1129}
1130
1137template <typename Result, typename Source>
1138std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxing, Result> ExplicitCast(const Source& value)
1139{
1140 return *(value.template Cast<Result, std::true_type>());
1141}
1142
1149template <typename Result, typename Source>
1150std::enable_if_t<Details::CastType<Source, Result>::Unboxing, Result> ExplicitCast(const Source& value)
1151{
1152 return ObjectExt::Unbox<Result>(value);
1153}
1154
1161template <typename Result, typename Source>
1162std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1163{
1164 return typename CastResult<Result>::type(nullptr);
1165}
1166
1174template <typename Result, typename Source>
1175std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1176{
1177 if (!value)
1178 return nullptr;
1179
1180 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1181 std::transform(value->data().begin(), value->data().end(), result->data().begin(),
1182 [](const auto& value) {return ExplicitCast<typename Result::ValueType>(value);});
1183
1184 return result;
1185}
1186
1193template <typename Result, typename Source>
1194std::enable_if_t<Details::CastType<Source, Result>::Static, Result> AsCast(const Source& value)
1195{
1196 return Result(value);
1197}
1198
1205template <typename Result, typename Source>
1206std::enable_if_t<Details::CastType<Source, Result>::None, Result> AsCast(const Source& value)
1207{
1208 return value;
1209}
1210
1217template <typename Result, typename Source>
1218std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> AsCast(const Source& value)
1219{
1220 return value.Get().template Cast<typename Result::ExceptionType, std::false_type>() ? Result(value.Get())
1221 : Result(nullptr);
1222}
1223
1230template <typename Result, typename Source>
1231std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> AsCast(const Source& value)
1232{
1233 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::false_type>();
1234 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::false_type>())
1235 : Result(nullptr);
1236}
1237
1244template <typename Result, typename Source>
1245std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
1246 AsCast(const Source& value)
1247{
1248 return value.template Cast<Result, std::false_type>();
1249}
1250
1257template <typename Result, typename Source>
1258std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
1259 AsCast(const Source& value)
1260{
1261 return AsCast<typename Result::Pointee_>(value);
1262}
1263
1270template <typename Result, typename Source>
1271std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1272 AsCast(const Source& value)
1273{
1274 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, true);
1275}
1276
1283template <typename Result, typename Source>
1284std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxingToNullable, Result> AsCast(const Source& value)
1285{
1286 Result result;
1287 if (ObjectExt::Is<typename Result::ValueType>(value))
1288 {
1289 result = *(value.template Cast<typename Result::ValueType, std::false_type>());
1290 }
1291 return result;
1292}
1293
1299template <typename Result, typename Source>
1300std::enable_if_t<Details::CastType<Source, Result>::InvalidUnboxing, Result> AsCast(const Source& value)
1301{
1302 return Default<Result>();
1303}
1304
1311template <typename Result, typename Source>
1312std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> AsCast(const Source& value)
1313{
1314 return Result(value);
1315}
1316
1323template <typename Result, typename Source>
1324std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1325 AsCast(const Source& value)
1326{
1327 if (!ObjectExt::Is<Result>(value))
1328 {
1329 return nullptr;
1330 }
1331
1332 return MakeObject<Source>(value).template Cast<Result, std::false_type>();
1333}
1334
1341template <typename Result, typename Source>
1342std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1343 AsCast(const Source& value)
1344{
1345 return ObjectExt::Box(value).template Cast<typename Result::Pointee_, std::false_type>();
1346}
1347
1354template <typename Result, typename Source>
1355std::enable_if_t<Details::CastType<Source, Result>::UnboxingToString, Result> AsCast(const Source& value)
1356{
1357 return ObjectExt::UnboxStringSafe(value);
1358}
1359
1366template <typename Result, typename Source>
1367std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> AsCast(const Source& value)
1368{
1369 return typename CastResult<Result>::type(nullptr);
1370}
1371
1378template <typename Result, typename Source>
1379std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> AsCast(const Source& value)
1380{
1381 if (!value)
1382 return nullptr;
1383
1384 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1385 auto d_it = result->data().begin();
1386 auto s_it = value->data().begin();
1387 while (s_it != value->data().end())
1388 {
1389 auto& source_element = *(s_it++);
1390 auto& result_element = *(d_it++);
1391
1392 result_element = AsCast<typename Result::ValueType>(source_element);
1393
1394 // Fail entire cast if any element fails
1395 if (source_element != nullptr && result_element == nullptr)
1396 return nullptr;
1397 }
1398
1399 return result;
1400}
1401
1408template <typename T0, typename T1>
1409static auto SafeInvoke(T0 expr, T1 func)
1410{
1411 // The type which 'func' actually returns
1412 using retval_t = System::Details::ResultOf<T1, T0>;
1413
1414 // The type which function SafeInvoke will return. Non-nullable types will be wrapped by 'Nullable<>' class template.
1415 using result_t = typename std::conditional<
1416 std::is_base_of<Details::BoxableObjectBase, retval_t>::value || std::is_arithmetic<retval_t>::value || std::is_enum<retval_t>::value,
1418 retval_t>::type;
1419
1420 return expr != nullptr ? result_t(func(expr)) : result_t(nullptr);
1421}
1422
1423} // 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:180
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:750
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:739
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 auto CoalesceAssign(T0 &value, T1 func) -> T0 &
Implementation of '??=' operator translation.
Definition: object_ext.h:725
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:758
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:764
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:1409
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:1194
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:935
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