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; }
13template <typename> class ReadOnlySpan;
14}
15
16namespace System
17{
18
22class ObjectExt : public ObjectType
23{
24public:
29 template <typename T>
30 static int GetHashCode(const T& obj)
31 {
32 return System::GetHashCode<T>(obj);
33 }
34
35 template<typename T, typename T2>
36 static typename std::enable_if<IsExceptionWrapper<T>::value, bool>::type Equals(const T& obj, const T2& another)
37 {
38 if (obj.IsNull())
39 System::Detail::SmartPtrCounter::ThrowNullReferenceException();
40 return obj.Equals(another);
41 }
42
50 template<typename T, typename T2>
51 static typename std::enable_if<IsSmartPtr<T>::value, bool>::type Equals(const T& obj, const T2& another)
52 {
53 return obj->Equals(another);
54 }
55
63 template<typename T, typename T2>
64 static typename std::enable_if<!IsExceptionWrapper<T>::value && !IsSmartPtr<T>::value && !std::is_scalar<T>::value, bool>::type Equals(T obj, const T2& another)
65 {
66 return obj.Equals(another);
67 }
68
76 template<typename T, typename T2>
77 static typename std::enable_if<!IsSmartPtr<T>::value && std::is_scalar<T>::value, bool>::type Equals(const T& obj, const T2& another)
78 {
79 return (obj == another);
80 }
81
88 template<size_t N>
89 static bool Equals(const char_t (&obj)[N], String another)
90 {
91 return another == obj;
92 }
93
95 inline static bool Equals(const System::String& obj, const System::String& another)
96 {
97 return obj == nullptr && another == nullptr || obj != nullptr && another != nullptr && obj.Equals(another);
98 }
99
103 static inline String ToString(const char_t * obj)
104 {
105 return String(obj);
106 }
107
112 template<typename T>
113 static inline String ToString(const Nullable<T> & obj)
114 {
115 return (obj.IsNull() ? u"" : ToString(obj.get_Value()));
116 }
117
122 template<typename T>
123 static typename std::enable_if<std::is_enum<T>::value, String>::type ToString(const T& obj)
124 {
125 String str = Enum<T>::GetName(obj);
126 return !str.IsNullOrEmpty() ? str : System::Convert::ToString(static_cast<typename std::underlying_type<T>::type>(obj));
127 }
128
133 template<typename T>
134 static typename std::enable_if<IsSmartPtr<T>::value, String>::type ToString(const T& obj)
135 {
136 return obj->ToString();
137 }
138
143 template<typename T>
144 static typename std::enable_if<IsSmartPtr<T>::value || std::is_pointer<T>::value || IsExceptionWrapper<T>::value, String>::type ToString(T& obj)
145 {
146 return obj->ToString();
147 }
148
153 template<typename T>
154 static typename std::enable_if<!IsSmartPtr<T>::value && std::is_scalar<T>::value && !std::is_enum<T>::value, String>::type ToString(T& obj)
155 {
156 return System::Convert::ToString(obj);
157 }
158
163 template<typename T>
164 static typename std::enable_if<!IsSmartPtr<T>::value && std::is_scalar<T>::value && !std::is_enum<T>::value, String>::type ToString(T&& obj)
165 {
166 return System::Convert::ToString(obj);
167 }
168
173 template<typename T>
174 static typename std::enable_if<!IsExceptionWrapper<T>::value && !IsSmartPtr<T>::value && !std::is_scalar<T>::value && !IsNullable<T>::value, String>::type ToString(T& obj)
175 {
176 return obj.ToString();
177 }
178
183 template <typename T>
184 static typename std::enable_if<!IsSmartPtr<T>::value && !std::is_scalar<T>::value && !IsNullable<T>::value, String>::type ToString(const T& obj)
185 {
186 return obj.ToString();
187 }
188
193 template<typename T>
194 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)
195 {
196 return obj.ToString();
197 }
198
204 template<typename T>
205 static typename std::enable_if<std::is_enum<T>::value, System::SmartPtr<System::Object>>::type Box(const T& value)
206 {
207 return System::MakeObject<BoxedEnum<T>>(value);
208 }
209
215 template<typename T>
216 static typename std::enable_if<!std::is_enum<T>::value && !IsNullable<T>::value, System::SmartPtr<System::Object>>::type Box(const T& value)
217 {
218 return System::MakeObject<BoxedValue<T>>(value);
219 }
220
225 template<typename T>
226 static typename std::enable_if <IsNullable<T>::value, System::SmartPtr<System::Object>>::type Box(const T& value)
227 {
228 if (value == nullptr)
229 return nullptr;
230
231 return System::MakeObject<BoxedValue<typename T::ValueType>>(value.get_Value());
232 }
233
239 template<typename T>
240 static typename std::enable_if<std::is_enum<T>::value, T>::type Unbox(const SmartPtr<Object>& obj)
241 {
242 using UT = typename std::underlying_type<T>::type;
243
244 if (obj && obj->Is(BoxedEnum<T>::Type()))
245 {
246 auto boxed = obj.template Cast<BoxedEnum<T>>();
247 return static_cast<T>(boxed->unbox());
248 }
249 using UT = typename std::underlying_type<T>::type;
250 if (obj && obj->Is(ObjectExt::GetType<UT>()))
251 {
252 auto boxed = obj.Cast<BoxedValue<UT>>();
253 return static_cast<T>(boxed->unbox());
254 }
255
256
257 throw InvalidCastException();
258 }
259
265 template<class T>
266 static typename std::enable_if<!std::is_enum<T>::value && detail::has_operator_equal<T>::value, T>::type Unbox(const SmartPtr<Object>& obj)
267 {
268 if (obj)
269 {
270 if (obj->Is(ObjectExt::GetType<T>()))
271 {
272 auto boxed = obj.template Cast<BoxedValue<T>>();
273 return boxed->unbox();
274 }
275
276 throw InvalidCastException();
277 }
278 throw NullReferenceException();
279 }
280
286 template<class T>
287 static typename std::enable_if<!std::is_enum<T>::value && !detail::has_operator_equal<T>::value, T>::type Unbox(const SmartPtr<Object>& obj)
288 {
289
290 if (obj && obj->Is(BoxedValue<T>::Type()))
291 {
292 auto boxed = obj.template Cast<BoxedValue<T>>();
293 return boxed->unbox();
294 }
295
296 throw InvalidCastException();
297 }
298
304 template<class T, class E>
305 static typename std::enable_if<std::is_enum<E>::value && std::numeric_limits<T>::is_integer, T>::type Unbox(E e)
306 {
307 return static_cast<T>(e);
308 }
309
315 template<class T, class E>
316 static typename std::enable_if<std::is_enum<E>::value && std::is_enum<T>::value, T>::type Unbox(E e)
317 {
318 return static_cast<T>(e);
319 }
320
325 static ASPOSECPP_SHARED_API String UnboxStringSafe(const SmartPtr<Object>& obj);
326
332 template<class T>
333 static Nullable<T> UnboxToNullable(const SmartPtr<Object>& obj, bool safe = true)
334 {
335 if (obj)
336 {
337 if (obj->Is(ObjectExt::GetType<T>()))
338 {
339 auto boxed = obj.template Cast<BoxedValue<T>>();
340 return Nullable<T>(boxed->unbox());
341 }
342 }
343
344 if (!obj || safe)
345 return Nullable<T>(nullptr);
346
347 throw InvalidCastException();
348 }
349
355 template <class T>
356 static typename std::enable_if<System::IsBoxable<T>::value, bool>::type Is(const T& obj)
357 {
358 return true;
359 }
360
367 template<class T, class U>
368 static typename std::enable_if<std::is_convertible<T, Object>::value && std::is_final<T>::value &&
370 bool>::type Is(const U& obj)
371 {
372 if (obj == nullptr)
373 return false;
374
375 return typeid(*obj.get()) == typeid(T);
376 }
377
384 template<class T, class U>
385 static typename std::enable_if<std::is_convertible<T, Object>::value&& !std::is_final<T>::value &&
387 bool>::type Is(const U& obj)
388 {
389 if (!obj)
390 return false;
391
392 return dynamic_cast<T*>(obj.get()) != nullptr;
393 }
394
400 template<class T>
401 static typename std::enable_if<std::is_convertible<T, Object>::value,
402 bool>::type Is(const Object& obj)
403 {
404 return obj.Is(T::Type());
405 }
406
412 template<class T>
413 static typename std::enable_if<!std::is_convertible<T, Object>::value,
414 bool>::type Is(const Object& obj)
415 {
416 return false;
417 }
418
424 template<class T, class U>
425 static typename std::enable_if<IsSmartPtr<T>::value, bool>::type Is(const SmartPtr<U>& obj)
426 {
427 if (!obj)
428 return false;
429
430 return dynamic_cast<typename T::Pointee_*>(obj.get()) != nullptr;
431 }
432
438 template<class T, class U>
439 static typename std::enable_if<IsExceptionWrapper<T>::value, bool>::type Is(const ExceptionWrapper<U>& obj)
440 {
441 if (obj == nullptr)
442 return false;
443
444 return Is<SmartPtr<typename T::ExceptionType>>(obj.Get());
445 }
446
452 template<class T>
453 static typename std::enable_if<IsNullable<T>::value, bool>::type Is(const SmartPtr<Object>& obj)
454 {
455 if (!obj)
456 return false;
457
458 if (obj->Is(System::ObjectExt::GetType<typename T::ValueType>()))
459 return true;
460
461 return false;
462 }
463
469 template<class T>
470 static typename std::enable_if<
472 bool
473 >::type Is(const SmartPtr<Object>& obj)
474 {
475 if (!obj)
476 return false;
477
478 if (obj->Is(System::ObjectExt::GetType<T>()))
479 {
480 return true;
481 }
482
483 if (obj->Is(Nullable<T>::Type()))
484 {
485 auto boxed = obj.Cast<BoxedValue<Nullable<T>>>();
486 return !boxed->unbox().IsNull();
487 }
488
489 return false;
490 }
491
497 template<class T>
498 static typename std::enable_if<
500 bool
501 >::type Is(const SmartPtr<Object>& obj)
502 {
503 if (!obj)
504 return false;
505
506 if (obj->Is(TypeInfo::BoxedValueType<T>()))
507 {
508 return true;
509 }
510
511 return false;
512 }
513
520 template <class T, class V>
521 static typename std::enable_if<
522 System::IsBoxable<T>::value && !IsNullable<T>::value && !std::is_enum<T>::value && !std::is_same<V, Object>::value,
523 bool>::type Is(const SmartPtr<V>& obj)
524 {
525 return dynamic_cast<T*>(obj.get()) != nullptr;
526 }
527
534 template<class T, class U>
535 static typename std::enable_if<std::is_enum<T>::value, bool>::type Is(const SmartPtr<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
552 template<class T, class U>
553 static typename std::enable_if<std::is_enum<T>::value, bool>::type Is(const WeakPtr<U>& obj)
554 {
555 if (!obj)
556 return false;
557
558 if (obj->Is(TypeInfo::BoxedValueType<T>()))
559 return Enum<T>::IsDefined(Unbox<T>(obj));
560
561 return false;
562 }
563
564private:
569 template<class T, class U>
570 static bool IsImpl()
571 {
572 TypeInfo typeU = ObjectExt::GetType<U>();
573 TypeInfo typeT = ObjectExt::GetType<T>();
574 return typeU == typeT || typeU.IsSubclassOf(typeT);
575 }
576
577public:
583 template<class T, class U>
584 static bool Is(const Nullable<U>& value)
585 {
586 if (value == nullptr)
587 return false;
588
589 return IsImpl<T, U>();
590 }
591
597 template<class T>
598 static bool Is(const char16_t* str)
599 {
600 if (str == nullptr)
601 return false;
602
603 return IsImpl<T, System::String>();
604 }
605
611 template<class T>
612 static bool Is(int32_t value)
613 {
614 ASPOSE_UNUSED(value);
615
616 return IsImpl<T, System::Int32>();
617 }
618
622 static ASPOSECPP_SHARED_API bool IsBoxedValue(const SmartPtr<Object>& obj);
623
628 template<typename T>
629 static typename std::enable_if<IsSmartPtr<T>::value, System::SmartPtr<Object> >::type UnknownToObject(T obj)
630 {
631 return obj.template Cast<Object>();
632 }
633
638 template<typename T>
639 static typename std::enable_if<!IsSmartPtr<T>::value, System::SmartPtr<Object> >::type UnknownToObject(const T& obj)
640 {
641 return Box<T>(obj);
642 }
643
648 template<typename T>
649 static typename std::enable_if<IsSmartPtr<T>::value, T>::type ObjectToUnknown(SmartPtr<Object> obj)
650 {
651 return obj.template Cast<typename T::Pointee_>();
652 }
653
658 template<typename T>
659 static typename std::enable_if<!IsSmartPtr<T>::value, T>::type ObjectToUnknown(SmartPtr<Object> obj)
660 {
661 return System::ObjectExt::Unbox<T>(obj);
662 }
663
669 template<typename T>
670 static typename std::enable_if<!std::is_scalar<T>::value, bool>::type UnknownIsNull(T obj)
671 {
672 return obj == nullptr;
673 }
674
680 template<typename T>
681 static typename std::enable_if<std::is_scalar<T>::value, bool>::type UnknownIsNull(T obj)
682 {
683 return false;
684 }
685
693 template<typename RT1, typename RT2, typename F>
694 static typename std::conditional<std::is_convertible<RT2, RT1>::value, RT1, RT2>::type CoalesceInternal(RT1 value, F func)
695 {
696 return value != nullptr ? value : func();
697 }
698
699
706 template<typename T0, typename T1>
707 static auto Coalesce(T0 value, T1 func)
708 {
709 using retval_t = System::Details::ResultOf<T1>;
710 return CoalesceInternal<T0, retval_t, typename std::function<retval_t()>>(value, func);
711 }
712
719 template<typename T0, typename T1>
720 static T0 Coalesce(System::Nullable<T0> value, T1 func)
721 {
722 return !value.IsNull() ? value.get_Value() : func();
723 }
724
731 template <typename T0, typename T1>
732 static auto CoalesceAssign(T0& value, T1 func) -> T0&
733 {
734 if (value == nullptr)
735 {
736 value = func();
737 }
738 return value;
739 }
740
745 template<typename T>
747 {
749 }
750
756 template<typename To, typename ...From>
757 static typename std::enable_if<(std::is_fundamental<To>::value), std::array<To, sizeof...(From)>>::type ArrayInitializerCast(From ...args)
758 {
759 return std::array<To, sizeof...(From)>({ static_cast<To>(args)... });
760 }
761
763
764 template<typename T>
765 static typename std::enable_if<System::IsBoxable<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
766 {
767 return ObjectExt::Box(value);
768 }
769
770 template<typename T>
771 static typename std::enable_if<System::IsSmartPtr<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
772 {
773 return value;
774 }
775};
776
782template<>
783inline bool ObjectExt::Equals<float, float>(const float& obj, const float& another)
784{
785 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
786}
787
793template<>
794inline bool ObjectExt::Equals<double, double>(const double& obj, const double& another)
795{
796 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
797}
798
802template<>
803inline SmartPtr<Object> ObjectExt::Box<String>(const String& value)
804{
805 return value.IsNull() ? nullptr : MakeObject<BoxedValue<String>>(value);
806}
807
811template<>
812inline String ObjectExt::Unbox<String>(const SmartPtr<Object>& obj)
813{
814 if (obj == nullptr)
815 return String();
816
817 if (obj && obj->Is(String::Type()))
818 {
819 auto boxed = obj.Cast<BoxedValue<String>>();
820 return boxed->unbox();
821 }
822
823 throw InvalidCastException();
824}
825
826namespace Details {
827
829template<typename T>
830struct IsObjectArray : std::false_type {};
831template <typename O>
832struct IsObjectArray<System::Array<SmartPtr<O>>> : std::is_base_of<System::Object, O> {};
833template <>
834struct IsObjectArray<System::Array<String>> : std::true_type {};
835template <typename A>
836struct IsObjectArray<SmartPtr<A>> : IsObjectArray<A> {};
837
838
842template <typename Source, typename Result>
843struct CastType
844{
846 static constexpr bool None = std::is_same<Source, Result>::value;
847
849 static constexpr bool StaticArithmetic =
850 (std::is_enum<Source>::value || std::is_arithmetic<Source>::value) &&
851 (std::is_enum<Result>::value || std::is_arithmetic<Result>::value);
853 static constexpr bool StaticIntPtr =
854 (std::is_same<Source, IntPtr>::value && (std::is_arithmetic<Result>::value || std::is_pointer<Result>::value)) ||
855 (std::is_same<Result, IntPtr>::value && (std::is_arithmetic<Source>::value || std::is_pointer<Source>::value));
857 static constexpr bool StaticString = std::is_same<Result, String>::value && std::is_constructible<String, Source>::value ||
858 std::is_same<Source, String>::value && std::is_same<Result, System::ReadOnlySpan<char16_t>>::value;
860 static constexpr bool Static = !None && (StaticArithmetic || StaticIntPtr || StaticString);
861
863 static constexpr bool Exception = !None &&
864 IsExceptionWrapper<Source>::value && IsExceptionWrapper<Result>::value &&
865 (std::is_convertible<Result, Source>::value || std::is_base_of<Result, Source>::value);
867 static constexpr bool ObjectToException = !None &&
868 std::is_same<SharedPtr<System::Object>, Source>::value && IsExceptionWrapper<Result>::value;
869
871 static constexpr bool Array = !None && IsObjectArray<Result>::value && IsObjectArray<Source>::value;
872
874 static constexpr bool ToSmartPointer = std::is_base_of<System::Object, Result>::value &&
875 !IsExceptionWrapper<Result>::value && !IsBoxable<Result>::value;
877 static constexpr bool RawPointer = ToSmartPointer && std::is_pointer<Source>::value &&
878 std::is_base_of<Object, std::remove_pointer_t<Source>>::value;
880 static constexpr bool Pointer = !None && !Array && ToSmartPointer && IsSmartPtr<Source>::value;
882 static constexpr bool PointerToPointer = !None && !Array && IsSmartPtr<Source>::value && IsSmartPtr<Result>::value;
883
885 static constexpr bool UnboxingToNullable =
886 (std::is_same<Source, SmartPtr<Object>>::value || std::is_same<Source, std::nullptr_t>::value) &&
887 IsNullable<Result>::value;
888
890 static constexpr bool InterfaceUnboxingToNullable =
891 !std::is_same<Source, SmartPtr<Object>>::value && IsSmartPtr<Source>::value && IsNullable<Result>::value;
892
894 static constexpr bool InterfaceUnboxing = !std::is_same<Source, SmartPtr<Object>>::value &&
895 IsSmartPtr<Source>::value && !IsNullable<Result>::value &&
896 std::is_base_of<Details::BoxableObjectBase, Result>::value;
897
899 static constexpr bool NullableBoxing = !UnboxingToNullable && (std::is_same<Result, Nullable<Source>>::value ||
900 (IsNullable<Result>::value && std::is_same<Source, std::nullptr_t>::value));
902 static constexpr bool NullableUnboxing = std::is_same<Source, Nullable<Result>>::value;
903
905 static constexpr bool BoxingCommon = !None && (std::is_base_of<Object, Result>::value || IsSmartPtr<Result>::value);
907 static constexpr bool EnumBoxing = BoxingCommon && std::is_enum<Source>::value;
909 static constexpr bool HeapifyBoxing = std::is_same<Result, SharedPtr<Source>>::value;
911 static constexpr bool InterfaceBoxing = BoxingCommon && !HeapifyBoxing && !std::is_same<Result, Object>::value &&
912 std::is_base_of<Details::BoxableObjectBase, Source>::value &&
913 !BoxedValueDetail::ImplementsInterface_v<Source, Result>;
915 static constexpr bool Boxing = BoxingCommon && !EnumBoxing && !HeapifyBoxing && !InterfaceBoxing && IsBoxable<Source>::value;
917 static constexpr bool StringBoxing = BoxingCommon && !Boxing && !Pointer && !std::is_same<Source, std::nullptr_t>::value &&
918 std::is_constructible<String, Source>::value;
919
921 static constexpr bool Unboxing =
922 !UnboxingToNullable && !InterfaceUnboxing && IsSmartPtr<Source>::value && IsBoxable<Result>::value;
923
925 static constexpr bool UnboxingToString = std::is_same<Result, String>::value && std::is_same<Source, SmartPtr<Object>>::value;
926
928 static constexpr bool Null = !Static && !UnboxingToNullable && !NullableBoxing &&
929 std::is_same<Source, std::nullptr_t>::value;
930
932 static constexpr bool InvalidUnboxing = Unboxing && !InterfaceUnboxingToNullable && !InterfaceUnboxing && !std::is_same<Source, SmartPtr<Object>>::value;
933};
934
935} // namespace Details
936
943template <typename Result, typename Source>
944std::enable_if_t<Details::CastType<Source, Result>::None, Result> ExplicitCast(const Source& value)
945{
946 return value;
947}
948
955template <typename Result, typename Source>
956std::enable_if_t<Details::CastType<Source, Result>::Static, Result> ExplicitCast(const Source& value)
957{
958 return Result(value);
959}
960
968template <typename Result, typename Source>
969std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> ExplicitCast(const Source& value)
970{
971 return value.Get().template Cast<typename Result::ExceptionType, std::true_type>() ? Result(value.Get())
972 : Result(nullptr);
973}
974
982template <typename Result, typename Source>
983std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> ExplicitCast(const Source& value)
984{
985 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::true_type>();
986 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::true_type>())
987 : Result(nullptr);
988}
989
997template <typename Result, typename Source>
998std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
999 ExplicitCast(const Source& value)
1000{
1001 return value.template Cast<Result, std::true_type>();
1002}
1003
1011template <typename Result, typename Source>
1012std::enable_if_t<Details::CastType<Source, Result>::RawPointer, typename CastResult<std::remove_pointer_t<Result>>::type>
1013 ExplicitCast(Source value)
1014{
1015 return ExplicitCast<Result>(SmartPtr<std::remove_pointer_t<Source>>(value));
1016}
1017
1025template <typename Result, typename Source>
1026std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
1027 ExplicitCast(const Source& value)
1028{
1029 return ExplicitCast<typename Result::Pointee_>(value);
1030}
1031
1039template <typename Result, typename Source>
1040std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1041 ExplicitCast(const Source& value)
1042{
1043 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, false);
1044}
1045
1052template <typename Result, typename Source>
1053std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> ExplicitCast(const Source& value)
1054{
1055 return Result(value);
1056}
1057
1065template <typename Result, typename Source>
1066std::enable_if_t<Details::CastType<Source, Result>::NullableUnboxing, Result> ExplicitCast(const Source& value)
1067{
1068 if (value == nullptr)
1069 throw NullReferenceException(u"Can not unbox null value");
1070
1071 return static_cast<Result>(value);
1072}
1073
1080template <typename Result, typename Source>
1081std::enable_if_t<Details::CastType<Source, Result>::EnumBoxing, SmartPtr<BoxedValueBase>>
1082 ExplicitCast(const Source& value)
1083{
1084 return ObjectExt::BoxEnum(value);
1085}
1086
1094template <typename Result, typename Source>
1095std::enable_if_t<Details::CastType<Source, Result>::HeapifyBoxing, typename CastResult<Result>::type>
1096 ExplicitCast(const Source& value)
1097{
1098 return MakeObject<Source>(value).template Cast<typename Result::Pointee_, std::true_type>();
1099}
1100
1107template <typename Result, typename Source>
1108std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1109 ExplicitCast(const Source& value)
1110{
1111 return MakeObject<Source>(value).template Cast<Result, std::true_type>();
1112}
1113
1120template <typename Result, typename Source>
1121std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1122 ExplicitCast(const Source& value)
1123{
1124 return ObjectExt::Box(value).template Cast<typename CastResult<Result>::type::Pointee_, std::true_type>();
1125}
1126
1133template <typename Result, typename Source>
1134std::enable_if_t<Details::CastType<Source, Result>::StringBoxing, typename CastResult<Result>::type>
1135 ExplicitCast(const Source& value)
1136{
1137 return ObjectExt::Box<String>(value).template Cast<typename CastResult<Result>::type::Pointee_, std::true_type>();
1138}
1139
1146template <typename Result, typename Source>
1147std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxing, Result> ExplicitCast(const Source& value)
1148{
1149 return *(value.template Cast<Result, std::true_type>());
1150}
1151
1158template <typename Result, typename Source>
1159std::enable_if_t<Details::CastType<Source, Result>::Unboxing, Result> ExplicitCast(const Source& value)
1160{
1161 return ObjectExt::Unbox<Result>(value);
1162}
1163
1170template <typename Result, typename Source>
1171std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1172{
1173 return typename CastResult<Result>::type(nullptr);
1174}
1175
1183template <typename Result, typename Source>
1184std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1185{
1186 if (!value)
1187 return nullptr;
1188
1189 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1190 std::transform(value->data().begin(), value->data().end(), result->data().begin(),
1191 [](const auto& value) {return ExplicitCast<typename Result::ValueType>(value);});
1192
1193 return result;
1194}
1195
1202template <typename Result, typename Source>
1203std::enable_if_t<Details::CastType<Source, Result>::Static, Result> AsCast(const Source& value)
1204{
1205 return Result(value);
1206}
1207
1214template <typename Result, typename Source>
1215std::enable_if_t<Details::CastType<Source, Result>::None, Result> AsCast(const Source& value)
1216{
1217 return value;
1218}
1219
1226template <typename Result, typename Source>
1227std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> AsCast(const Source& value)
1228{
1229 return value.Get().template Cast<typename Result::ExceptionType, std::false_type>() ? Result(value.Get())
1230 : Result(nullptr);
1231}
1232
1239template <typename Result, typename Source>
1240std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> AsCast(const Source& value)
1241{
1242 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::false_type>();
1243 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::false_type>())
1244 : Result(nullptr);
1245}
1246
1253template <typename Result, typename Source>
1254std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
1255 AsCast(const Source& value)
1256{
1257 return value.template Cast<Result, std::false_type>();
1258}
1259
1266template <typename Result, typename Source>
1267std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
1268 AsCast(const Source& value)
1269{
1270 return AsCast<typename Result::Pointee_>(value);
1271}
1272
1279template <typename Result, typename Source>
1280std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1281 AsCast(const Source& value)
1282{
1283 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, true);
1284}
1285
1292template <typename Result, typename Source>
1293std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxingToNullable, Result> AsCast(const Source& value)
1294{
1295 Result result;
1296 if (ObjectExt::Is<typename Result::ValueType>(value))
1297 {
1298 result = *(value.template Cast<typename Result::ValueType, std::false_type>());
1299 }
1300 return result;
1301}
1302
1308template <typename Result, typename Source>
1309std::enable_if_t<Details::CastType<Source, Result>::InvalidUnboxing, Result> AsCast(const Source& value)
1310{
1311 return Default<Result>();
1312}
1313
1320template <typename Result, typename Source>
1321std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> AsCast(const Source& value)
1322{
1323 return Result(value);
1324}
1325
1332template <typename Result, typename Source>
1333std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1334 AsCast(const Source& value)
1335{
1336 if (!ObjectExt::Is<Result>(value))
1337 {
1338 return nullptr;
1339 }
1340
1341 return MakeObject<Source>(value).template Cast<Result, std::false_type>();
1342}
1343
1350template <typename Result, typename Source>
1351std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1352 AsCast(const Source& value)
1353{
1354 return ObjectExt::Box(value).template Cast<typename CastResult<Result>::type::Pointee_, std::false_type>();
1355}
1356
1363template <typename Result, typename Source>
1364std::enable_if_t<Details::CastType<Source, Result>::UnboxingToString, Result> AsCast(const Source& value)
1365{
1366 return ObjectExt::UnboxStringSafe(value);
1367}
1368
1375template <typename Result, typename Source>
1376std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> AsCast(const Source& value)
1377{
1378 return typename CastResult<Result>::type(nullptr);
1379}
1380
1387template <typename Result, typename Source>
1388std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> AsCast(const Source& value)
1389{
1390 if (!value)
1391 return nullptr;
1392
1393 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1394 auto d_it = result->data().begin();
1395 auto s_it = value->data().begin();
1396 while (s_it != value->data().end())
1397 {
1398 auto& source_element = *(s_it++);
1399 auto& result_element = *(d_it++);
1400
1401 result_element = AsCast<typename Result::ValueType>(source_element);
1402
1403 // Fail entire cast if any element fails
1404 if (source_element != nullptr && result_element == nullptr)
1405 return nullptr;
1406 }
1407
1408 return result;
1409}
1410
1417template <typename T0, typename T1>
1418static auto SafeInvoke(T0&& expr, T1&& func)
1419{
1420 // The type which 'func' actually returns
1421 using retval_t = decltype(func(expr));
1422
1423 // The type which function SafeInvoke will return. Non-nullable types will be wrapped by 'Nullable<>' class template.
1424 using result_t = typename std::conditional<
1425 std::is_base_of<Details::BoxableObjectBase, retval_t>::value || std::is_arithmetic<retval_t>::value || std::is_enum<retval_t>::value,
1427 retval_t>::type;
1428
1429 return expr != nullptr ? result_t(func(expr)) : result_t(nullptr);
1430}
1431
1432} // 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:218
const T & unbox() const
Unboxes the value represented by the current object.
Definition: boxed_value.h:248
Template that represents wrapper of exceptions that are derived from Exception class.
Definition: exception.h:118
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:23
static bool Is(int32_t value)
Implements 'is' operator translation. Specialization for integer literal.
Definition: object_ext.h:612
static String ToString(const char_t *obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:103
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:473
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:757
static T0 Coalesce(System::Nullable< T0 > value, T1 func)
Implementation of '??' operator translation for nullable types.
Definition: object_ext.h:720
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:216
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:425
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:134
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:194
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:414
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:316
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:89
static SmartPtr< System::BoxedValueBase > BoxEnum(T enumValue)
Boxes enum types for being propagated as Object.
Definition: object_ext.h:746
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:535
static auto CoalesceAssign(T0 &value, T1 func) -> T0 &
Implementation of '??=' operator translation.
Definition: object_ext.h:732
static bool Is(const Nullable< U > &value)
Implements 'is' operator translation. Specialization for Nullable type.
Definition: object_ext.h:584
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:184
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:287
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:370
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:240
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:387
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:659
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:154
static auto Coalesce(T0 value, T1 func)
Implementation of '??' operator translation for non-nullable types.
Definition: object_ext.h:707
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:305
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:670
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:681
static bool Equals(const System::String &obj, const System::String &another)
Object.Equals for System.String.
Definition: object_ext.h:95
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:553
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:639
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:123
static bool Is(const char16_t *str)
Implements 'is' operator translation. Specialization for string literal.
Definition: object_ext.h:598
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:174
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:77
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:356
static int GetHashCode(const T &obj)
Implements GetHashCode() calls; works on both Object subclasses and unrelated types.
Definition: object_ext.h:30
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:439
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:523
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:501
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:694
static std::enable_if< System::IsBoxable< T >::value, System::SharedPtr< System::Object > >::type ExplicitCastToObject(const T &value)
Definition: object_ext.h:765
static std::enable_if< IsExceptionWrapper< T >::value, bool >::type Equals(const T &obj, const T2 &another)
Definition: object_ext.h:36
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:164
static Nullable< T > UnboxToNullable(const SmartPtr< Object > &obj, bool safe=true)
Unboxes object to nullable type.
Definition: object_ext.h:333
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:629
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:453
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:51
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:113
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:266
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:649
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:64
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:402
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:771
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:205
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:226
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:144
Base class that enables using methods available for System.Object class in C#. All non-trivial classe...
Definition: object.h:51
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:864
String class used across the library. Is a substitute for C# System.String when translating code....
Definition: string.h:125
bool IsNullOrEmpty() const
Checks if string is empty or is considered null.
bool Equals(const String &str, System::StringComparison comparison_type) const
String equality comparison. Several modes provided by StringComparison enumeration are supported.
bool IsNull() const
Checks if string is considered null. String is null and only if it is constructed via String() constr...
Definition: string.h:291
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
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:1203
static auto SafeInvoke(T0 &&expr, T1 &&func)
Implementation of '?.' operator translation.
Definition: object_ext.h:1418
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:944
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:379
SmartPtr< TTo > type
An alias for a pointer to an instance of TTo.
Definition: object.h:376
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:394
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