Loading libs/binder/ndk/include_cpp/android/binder_to_string.h +37 −11 Original line number Diff line number Diff line Loading @@ -28,10 +28,22 @@ #include <codecvt> #include <locale> #include <memory> #include <optional> #include <sstream> #include <string> #include <type_traits> #if __has_include(<utils/StrongPointer.h>) #include <utils/StrongPointer.h> #define HAS_STRONG_POINTER #endif #if __has_include(<utils/String16.h>) #include <utils/String16.h> #define HAS_STRING16 #endif #if __has_include(<android/binder_ibinder.h>) #include <android/binder_auto_utils.h> #include <android/binder_interface_utils.h> Loading @@ -42,9 +54,6 @@ #include <binder/IInterface.h> #include <binder/ParcelFileDescriptor.h> #include <binder/ParcelableHolder.h> #include <utils/String16.h> #include <utils/StrongPointer.h> #define HAS_CPP_INTERFACE #endif //_has_include namespace android { Loading Loading @@ -80,11 +89,28 @@ class HasToStringFunction { enum { value = decltype(_test<_T>(0))::value }; }; // Truthy if _T is like a pointer template <typename T, template <typename...> typename U> struct IsInstantiationOf : std::false_type {}; template <template <typename...> typename U, typename... Args> struct IsInstantiationOf<U<Args...>, U> : std::true_type {}; // Truthy if _T is like a pointer: one of sp/optional/shared_ptr template <typename _T> class IsPointerLike { template <typename _U> static auto _test(int) -> decltype(!std::declval<_U>(), *std::declval<_U>(), std::true_type()); static std::enable_if_t< #ifdef HAS_STRONG_POINTER IsInstantiationOf<_U, sp>::value || // for IBinder and interface types in the C++ // backend #endif IsInstantiationOf<_U, std::optional>::value || // for @nullable types in the // C++/NDK backends IsInstantiationOf<_U, std::shared_ptr>::value, // for interface types in the // NDK backends std::true_type> _test(int); template <typename _U> static std::false_type _test(...); Loading Loading @@ -142,12 +168,17 @@ std::string ToString(const _T& t) { return std::to_string(t); } else if constexpr (std::is_same_v<std::string, _T>) { return t; #ifdef HAS_CPP_INTERFACE #ifdef HAS_STRING16 } else if constexpr (std::is_same_v<String16, _T>) { std::stringstream out; out << t; return out.str(); #endif } else if constexpr (details::IsPointerLike<_T>::value) { if (!t) return "(null)"; std::stringstream out; out << ToString(*t); return out.str(); } else if constexpr (details::HasToStringMethod<_T>::value) { return t.toString(); } else if constexpr (details::HasToStringFunction<_T>::value) { Loading @@ -168,11 +199,6 @@ std::string ToString(const _T& t) { } out << "]"; return out.str(); } else if constexpr (details::IsPointerLike<_T>::value) { if (!t) return "(null)"; std::stringstream out; out << ToString(*t); return out.str(); } else { return "{no toString() implemented}"; } Loading Loading
libs/binder/ndk/include_cpp/android/binder_to_string.h +37 −11 Original line number Diff line number Diff line Loading @@ -28,10 +28,22 @@ #include <codecvt> #include <locale> #include <memory> #include <optional> #include <sstream> #include <string> #include <type_traits> #if __has_include(<utils/StrongPointer.h>) #include <utils/StrongPointer.h> #define HAS_STRONG_POINTER #endif #if __has_include(<utils/String16.h>) #include <utils/String16.h> #define HAS_STRING16 #endif #if __has_include(<android/binder_ibinder.h>) #include <android/binder_auto_utils.h> #include <android/binder_interface_utils.h> Loading @@ -42,9 +54,6 @@ #include <binder/IInterface.h> #include <binder/ParcelFileDescriptor.h> #include <binder/ParcelableHolder.h> #include <utils/String16.h> #include <utils/StrongPointer.h> #define HAS_CPP_INTERFACE #endif //_has_include namespace android { Loading Loading @@ -80,11 +89,28 @@ class HasToStringFunction { enum { value = decltype(_test<_T>(0))::value }; }; // Truthy if _T is like a pointer template <typename T, template <typename...> typename U> struct IsInstantiationOf : std::false_type {}; template <template <typename...> typename U, typename... Args> struct IsInstantiationOf<U<Args...>, U> : std::true_type {}; // Truthy if _T is like a pointer: one of sp/optional/shared_ptr template <typename _T> class IsPointerLike { template <typename _U> static auto _test(int) -> decltype(!std::declval<_U>(), *std::declval<_U>(), std::true_type()); static std::enable_if_t< #ifdef HAS_STRONG_POINTER IsInstantiationOf<_U, sp>::value || // for IBinder and interface types in the C++ // backend #endif IsInstantiationOf<_U, std::optional>::value || // for @nullable types in the // C++/NDK backends IsInstantiationOf<_U, std::shared_ptr>::value, // for interface types in the // NDK backends std::true_type> _test(int); template <typename _U> static std::false_type _test(...); Loading Loading @@ -142,12 +168,17 @@ std::string ToString(const _T& t) { return std::to_string(t); } else if constexpr (std::is_same_v<std::string, _T>) { return t; #ifdef HAS_CPP_INTERFACE #ifdef HAS_STRING16 } else if constexpr (std::is_same_v<String16, _T>) { std::stringstream out; out << t; return out.str(); #endif } else if constexpr (details::IsPointerLike<_T>::value) { if (!t) return "(null)"; std::stringstream out; out << ToString(*t); return out.str(); } else if constexpr (details::HasToStringMethod<_T>::value) { return t.toString(); } else if constexpr (details::HasToStringFunction<_T>::value) { Loading @@ -168,11 +199,6 @@ std::string ToString(const _T& t) { } out << "]"; return out.str(); } else if constexpr (details::IsPointerLike<_T>::value) { if (!t) return "(null)"; std::stringstream out; out << ToString(*t); return out.str(); } else { return "{no toString() implemented}"; } Loading