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
94
98 static inline String ToString(const char_t * obj)
99 {
100 return String(obj);
101 }
102
107 template<typename T>
108 static inline String ToString(const Nullable<T> & obj)
109 {
110 return (obj.IsNull() ? u"" : ToString(obj.get_Value()));
111 }
112
117 template<typename T>
118 static typename std::enable_if<std::is_enum<T>::value, String>::type ToString(const T& obj)
119 {
120 String str = Enum<T>::GetName(obj);
121 return !str.IsNullOrEmpty() ? str : System::Convert::ToString(static_cast<typename std::underlying_type<T>::type>(obj));
122 }
123
128 template<typename T>
129 static typename std::enable_if<IsSmartPtr<T>::value, String>::type ToString(const T& obj)
130 {
131 return obj->ToString();
132 }
133
138 template<typename T>
139 static typename std::enable_if<IsSmartPtr<T>::value || std::is_pointer<T>::value || IsExceptionWrapper<T>::value, String>::type ToString(T& obj)
140 {
141 return obj->ToString();
142 }
143
148 template<typename T>
149 static typename std::enable_if<!IsSmartPtr<T>::value && std::is_scalar<T>::value && !std::is_enum<T>::value, String>::type ToString(T& obj)
150 {
151 return System::Convert::ToString(obj);
152 }
153
158 template<typename T>
159 static typename std::enable_if<!IsSmartPtr<T>::value && std::is_scalar<T>::value && !std::is_enum<T>::value, String>::type ToString(T&& obj)
160 {
161 return System::Convert::ToString(obj);
162 }
163
168 template<typename T>
169 static typename std::enable_if<!IsExceptionWrapper<T>::value && !IsSmartPtr<T>::value && !std::is_scalar<T>::value && !IsNullable<T>::value, String>::type ToString(T& obj)
170 {
171 return obj.ToString();
172 }
173
178 template <typename T>
179 static typename std::enable_if<!IsSmartPtr<T>::value && !std::is_scalar<T>::value && !IsNullable<T>::value, String>::type ToString(const T& obj)
180 {
181 return obj.ToString();
182 }
183
188 template<typename T>
189 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)
190 {
191 return obj.ToString();
192 }
193
199 template<typename T>
200 static typename std::enable_if<std::is_enum<T>::value, System::SmartPtr<System::Object>>::type Box(const T& value)
201 {
202 return System::MakeObject<BoxedEnum<T>>(value);
203 }
204
210 template<typename T>
211 static typename std::enable_if<!std::is_enum<T>::value && !IsNullable<T>::value, System::SmartPtr<System::Object>>::type Box(const T& value)
212 {
213 return System::MakeObject<BoxedValue<T>>(value);
214 }
215
220 template<typename T>
221 static typename std::enable_if <IsNullable<T>::value, System::SmartPtr<System::Object>>::type Box(const T& value)
222 {
223 if (value == nullptr)
224 return nullptr;
225
226 return System::MakeObject<BoxedValue<typename T::ValueType>>(value.get_Value());
227 }
228
234 template<typename T>
235 static typename std::enable_if<std::is_enum<T>::value, T>::type Unbox(const SmartPtr<Object>& obj)
236 {
237 using UT = typename std::underlying_type<T>::type;
238
239 if (obj && obj->Is(BoxedEnum<T>::Type()))
240 {
241 auto boxed = obj.template Cast<BoxedEnum<T>>();
242 return static_cast<T>(boxed->unbox());
243 }
244 using UT = typename std::underlying_type<T>::type;
245 if (obj && obj->Is(ObjectExt::GetType<UT>()))
246 {
247 auto boxed = obj.Cast<BoxedValue<UT>>();
248 return static_cast<T>(boxed->unbox());
249 }
250
251
252 throw InvalidCastException();
253 }
254
260 template<class T>
261 static typename std::enable_if<!std::is_enum<T>::value && detail::has_operator_equal<T>::value, T>::type Unbox(const SmartPtr<Object>& obj)
262 {
263 if (obj)
264 {
265 if (obj->Is(ObjectExt::GetType<T>()))
266 {
267 auto boxed = obj.template Cast<BoxedValue<T>>();
268 return boxed->unbox();
269 }
270
271 throw InvalidCastException();
272 }
273 throw NullReferenceException();
274 }
275
281 template<class T>
282 static typename std::enable_if<!std::is_enum<T>::value && !detail::has_operator_equal<T>::value, T>::type Unbox(const SmartPtr<Object>& obj)
283 {
284
285 if (obj && obj->Is(BoxedValue<T>::Type()))
286 {
287 auto boxed = obj.template Cast<BoxedValue<T>>();
288 return boxed->unbox();
289 }
290
291 throw InvalidCastException();
292 }
293
299 template<class T, class E>
300 static typename std::enable_if<std::is_enum<E>::value && std::numeric_limits<T>::is_integer, T>::type Unbox(E e)
301 {
302 return static_cast<T>(e);
303 }
304
310 template<class T, class E>
311 static typename std::enable_if<std::is_enum<E>::value && std::is_enum<T>::value, T>::type Unbox(E e)
312 {
313 return static_cast<T>(e);
314 }
315
320 static ASPOSECPP_SHARED_API String UnboxStringSafe(const SmartPtr<Object>& obj);
321
327 template<class T>
328 static Nullable<T> UnboxToNullable(const SmartPtr<Object>& obj, bool safe = true)
329 {
330 if (obj)
331 {
332 if (obj->Is(ObjectExt::GetType<T>()))
333 {
334 auto boxed = obj.template Cast<BoxedValue<T>>();
335 return Nullable<T>(boxed->unbox());
336 }
337 }
338
339 if (!obj || safe)
340 return Nullable<T>(nullptr);
341
342 throw InvalidCastException();
343 }
344
350 template <class T>
351 static typename std::enable_if<System::IsBoxable<T>::value, bool>::type Is(const T& obj)
352 {
353 return true;
354 }
355
362 template<class T, class U>
363 static typename std::enable_if<std::is_convertible<T, Object>::value && std::is_final<T>::value &&
365 bool>::type Is(const U& obj)
366 {
367 if (obj == nullptr)
368 return false;
369
370 return typeid(*obj.get()) == typeid(T);
371 }
372
379 template<class T, class U>
380 static typename std::enable_if<std::is_convertible<T, Object>::value&& !std::is_final<T>::value &&
382 bool>::type Is(const U& obj)
383 {
384 if (!obj)
385 return false;
386
387 return dynamic_cast<T*>(obj.get()) != nullptr;
388 }
389
395 template<class T>
396 static typename std::enable_if<std::is_convertible<T, Object>::value,
397 bool>::type Is(const Object& obj)
398 {
399 return obj.Is(T::Type());
400 }
401
407 template<class T>
408 static typename std::enable_if<!std::is_convertible<T, Object>::value,
409 bool>::type Is(const Object& obj)
410 {
411 return false;
412 }
413
419 template<class T, class U>
420 static typename std::enable_if<IsSmartPtr<T>::value, bool>::type Is(const SmartPtr<U>& obj)
421 {
422 if (!obj)
423 return false;
424
425 return dynamic_cast<typename T::Pointee_*>(obj.get()) != nullptr;
426 }
427
433 template<class T, class U>
434 static typename std::enable_if<IsExceptionWrapper<T>::value, bool>::type Is(const ExceptionWrapper<U>& obj)
435 {
436 if (obj == nullptr)
437 return false;
438
439 return Is<SmartPtr<typename T::ExceptionType>>(obj.Get());
440 }
441
447 template<class T>
448 static typename std::enable_if<IsNullable<T>::value, bool>::type Is(const SmartPtr<Object>& obj)
449 {
450 if (!obj)
451 return false;
452
453 if (obj->Is(System::ObjectExt::GetType<typename T::ValueType>()))
454 return true;
455
456 return false;
457 }
458
464 template<class T>
465 static typename std::enable_if<
467 bool
468 >::type Is(const SmartPtr<Object>& obj)
469 {
470 if (!obj)
471 return false;
472
473 if (obj->Is(System::ObjectExt::GetType<T>()))
474 {
475 return true;
476 }
477
478 if (obj->Is(Nullable<T>::Type()))
479 {
480 auto boxed = obj.Cast<BoxedValue<Nullable<T>>>();
481 return !boxed->unbox().IsNull();
482 }
483
484 return false;
485 }
486
492 template<class T>
493 static typename std::enable_if<
495 bool
496 >::type Is(const SmartPtr<Object>& obj)
497 {
498 if (!obj)
499 return false;
500
501 if (obj->Is(TypeInfo::BoxedValueType<T>()))
502 {
503 return true;
504 }
505
506 return false;
507 }
508
515 template <class T, class V>
516 static typename std::enable_if<
517 System::IsBoxable<T>::value && !IsNullable<T>::value && !std::is_enum<T>::value && !std::is_same<V, Object>::value,
518 bool>::type Is(const SmartPtr<V>& obj)
519 {
520 return dynamic_cast<T*>(obj.get()) != nullptr;
521 }
522
529 template<class T, class U>
530 static typename std::enable_if<std::is_enum<T>::value, bool>::type Is(const SmartPtr<U>& obj)
531 {
532 if (!obj)
533 return false;
534
535 if (obj->Is(TypeInfo::BoxedValueType<T>()))
536 return Enum<T>::IsDefined(Unbox<T>(obj));
537
538 return false;
539 }
540
547 template<class T, class U>
548 static typename std::enable_if<std::is_enum<T>::value, bool>::type Is(const WeakPtr<U>& obj)
549 {
550 if (!obj)
551 return false;
552
553 if (obj->Is(TypeInfo::BoxedValueType<T>()))
554 return Enum<T>::IsDefined(Unbox<T>(obj));
555
556 return false;
557 }
558
559private:
564 template<class T, class U>
565 static bool IsImpl()
566 {
567 TypeInfo typeU = ObjectExt::GetType<U>();
568 TypeInfo typeT = ObjectExt::GetType<T>();
569 return typeU == typeT || typeU.IsSubclassOf(typeT);
570 }
571
572public:
578 template<class T, class U>
579 static bool Is(const Nullable<U>& value)
580 {
581 if (value == nullptr)
582 return false;
583
584 return IsImpl<T, U>();
585 }
586
592 template<class T>
593 static bool Is(const char16_t* str)
594 {
595 if (str == nullptr)
596 return false;
597
598 return IsImpl<T, System::String>();
599 }
600
606 template<class T>
607 static bool Is(int32_t value)
608 {
609 ASPOSE_UNUSED(value);
610
611 return IsImpl<T, System::Int32>();
612 }
613
617 static ASPOSECPP_SHARED_API bool IsBoxedValue(const SmartPtr<Object>& obj);
618
623 template<typename T>
624 static typename std::enable_if<IsSmartPtr<T>::value, System::SmartPtr<Object> >::type UnknownToObject(T obj)
625 {
626 return obj.template Cast<Object>();
627 }
628
633 template<typename T>
634 static typename std::enable_if<!IsSmartPtr<T>::value, System::SmartPtr<Object> >::type UnknownToObject(const T& obj)
635 {
636 return Box<T>(obj);
637 }
638
643 template<typename T>
644 static typename std::enable_if<IsSmartPtr<T>::value, T>::type ObjectToUnknown(SmartPtr<Object> obj)
645 {
646 return obj.template Cast<typename T::Pointee_>();
647 }
648
653 template<typename T>
654 static typename std::enable_if<!IsSmartPtr<T>::value, T>::type ObjectToUnknown(SmartPtr<Object> obj)
655 {
656 return System::ObjectExt::Unbox<T>(obj);
657 }
658
664 template<typename T>
665 static typename std::enable_if<!std::is_scalar<T>::value, bool>::type UnknownIsNull(T obj)
666 {
667 return obj == nullptr;
668 }
669
675 template<typename T>
676 static typename std::enable_if<std::is_scalar<T>::value, bool>::type UnknownIsNull(T obj)
677 {
678 return false;
679 }
680
688 template<typename RT1, typename RT2, typename F>
689 static typename std::conditional<std::is_convertible<RT2, RT1>::value, RT1, RT2>::type CoalesceInternal(RT1 value, F func)
690 {
691 return value != nullptr ? value : func();
692 }
693
694
701 template<typename T0, typename T1>
702 static auto Coalesce(T0 value, T1 func)
703 {
704 using retval_t = System::Details::ResultOf<T1>;
705 return CoalesceInternal<T0, retval_t, typename std::function<retval_t()>>(value, func);
706 }
707
714 template<typename T0, typename T1>
715 static T0 Coalesce(System::Nullable<T0> value, T1 func)
716 {
717 return !value.IsNull() ? value.get_Value() : func();
718 }
719
726 template <typename T0, typename T1>
727 static auto CoalesceAssign(T0& value, T1 func) -> T0&
728 {
729 if (value == nullptr)
730 {
731 value = func();
732 }
733 return value;
734 }
735
740 template<typename T>
742 {
744 }
745
751 template<typename To, typename ...From>
752 static typename std::enable_if<(std::is_fundamental<To>::value), std::array<To, sizeof...(From)>>::type ArrayInitializerCast(From ...args)
753 {
754 return std::array<To, sizeof...(From)>({ static_cast<To>(args)... });
755 }
756
758
759 template<typename T>
760 static typename std::enable_if<System::IsBoxable<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
761 {
762 return ObjectExt::Box(value);
763 }
764
765 template<typename T>
766 static typename std::enable_if<System::IsSmartPtr<T>::value, System::SharedPtr<System::Object>>::type ExplicitCastToObject(const T& value)
767 {
768 return value;
769 }
770};
771
777template<>
778inline bool ObjectExt::Equals<float, float>(const float& obj, const float& another)
779{
780 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
781}
782
788template<>
789inline bool ObjectExt::Equals<double, double>(const double& obj, const double& another)
790{
791 return (std::isnan(obj) && std::isnan(another)) ? true : obj == another;
792}
793
797template<>
798inline SmartPtr<Object> ObjectExt::Box<String>(const String& value)
799{
800 return value.IsNull() ? nullptr : MakeObject<BoxedValue<String>>(value);
801}
802
806template<>
807inline String ObjectExt::Unbox<String>(const SmartPtr<Object>& obj)
808{
809 if (obj == nullptr)
810 return String();
811
812 if (obj && obj->Is(String::Type()))
813 {
814 auto boxed = obj.Cast<BoxedValue<String>>();
815 return boxed->unbox();
816 }
817
818 throw InvalidCastException();
819}
820
821namespace Details {
822
824template<typename T>
825struct IsObjectArray : std::false_type {};
826template <typename O>
827struct IsObjectArray<System::Array<SmartPtr<O>>> : std::is_base_of<System::Object, O> {};
828template <>
829struct IsObjectArray<System::Array<String>> : std::true_type {};
830template <typename A>
831struct IsObjectArray<SmartPtr<A>> : IsObjectArray<A> {};
832
833
837template <typename Source, typename Result>
838struct CastType
839{
841 static constexpr bool None = std::is_same<Source, Result>::value;
842
844 static constexpr bool StaticArithmetic =
845 (std::is_enum<Source>::value || std::is_arithmetic<Source>::value) &&
846 (std::is_enum<Result>::value || std::is_arithmetic<Result>::value);
848 static constexpr bool StaticIntPtr =
849 (std::is_same<Source, IntPtr>::value && (std::is_arithmetic<Result>::value || std::is_pointer<Result>::value)) ||
850 (std::is_same<Result, IntPtr>::value && (std::is_arithmetic<Source>::value || std::is_pointer<Source>::value));
852 static constexpr bool StaticString = std::is_same<Result, String>::value && std::is_constructible<String, Source>::value ||
853 std::is_same<Source, String>::value && std::is_same<Result, System::ReadOnlySpan<char16_t>>::value;
855 static constexpr bool Static = !None && (StaticArithmetic || StaticIntPtr || StaticString);
856
858 static constexpr bool Exception = !None &&
859 IsExceptionWrapper<Source>::value && IsExceptionWrapper<Result>::value &&
860 (std::is_convertible<Result, Source>::value || std::is_base_of<Result, Source>::value);
862 static constexpr bool ObjectToException = !None &&
863 std::is_same<SharedPtr<System::Object>, Source>::value && IsExceptionWrapper<Result>::value;
864
866 static constexpr bool Array = !None && IsObjectArray<Result>::value && IsObjectArray<Source>::value;
867
869 static constexpr bool ToSmartPointer = std::is_base_of<System::Object, Result>::value &&
870 !IsExceptionWrapper<Result>::value && !IsBoxable<Result>::value;
872 static constexpr bool RawPointer = ToSmartPointer && std::is_pointer<Source>::value &&
873 std::is_base_of<Object, std::remove_pointer_t<Source>>::value;
875 static constexpr bool Pointer = !None && !Array && ToSmartPointer && IsSmartPtr<Source>::value;
877 static constexpr bool PointerToPointer = !None && !Array && IsSmartPtr<Source>::value && IsSmartPtr<Result>::value;
878
880 static constexpr bool UnboxingToNullable =
881 (std::is_same<Source, SmartPtr<Object>>::value || std::is_same<Source, std::nullptr_t>::value) &&
882 IsNullable<Result>::value;
883
885 static constexpr bool InterfaceUnboxingToNullable =
886 !std::is_same<Source, SmartPtr<Object>>::value && IsSmartPtr<Source>::value && IsNullable<Result>::value;
887
889 static constexpr bool InterfaceUnboxing = !std::is_same<Source, SmartPtr<Object>>::value &&
890 IsSmartPtr<Source>::value && !IsNullable<Result>::value &&
891 std::is_base_of<Details::BoxableObjectBase, Result>::value;
892
894 static constexpr bool NullableBoxing = !UnboxingToNullable && (std::is_same<Result, Nullable<Source>>::value ||
895 (IsNullable<Result>::value && std::is_same<Source, std::nullptr_t>::value));
897 static constexpr bool NullableUnboxing = std::is_same<Source, Nullable<Result>>::value;
898
900 static constexpr bool BoxingCommon = !None && (std::is_base_of<Object, Result>::value || IsSmartPtr<Result>::value);
902 static constexpr bool EnumBoxing = BoxingCommon && std::is_enum<Source>::value;
904 static constexpr bool HeapifyBoxing = std::is_same<Result, SharedPtr<Source>>::value;
906 static constexpr bool InterfaceBoxing = BoxingCommon && !HeapifyBoxing && !std::is_same<Result, Object>::value &&
907 std::is_base_of<Details::BoxableObjectBase, Source>::value &&
908 !BoxedValueDetail::ImplementsInterface_v<Source, Result>;
910 static constexpr bool Boxing = BoxingCommon && !EnumBoxing && !HeapifyBoxing && !InterfaceBoxing && IsBoxable<Source>::value;
912 static constexpr bool StringBoxing = BoxingCommon && !Boxing && !Pointer && !std::is_same<Source, std::nullptr_t>::value &&
913 std::is_constructible<String, Source>::value;
914
916 static constexpr bool Unboxing =
917 !UnboxingToNullable && !InterfaceUnboxing && IsSmartPtr<Source>::value && IsBoxable<Result>::value;
918
920 static constexpr bool UnboxingToString = std::is_same<Result, String>::value && std::is_same<Source, SmartPtr<Object>>::value;
921
923 static constexpr bool Null = !Static && !UnboxingToNullable && !NullableBoxing &&
924 std::is_same<Source, std::nullptr_t>::value;
925
927 static constexpr bool InvalidUnboxing = Unboxing && !InterfaceUnboxingToNullable && !InterfaceUnboxing && !std::is_same<Source, SmartPtr<Object>>::value;
928};
929
930} // namespace Details
931
938template <typename Result, typename Source>
939std::enable_if_t<Details::CastType<Source, Result>::None, Result> ExplicitCast(const Source& value)
940{
941 return value;
942}
943
950template <typename Result, typename Source>
951std::enable_if_t<Details::CastType<Source, Result>::Static, Result> ExplicitCast(const Source& value)
952{
953 return Result(value);
954}
955
963template <typename Result, typename Source>
964std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> ExplicitCast(const Source& value)
965{
966 return value.Get().template Cast<typename Result::ExceptionType, std::true_type>() ? Result(value.Get())
967 : Result(nullptr);
968}
969
977template <typename Result, typename Source>
978std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> ExplicitCast(const Source& value)
979{
980 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::true_type>();
981 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::true_type>())
982 : Result(nullptr);
983}
984
992template <typename Result, typename Source>
993std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
994 ExplicitCast(const Source& value)
995{
996 return value.template Cast<Result, std::true_type>();
997}
998
1006template <typename Result, typename Source>
1007std::enable_if_t<Details::CastType<Source, Result>::RawPointer, typename CastResult<std::remove_pointer_t<Result>>::type>
1008 ExplicitCast(Source value)
1009{
1010 return ExplicitCast<Result>(SmartPtr<std::remove_pointer_t<Source>>(value));
1011}
1012
1020template <typename Result, typename Source>
1021std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
1022 ExplicitCast(const Source& value)
1023{
1024 return ExplicitCast<typename Result::Pointee_>(value);
1025}
1026
1034template <typename Result, typename Source>
1035std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1036 ExplicitCast(const Source& value)
1037{
1038 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, false);
1039}
1040
1047template <typename Result, typename Source>
1048std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> ExplicitCast(const Source& value)
1049{
1050 return Result(value);
1051}
1052
1060template <typename Result, typename Source>
1061std::enable_if_t<Details::CastType<Source, Result>::NullableUnboxing, Result> ExplicitCast(const Source& value)
1062{
1063 if (value == nullptr)
1064 throw NullReferenceException(u"Can not unbox null value");
1065
1066 return static_cast<Result>(value);
1067}
1068
1075template <typename Result, typename Source>
1076std::enable_if_t<Details::CastType<Source, Result>::EnumBoxing, SmartPtr<BoxedValueBase>>
1077 ExplicitCast(const Source& value)
1078{
1079 return ObjectExt::BoxEnum(value);
1080}
1081
1089template <typename Result, typename Source>
1090std::enable_if_t<Details::CastType<Source, Result>::HeapifyBoxing, typename CastResult<Result>::type>
1091 ExplicitCast(const Source& value)
1092{
1093 return MakeObject<Source>(value).template Cast<typename Result::Pointee_, std::true_type>();
1094}
1095
1102template <typename Result, typename Source>
1103std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1104 ExplicitCast(const Source& value)
1105{
1106 return MakeObject<Source>(value).template Cast<Result, std::true_type>();
1107}
1108
1115template <typename Result, typename Source>
1116std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1117 ExplicitCast(const Source& value)
1118{
1119 return ObjectExt::Box(value).template Cast<typename CastResult<Result>::type::Pointee_, std::true_type>();
1120}
1121
1128template <typename Result, typename Source>
1129std::enable_if_t<Details::CastType<Source, Result>::StringBoxing, typename CastResult<Result>::type>
1130 ExplicitCast(const Source& value)
1131{
1132 return ObjectExt::Box<String>(value).template Cast<typename CastResult<Result>::type::Pointee_, std::true_type>();
1133}
1134
1141template <typename Result, typename Source>
1142std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxing, Result> ExplicitCast(const Source& value)
1143{
1144 return *(value.template Cast<Result, std::true_type>());
1145}
1146
1153template <typename Result, typename Source>
1154std::enable_if_t<Details::CastType<Source, Result>::Unboxing, Result> ExplicitCast(const Source& value)
1155{
1156 return ObjectExt::Unbox<Result>(value);
1157}
1158
1165template <typename Result, typename Source>
1166std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1167{
1168 return typename CastResult<Result>::type(nullptr);
1169}
1170
1178template <typename Result, typename Source>
1179std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> ExplicitCast(const Source& value)
1180{
1181 if (!value)
1182 return nullptr;
1183
1184 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1185 std::transform(value->data().begin(), value->data().end(), result->data().begin(),
1186 [](const auto& value) {return ExplicitCast<typename Result::ValueType>(value);});
1187
1188 return result;
1189}
1190
1197template <typename Result, typename Source>
1198std::enable_if_t<Details::CastType<Source, Result>::Static, Result> AsCast(const Source& value)
1199{
1200 return Result(value);
1201}
1202
1209template <typename Result, typename Source>
1210std::enable_if_t<Details::CastType<Source, Result>::None, Result> AsCast(const Source& value)
1211{
1212 return value;
1213}
1214
1221template <typename Result, typename Source>
1222std::enable_if_t<Details::CastType<Source, Result>::Exception, Result> AsCast(const Source& value)
1223{
1224 return value.Get().template Cast<typename Result::ExceptionType, std::false_type>() ? Result(value.Get())
1225 : Result(nullptr);
1226}
1227
1234template <typename Result, typename Source>
1235std::enable_if_t<Details::CastType<Source, Result>::ObjectToException, Result> AsCast(const Source& value)
1236{
1237 auto exception_ptr = value.template Cast<typename Result::ExceptionType, std::false_type>();
1238 return exception_ptr ? Result(exception_ptr.template Cast<System::Details_Exception, std::false_type>())
1239 : Result(nullptr);
1240}
1241
1248template <typename Result, typename Source>
1249std::enable_if_t<Details::CastType<Source, Result>::Pointer, typename CastResult<Result>::type>
1250 AsCast(const Source& value)
1251{
1252 return value.template Cast<Result, std::false_type>();
1253}
1254
1261template <typename Result, typename Source>
1262std::enable_if_t<Details::CastType<Source, Result>::PointerToPointer, Result>
1263 AsCast(const Source& value)
1264{
1265 return AsCast<typename Result::Pointee_>(value);
1266}
1267
1274template <typename Result, typename Source>
1275std::enable_if_t<Details::CastType<Source, Result>::UnboxingToNullable, Result>
1276 AsCast(const Source& value)
1277{
1278 return ObjectExt::UnboxToNullable<typename Result::ValueType>(value, true);
1279}
1280
1287template <typename Result, typename Source>
1288std::enable_if_t<Details::CastType<Source, Result>::InterfaceUnboxingToNullable, Result> AsCast(const Source& value)
1289{
1290 Result result;
1291 if (ObjectExt::Is<typename Result::ValueType>(value))
1292 {
1293 result = *(value.template Cast<typename Result::ValueType, std::false_type>());
1294 }
1295 return result;
1296}
1297
1303template <typename Result, typename Source>
1304std::enable_if_t<Details::CastType<Source, Result>::InvalidUnboxing, Result> AsCast(const Source& value)
1305{
1306 return Default<Result>();
1307}
1308
1315template <typename Result, typename Source>
1316std::enable_if_t<Details::CastType<Source, Result>::NullableBoxing, Result> AsCast(const Source& value)
1317{
1318 return Result(value);
1319}
1320
1327template <typename Result, typename Source>
1328std::enable_if_t<Details::CastType<Source, Result>::InterfaceBoxing, typename CastResult<Result>::type>
1329 AsCast(const Source& value)
1330{
1331 if (!ObjectExt::Is<Result>(value))
1332 {
1333 return nullptr;
1334 }
1335
1336 return MakeObject<Source>(value).template Cast<Result, std::false_type>();
1337}
1338
1345template <typename Result, typename Source>
1346std::enable_if_t<Details::CastType<Source, Result>::Boxing, typename CastResult<Result>::type>
1347 AsCast(const Source& value)
1348{
1349 return ObjectExt::Box(value).template Cast<typename CastResult<Result>::type::Pointee_, std::false_type>();
1350}
1351
1358template <typename Result, typename Source>
1359std::enable_if_t<Details::CastType<Source, Result>::UnboxingToString, Result> AsCast(const Source& value)
1360{
1361 return ObjectExt::UnboxStringSafe(value);
1362}
1363
1370template <typename Result, typename Source>
1371std::enable_if_t<Details::CastType<Source, Result>::Null, typename CastResult<Result>::type> AsCast(const Source& value)
1372{
1373 return typename CastResult<Result>::type(nullptr);
1374}
1375
1382template <typename Result, typename Source>
1383std::enable_if_t<Details::CastType<Source, Result>::Array, typename CastResult<Result>::type> AsCast(const Source& value)
1384{
1385 if (!value)
1386 return nullptr;
1387
1388 auto result = MakeArray<typename Result::ValueType>(value->data().size());
1389 auto d_it = result->data().begin();
1390 auto s_it = value->data().begin();
1391 while (s_it != value->data().end())
1392 {
1393 auto& source_element = *(s_it++);
1394 auto& result_element = *(d_it++);
1395
1396 result_element = AsCast<typename Result::ValueType>(source_element);
1397
1398 // Fail entire cast if any element fails
1399 if (source_element != nullptr && result_element == nullptr)
1400 return nullptr;
1401 }
1402
1403 return result;
1404}
1405
1412template <typename T0, typename T1>
1413static auto SafeInvoke(T0&& expr, T1&& func)
1414{
1415 // The type which 'func' actually returns
1416 using retval_t = decltype(func(expr));
1417
1418 // The type which function SafeInvoke will return. Non-nullable types will be wrapped by 'Nullable<>' class template.
1419 using result_t = typename std::conditional<
1420 std::is_base_of<Details::BoxableObjectBase, retval_t>::value || std::is_arithmetic<retval_t>::value || std::is_enum<retval_t>::value,
1422 retval_t>::type;
1423
1424 return expr != nullptr ? result_t(func(expr)) : result_t(nullptr);
1425}
1426
1427} // 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:202
const T & unbox() const
Unboxes the value represented by the current object.
Definition: boxed_value.h:232
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:607
static String ToString(const char_t *obj)
Substitution for C# ToString method to work on any C++ type.
Definition: object_ext.h:98
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:468
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:752
static T0 Coalesce(System::Nullable< T0 > value, T1 func)
Implementation of '??' operator translation for nullable types.
Definition: object_ext.h:715
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:211
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:420
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:129
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:189
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:409
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:311
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:741
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:530
static auto CoalesceAssign(T0 &value, T1 func) -> T0 &
Implementation of '??=' operator translation.
Definition: object_ext.h:727
static bool Is(const Nullable< U > &value)
Implements 'is' operator translation. Specialization for Nullable type.
Definition: object_ext.h:579
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:179
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:282
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:365
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:235
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:382
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:654
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:149
static auto Coalesce(T0 value, T1 func)
Implementation of '??' operator translation for non-nullable types.
Definition: object_ext.h:702
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:300
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:665
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:676
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:548
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:634
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:118
static bool Is(const char16_t *str)
Implements 'is' operator translation. Specialization for string literal.
Definition: object_ext.h:593
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:169
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:351
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:434
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:518
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:496
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:689
static std::enable_if< System::IsBoxable< T >::value, System::SharedPtr< System::Object > >::type ExplicitCastToObject(const T &value)
Definition: object_ext.h:760
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:159
static Nullable< T > UnboxToNullable(const SmartPtr< Object > &obj, bool safe=true)
Unboxes object to nullable type.
Definition: object_ext.h:328
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:624
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:448
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:108
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:261
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:644
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:397
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:766
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:200
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:221
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:139
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 IsNull() const
Checks if string is considered null. String is null and only if it is constructed via String() constr...
Definition: string.h:293
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:1198
static auto SafeInvoke(T0 &&expr, T1 &&func)
Implementation of '?.' operator translation.
Definition: object_ext.h:1413
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:939
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