diff options
author | 2021-02-17 02:38:25 +0000 | |
---|---|---|
committer | 2021-02-17 02:38:25 +0000 | |
commit | 92f808f013a348e3fdc38e940052c6e40531d54c (patch) | |
tree | 7b4efd24688122dd5110033583a323e0f9b06992 | |
parent | 7fbb3083b2b657e291250cae2cb44eac6b481970 (diff) | |
parent | da671049875c4a195cc1e922ec93c8cf2ecaa4fe (diff) |
Merge "libbinder: fix ToString() for smart pointers" am: 616ddc4f6f am: 06863efc21 am: da67104987
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1589291
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I30fc85023a60a111317bdba8cb0c104932a4b88a
-rw-r--r-- | libs/binder/ndk/include_cpp/android/binder_to_string.h | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/libs/binder/ndk/include_cpp/android/binder_to_string.h b/libs/binder/ndk/include_cpp/android/binder_to_string.h index bd51b1167f..584292551b 100644 --- a/libs/binder/ndk/include_cpp/android/binder_to_string.h +++ b/libs/binder/ndk/include_cpp/android/binder_to_string.h @@ -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> @@ -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 { @@ -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(...); @@ -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) { @@ -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}"; } |