Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92f808f0 authored by Jooyung Han's avatar Jooyung Han Committed by Automerger Merge Worker
Browse files

Merge "libbinder: fix ToString() for smart pointers" am: 616ddc4f am: 06863efc am: da671049

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1589291

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I30fc85023a60a111317bdba8cb0c104932a4b88a
parents 7fbb3083 da671049
Loading
Loading
Loading
Loading
+37 −11
Original line number Diff line number Diff line
@@ -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}";
    }