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
349 template<class T, class U>
350 static typename std::enable_if<std::is_convertible<T, Object>::value && std::is_final<T>::value &&
352 bool>::type Is(const U& obj)
353 {
354 if (obj == nullptr)
355 return false;
356
357 return typeid(*obj.get()) == typeid(T);
358 }
359
366 template<class T, class U>
367 static typename std::enable_if<std::is_convertible<T, Object>::value&& !std::is_final<T>::value &&
369 bool>::type Is(const U& obj)
370 {
371 if (!obj)
372 return false;
373
374 return dynamic_cast<T*>(obj.get()) != nullptr;
375 }
376
382 template<class T>
383 static typename std::enable_if<std::is_convertible<T, Object>::value,
384 bool>::type Is(const Object& obj)
385 {
386 return obj.Is(T::Type());
387 }
388
394 template<class T>
395 static typename std::enable_if<!std::is_convertible<T, Object>::value,
396 bool>::type Is(const Object& obj)
397 {
398 return false;
399 }
400
406 template<class T, class U>
407 static typename std::enable_if<IsSmartPtr<T>::value, bool>::type Is(const SmartPtr<U>& obj)
408 {
409 if (!obj)
410 return false;
411
412 return dynamic_cast<typename T::Pointee_*>(obj.get()) != nullptr;
413 }
414
420 template<class T, class U>
421 static typename std::enable_if<IsExceptionWrapper<T>::value, bool>::type Is(const ExceptionWrapper<U>& obj)
422 {
423 if (obj == nullptr)
424 return false;
425
426 return Is<SmartPtr<typename T::ExceptionType>>(obj.Get());
427 }
428
434 template<class T>
435 static typename std::enable_if<IsNullable<T>::value, bool>::type Is(const SmartPtr<Object>& obj)
436 {
437 if (!obj)
438 return false;
439
440 if (obj->Is(System::ObjectExt::GetType<typename T::ValueType>()))
441 return true;
442
443 return false;
444 }
445
451 template<class T>
452 static typename std::enable_if<
454 bool
455 >::type Is(const SmartPtr<Object>& obj)
456 {
457 if (!obj)
458 return false;
459
460 if (obj->Is(System::ObjectExt::GetType<T>()))
461 {
462 return true;
463 }
464
465 if (obj->Is(Nullable<T>::Type()))
466 {
467 auto boxed = obj.Cast<BoxedValue<Nullable<T>>>();
468 return !boxed->unbox().IsNull();
469 }
470
471 return false;
472 }
473
479 template<class T>
480 static typename std::enable_if<
482 bool
483 >::type Is(const SmartPtr<Object>& obj)
484 {
485 if (!obj)
486 return false;
487
488 if (obj->Is(TypeInfo::BoxedValueType<T>()))
489 {
490 return true;
491 }
492
493 return false;
494 }
495
502 template <class T, class V>
503 static typename std::enable_if<
504 System::IsBoxable<T>::value && !IsNullable<T>::value && !std::is_enum<T>::value && !std::is_same<V, Object>::value,
505 bool>::type Is(const SmartPtr<V>& obj)
506 {
507 return dynamic_cast<T*>(obj.get()) != nullptr;
508 }
509
516 template<class T, class U>
517 static typename std::enable_if<std::is_enum<T>::value, bool>::type Is(const SmartPtr<U>& obj)
518 {
519 if (!obj)
520 return false;
521
522 if (obj->Is(TypeInfo::BoxedValueType<T>()))
523 return Enum<T>::IsDefined(Unbox<T>(obj));
524
525 return false;
526 }
527
534 template<class T, class U>
535 static typename std::enable_if<std::is_enum<T>::value, bool>::type Is(const WeakPtr<U>& obj)
536 {
537 if (!obj)
538 return false;
539
540 if (obj->Is(TypeInfo::BoxedValueType<T>()))
541 return Enum<T>::IsDefined(Unbox<T>(obj));
542
543 return false;
544 }
545
546private:
551 template<class T, class U>
552 static bool IsImpl()
553 {
554 TypeInfo typeU = ObjectExt::GetType<U>();
555 TypeInfo typeT = ObjectExt::GetType<T>();
556 return typeU == typeT || typeU.IsSubclassOf(typeT);
557 }
558
559public:
565 template<class T, class U>
566 static bool Is(const Nullable<U>& value)
567 {
568 if (value == nullptr)
569 return false;
570
571 return IsImpl<T, U>();
572 }
573
579 template<class T>
580 static bool Is(const char16_t* str)
581 {
582 if (str == nullptr)
583 return false;
584
585 return IsImpl<T, System::String>();
586 }
587
593 template<class T>
594 static bool Is(int32_t value)
595 {
596 ASPOSE_UNUSED(value);
597
598 return IsImpl<T, System::Int32>();
599 }
600
604 static ASPOSECPP_SHARED_API bool IsBoxedValue(const SmartPtr<Object>& obj);
605
610 template<typename T>
611 static typename std::enable_if<IsSmartPtr<T>::value, System::SmartPtr<Object> >::type UnknownToObject(T obj)
612 {
613 return obj.template Cast<Object>();
614 }
615
620 template<typename T>
621 static typename std::enable_if<!IsSmartPtr<T>::value, System::SmartPtr<Object> >::type UnknownToObject(const T& obj)
622 {
623 return Box<T>(obj);
624 }
625
630 template<typename T>
631 static typename std::enable_if<IsSmartPtr<T>::value, T>::type ObjectToUnknown(SmartPtr<Object> obj)
632 {
633 return obj.template Cast<typename T::Pointee_>();
634 }
635
640 template<typename T>
641 static typename std::enable_if<!IsSmartPtr<T>::value, T>::type ObjectToUnknown(SmartPtr<Object> obj)
642 {
643 return System::ObjectExt::Unbox<T>(obj);
644 }
645
651 template<typename T>
652 static typename std::enable_if<!std::is_scalar<T>::value, bool>::type UnknownIsNull(T obj)
653 {
654 return obj == nullptr;
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 false;
666 }
667
675 template<typename RT1, typename RT2, typename F>
676 static typename std::conditional<std::is_convertible<RT2, RT1>::value, RT1, RT2>::type CoalesceInternal(RT1 value, F func)
677 {
678 return value != nullptr ? value : func();
679 }
680
681
688 template<typename T0, typename T1>
689 static auto Coalesce(T0 value, T1 func)
690 {
691 using retval_t = System::Details::ResultOf<T1>;
692 return CoalesceInternal<T0, retval_t, typename std::function<retval_t()>>(value, func);
693 }
694
701 template<typename T0, typename T1>
702 static T0 Coalesce(System::Nullable<T0> value, T1 func)
703 {
704 return !value.IsNull() ? value.get_Value() : func();
705 }
706
711 template<typename T>
713 {
715 }
716
722 template<typename To, typename ...From>
723 static typename std::enable_if<(std::is_fundamental<To>::value), std::array<To, sizeof...(From)>>::type ArrayInitializerCast(From ...args)
724 {
725 return std::array<To, sizeof...(From)>({ static_cast<To>(args)... });
726 }
727
729
730 template<typename T>
731 static typename std::enable_if<System::IsBoxable<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
732 {
733 return ObjectExt::Box(value);
734 }
735
736 template<typename T>
737 static typename std::enable_if<System::IsSmartPtr<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
738 {
739 return value;
740 }
741};
742
748template<>
749inline bool ObjectExt::Equals<float, float>(const float& obj, const float& another)
750{
751 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
752}
753
759template<>
760inline bool ObjectExt::Equals<double, double>(const double& obj, const double& another)
761{
762 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
763}
764
768template<>
769inline SmartPtr<Object> ObjectExt::Box<String>(const String& value)
770{
771 return value.IsNull() ? nullptr : MakeObject<BoxedValue<String>>(value);
772}
773
777template<>
778inline String ObjectExt::Unbox<String>(const SmartPtr<Object>& obj)
779{
780 if (obj == nullptr)
781 return String();
782
783 if (obj && obj->Is(String::Type()))
784 {
785 auto boxed = obj.Cast<BoxedValue<String>>();
786 return boxed->unbox();
787 }
788
789 throw InvalidCastException();
790}
791
792namespace Details {
793
795template<typename T>
796struct IsObjectArray : std::false_type {};
797template <typename O>
798struct IsObjectArray<System::Array<SmartPtr<O>>> : std::is_base_of<System::Object, O> {};
799template <>
800struct IsObjectArray<System::Array<String>> : std::true_type {};
801template <typename A>
802struct IsObjectArray<SmartPtr<A>> : IsObjectArray<A> {};
803
804
808template <typename Source, typename Result>
809struct CastType
810{
812 static constexpr bool None = std::is_same<Source, Result>::value;
813
815 static constexpr bool StaticArithmetic =
816 (std::is_enum<Source>::value || std::is_arithmetic<Source>::value) &&
817 (std::is_enum<Result>::value || std::is_arithmetic<Result>::value);
819 static constexpr bool StaticIntPtr =
820 (std::is_same<Source, IntPtr>::value && (std::is_arithmetic<Result>::value || std::is_pointer<Result>::value)) ||
821 (std::is_same<Result, IntPtr>::value && (std::is_arithmetic<Source>::value || std::is_pointer<Source>::value));
823 static constexpr bool StaticString = std::is_same<Result, String>::value && std::is_constructible<String, Source>::value;
825 static constexpr bool Static = !None && (StaticArithmetic || StaticIntPtr || StaticString);
826
828 static constexpr bool Exception = !None &&
829 IsExceptionWrapper<Source>::value && IsExceptionWrapper<Result>::value &&
830 (std::is_convertible<Result, Source>::value || std::is_base_of<Result, Source>::value);
832 static constexpr bool ObjectToException = !None &&
833 std::is_same<SharedPtr<System::Object>, Source>::value && IsExceptionWrapper<Result>::value;
834
836 static constexpr bool Array = !None && IsObjectArray<Result>::value && IsObjectArray<Source>::value;
837
839 static constexpr bool ToSmartPointer = std::is_base_of<System::Object, Result>::value &&
840 !IsExceptionWrapper<Result>::value && !IsBoxable<Result>::value;
842 static constexpr bool RawPointer = ToSmartPointer && std::is_pointer<Source>::value &&
843 std::is_base_of<Object, std::remove_pointer_t<Source>>::value;
845 static constexpr bool Pointer = !None && !Array && ToSmartPointer && IsSmartPtr<Source>::value;
847 static constexpr bool PointerToPointer = !None && !Array && IsSmartPtr<Source>::value && IsSmartPtr<Result>::value;
848
850 static constexpr bool UnboxingToNullable =
851 (std::is_same<Source, SmartPtr<Object>>::value || std::is_same<Source, std::nullptr_t>::value) &&
852 IsNullable<Result>::value;
853
855 static constexpr bool InterfaceUnboxingToNullable =
856 !std::is_same<Source, SmartPtr<Object>>::value && IsSmartPtr<Source>::value && IsNullable<Result>::value;
857
859 static constexpr bool InterfaceUnboxing = !std::is_same<Source, SmartPtr<Object>>::value &&
860 IsSmartPtr<Source>::value && !IsNullable<Result>::value &&
861 std::is_base_of<Details::BoxableObjectBase, Result>::value;
862
864 static constexpr bool NullableBoxing = !UnboxingToNullable && (std::is_same<Result, Nullable<Source>>::value ||
865 (IsNullable<Result>::value && std::is_same<Source, std::nullptr_t>::value));
867 static constexpr bool NullableUnboxing = std::is_same<Source, Nullable<Result>>::value;
868
870 static constexpr bool BoxingCommon = !None && (std::is_base_of<Object, Result>::value || IsSmartPtr<Result>::value);
872 static constexpr bool EnumBoxing = BoxingCommon && std::is_enum<Source>::value;
874 static constexpr bool HeapifyBoxing = std::is_same<Result, SharedPtr<Source>>::value;
876 static constexpr bool InterfaceBoxing = BoxingCommon && !HeapifyBoxing && !std::is_same<Result, Object>::value &&
877 std::is_base_of<Details::BoxableObjectBase, Source>::value;
879 static constexpr bool Boxing = BoxingCommon && !EnumBoxing && !HeapifyBoxing && !InterfaceBoxing && IsBoxable<Source>::value;
881 static constexpr bool StringBoxing = BoxingCommon && !Boxing && !Pointer && !std::is_same<Source, std::nullptr_t>::value &&
882 std::is_constructible<String, Source>::value;
883
885 static constexpr bool Unboxing =
886 !UnboxingToNullable && !InterfaceUnboxing && IsSmartPtr<Source>::value && IsBoxable<Result>::value;
887
889 static constexpr bool UnboxingToString = std::is_same<Result, String>::value && std::is_same<Source, SmartPtr<Object>>::value;
890
892 static constexpr bool Null = !Static && !UnboxingToNullable && !NullableBoxing &&
893 std::is_same<Source, std::nullptr_t>::value;
894
896 static constexpr bool InvalidUnboxing = Unboxing && !InterfaceUnboxingToNullable && !InterfaceUnboxing && !std::is_same<Source, SmartPtr<Object>>::value;
897};
898
899} // namespace Details
900
907template <typename Result, typename Source>
908std::enable_if_t<Details::CastType<Source, Result>::None, Result> ExplicitCast(const Source& value)
909{
910 return value;
911}
912
919template <typename Result, typename Source>
920std::enable_if_t<Details::CastType<Source, Result>::Static, Result> ExplicitCast(const Source& value)
921{
922 return Result(value);
923}
924
932template <typename Result, typename Source>
933std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> ExplicitCast(const Source& value)
934{
935 return value.Get().template Cast<typename Result::ExceptionType, std::true_type>() ? Result(value.Get())
936 : Result(nullptr);
937}
938
946template <typename Result, typename Source>
947std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> ExplicitCast(const Source& value)
948{
949 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::true_type>();
950 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::true_type>())
951 : Result(nullptr);
952}
953
961template <typename Result, typename Source>
962std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
963 ExplicitCast(const Source& value)
964{
965 return value.template Cast<Result, std::true_type>();
966}
967
975template <typename Result, typename Source>
976std::enable_if_t<Details::CastType<Source, Result>::RawPointer, typename CastResult<std::remove_pointer_t<Result>>::type>
977 ExplicitCast(Source value)
978{
979 return ExplicitCast<Result>(SmartPtr<std::remove_pointer_t<Source>>(value));
980}
981
989template <typename Result, typename Source>
990std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
991 ExplicitCast(const Source& value)
992{
993 return ExplicitCast<typename Result::Pointee_>(value);
994}
995
1003template <typename Result, typename Source>
1004std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1005 ExplicitCast(const Source& value)
1006{
1007 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, false);
1008}
1009
1016template <typename Result, typename Source>
1017std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> ExplicitCast(const Source& value)
1018{
1019 return Result(value);
1020}
1021
1029template <typename Result, typename Source>
1030std::enable_if_t<Details::CastType<Source, Result>::NullableUnboxing, Result> ExplicitCast(const Source& value)
1031{
1032 if (value == nullptr)
1033 throw NullReferenceException(u"Can not unbox null value");
1034
1035 return static_cast<Result>(value);
1036}
1037
1044template <typename Result, typename Source>
1045std::enable_if_t<Details::CastType<Source, Result>::EnumBoxing, SmartPtr<BoxedValueBase>>
1046 ExplicitCast(const Source& value)
1047{
1048 return ObjectExt::BoxEnum(value);
1049}
1050
1058template <typename Result, typename Source>
1059std::enable_if_t<Details::CastType<Source, Result>::HeapifyBoxing, typename CastResult<Result>::type>
1060 ExplicitCast(const Source& value)
1061{
1062 return MakeObject<Source>(value).template Cast<typename Result::Pointee_, std::true_type>();
1063}
1064
1071template <typename Result, typename Source>
1072std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1073 ExplicitCast(const Source& value)
1074{
1075 return MakeObject<Source>(value).template Cast<Result, std::true_type>();
1076}
1077
1084template <typename Result, typename Source>
1085std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1086 ExplicitCast(const Source& value)
1087{
1088 return ObjectExt::Box(value);
1089}
1090
1097template <typename Result, typename Source>
1098std::enable_if_t<Details::CastType<Source, Result>::StringBoxing, typename CastResult<Result>::type>
1099 ExplicitCast(const Source& value)
1100{
1101 return ObjectExt::Box<String>(value);
1102}
1103
1110template <typename Result, typename Source>
1111std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxing, Result> ExplicitCast(const Source& value)
1112{
1113 return *(value.template Cast<Result, std::true_type>());
1114}
1115
1122template <typename Result, typename Source>
1123std::enable_if_t<Details::CastType<Source, Result>::Unboxing, Result> ExplicitCast(const Source& value)
1124{
1125 return ObjectExt::Unbox<Result>(value);
1126}
1127
1134template <typename Result, typename Source>
1135std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1136{
1137 return typename CastResult<Result>::type(nullptr);
1138}
1139
1147template <typename Result, typename Source>
1148std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1149{
1150 if (!value)
1151 return nullptr;
1152
1153 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1154 std::transform(value->data().begin(), value->data().end(), result->data().begin(),
1155 [](const auto& value) {return ExplicitCast<typename Result::ValueType>(value);});
1156
1157 return result;
1158}
1159
1166template <typename Result, typename Source>
1167std::enable_if_t<Details::CastType<Source, Result>::Static, Result> AsCast(const Source& value)
1168{
1169 return Result(value);
1170}
1171
1178template <typename Result, typename Source>
1179std::enable_if_t<Details::CastType<Source, Result>::None, Result> AsCast(const Source& value)
1180{
1181 return value;
1182}
1183
1190template <typename Result, typename Source>
1191std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> AsCast(const Source& value)
1192{
1193 return value.Get().template Cast<typename Result::ExceptionType, std::false_type>() ? Result(value.Get())
1194 : Result(nullptr);
1195}
1196
1203template <typename Result, typename Source>
1204std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> AsCast(const Source& value)
1205{
1206 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::false_type>();
1207 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::false_type>())
1208 : Result(nullptr);
1209}
1210
1217template <typename Result, typename Source>
1218std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
1219 AsCast(const Source& value)
1220{
1221 return value.template Cast<Result, std::false_type>();
1222}
1223
1230template <typename Result, typename Source>
1231std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
1232 AsCast(const Source& value)
1233{
1234 return AsCast<typename Result::Pointee_>(value);
1235}
1236
1243template <typename Result, typename Source>
1244std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1245 AsCast(const Source& value)
1246{
1247 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, true);
1248}
1249
1256template <typename Result, typename Source>
1257std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxingToNullable, Result> AsCast(const Source& value)
1258{
1259 Result result;
1260 if (ObjectExt::Is<typename Result::ValueType>(value))
1261 {
1262 result = *(value.template Cast<typename Result::ValueType, std::false_type>());
1263 }
1264 return result;
1265}
1266
1272template <typename Result, typename Source>
1273std::enable_if_t<Details::CastType<Source, Result>::InvalidUnboxing, Result> AsCast(const Source& value)
1274{
1275 return Default<Result>();
1276}
1277
1284template <typename Result, typename Source>
1285std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> AsCast(const Source& value)
1286{
1287 return Result(value);
1288}
1289
1296template <typename Result, typename Source>
1297std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1298 AsCast(const Source& value)
1299{
1300 if (!ObjectExt::Is<Result>(value))
1301 {
1302 return nullptr;
1303 }
1304
1305 return MakeObject<Source>(value).template Cast<Result, std::false_type>();
1306}
1307
1314template <typename Result, typename Source>
1315std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1316 AsCast(const Source& value)
1317{
1318 return ObjectExt::Box(value).template Cast<typename Result::Pointee_, std::false_type>();
1319}
1320
1327template <typename Result, typename Source>
1328std::enable_if_t<Details::CastType<Source, Result>::UnboxingToString, Result> AsCast(const Source& value)
1329{
1330 return ObjectExt::UnboxStringSafe(value);
1331}
1332
1339template <typename Result, typename Source>
1340std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> AsCast(const Source& value)
1341{
1342 return typename CastResult<Result>::type(nullptr);
1343}
1344
1351template <typename Result, typename Source>
1352std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> AsCast(const Source& value)
1353{
1354 if (!value)
1355 return nullptr;
1356
1357 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1358 auto d_it = result->data().begin();
1359 auto s_it = value->data().begin();
1360 while (s_it != value->data().end())
1361 {
1362 auto& source_element = *(s_it++);
1363 auto& result_element = *(d_it++);
1364
1365 result_element = AsCast<typename Result::ValueType>(source_element);
1366
1367 // Fail entire cast if any element fails
1368 if (source_element != nullptr && result_element == nullptr)
1369 return nullptr;
1370 }
1371
1372 return result;
1373}
1374
1381template <typename T0, typename T1>
1382static auto SafeInvoke(T0 expr, T1 func)
1383{
1384 // The type which 'func' actually returns
1385 using retval_t = System::Details::ResultOf<T1, T0>;
1386
1387 // The type which function SafeInvoke will return. Non-nullable types will be wrapped by 'Nullable<>' class template.
1388 using result_t = typename std::conditional<
1389 std::is_base_of<Details::BoxableObjectBase, retval_t>::value || std::is_arithmetic<retval_t>::value || std::is_enum<retval_t>::value,
1391 retval_t>::type;
1392
1393 return expr != nullptr ? result_t(func(expr)) : result_t(nullptr);
1394}
1395
1403template <class PatternT, class ExpressionT, class ResultT>
1404bool IsDeclaration(const ExpressionT& left, ResultT& result)
1405{
1406 if (ObjectExt::Is<PatternT>(left))
1407 {
1408 result = ExplicitCast<PatternT>(left);
1409 return true;
1410 }
1411 else
1412 {
1413 return false;
1414 }
1415}
1416
1423template <class ExpressionT, class ConstantT>
1424bool IsConstant(const ExpressionT& left, const ConstantT& constant)
1425{
1426 if (ObjectExt::Is<ConstantT>(left))
1427 {
1428 return Equals(constant, ExplicitCast<ConstantT>(left));
1429 }
1430 else
1431 {
1432 return false;
1433 }
1434}
1435
1436} // 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:594
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:455
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:723
static T0 Coalesce(System::Nullable< T0 > value, T1 func)
Implementation of '??' operator translation for nullable types.
Definition: object_ext.h:702
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:407
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:396
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:712
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:517
static bool Is(const Nullable< U > &value)
Implements 'is' operator translation. Specialization for Nullable type.
Definition: object_ext.h:566
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:352
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:369
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:641
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:689
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:652
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:663
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:535
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:621
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:580
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 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:421
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:505
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:483
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:676
static std::enable_if< System::IsBoxable< T >::value, System::SharedPtr< System::Object > >::type ExplicitCastToObject(const T &value)
Definition: object_ext.h:731
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:611
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:435
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:631
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:384
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:737
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:847
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
bool IsDeclaration(const ExpressionT &left, ResultT &result)
Implements 'is' declaration pattern translation.
Definition: object_ext.h:1404
bool Equals(const TA &a, const TB &b)
Determines the equality of two values applying operator==() to them.
Definition: primitive_types.h:77
static auto SafeInvoke(T0 expr, T1 func)
Implementation of '?.' operator translation.
Definition: object_ext.h:1382
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:1167
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:908
class ASPOSECPP_SHARED_CLASS Array
Definition: smart_ptr.h:22
bool IsConstant(const ExpressionT &left, const ConstantT &constant)
Implements 'is' constant pattern translation.
Definition: object_ext.h:1424
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