Loading libutils/include/utils/RefBase.h +34 −0 Original line number Diff line number Diff line Loading @@ -779,6 +779,40 @@ void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { } // namespace android namespace libutilsinternal { template <typename T, typename = void> struct is_complete_type : std::false_type {}; template <typename T> struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {}; } // namespace libutilsinternal namespace std { // Define `RefBase` specific versions of `std::make_shared` and // `std::make_unique` to block people from using them. Using them to allocate // `RefBase` objects results in double ownership. Use // `sp<T>::make(...)` instead. // // Note: We exclude incomplete types because `std::is_base_of` is undefined in // that case. template <typename T, typename... Args, typename std::enable_if<libutilsinternal::is_complete_type<T>::value, bool>::value = true, typename std::enable_if<std::is_base_of<android::RefBase, T>::value, bool>::value = true> shared_ptr<T> make_shared(Args...) { // SEE COMMENT ABOVE. static_assert(!std::is_base_of<android::RefBase, T>::value, "Must use RefBase with sp<>"); } template <typename T, typename... Args, typename std::enable_if<libutilsinternal::is_complete_type<T>::value, bool>::value = true, typename std::enable_if<std::is_base_of<android::RefBase, T>::value, bool>::value = true> unique_ptr<T> make_unique(Args...) { // SEE COMMENT ABOVE. static_assert(!std::is_base_of<android::RefBase, T>::value, "Must use RefBase with sp<>"); } } // namespace std // --------------------------------------------------------------------------- #endif // ANDROID_REF_BASE_H Loading
libutils/include/utils/RefBase.h +34 −0 Original line number Diff line number Diff line Loading @@ -779,6 +779,40 @@ void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) { } // namespace android namespace libutilsinternal { template <typename T, typename = void> struct is_complete_type : std::false_type {}; template <typename T> struct is_complete_type<T, decltype(void(sizeof(T)))> : std::true_type {}; } // namespace libutilsinternal namespace std { // Define `RefBase` specific versions of `std::make_shared` and // `std::make_unique` to block people from using them. Using them to allocate // `RefBase` objects results in double ownership. Use // `sp<T>::make(...)` instead. // // Note: We exclude incomplete types because `std::is_base_of` is undefined in // that case. template <typename T, typename... Args, typename std::enable_if<libutilsinternal::is_complete_type<T>::value, bool>::value = true, typename std::enable_if<std::is_base_of<android::RefBase, T>::value, bool>::value = true> shared_ptr<T> make_shared(Args...) { // SEE COMMENT ABOVE. static_assert(!std::is_base_of<android::RefBase, T>::value, "Must use RefBase with sp<>"); } template <typename T, typename... Args, typename std::enable_if<libutilsinternal::is_complete_type<T>::value, bool>::value = true, typename std::enable_if<std::is_base_of<android::RefBase, T>::value, bool>::value = true> unique_ptr<T> make_unique(Args...) { // SEE COMMENT ABOVE. static_assert(!std::is_base_of<android::RefBase, T>::value, "Must use RefBase with sp<>"); } } // namespace std // --------------------------------------------------------------------------- #endif // ANDROID_REF_BASE_H