Merge "first_stage_init: Optimize redundant vector copy"
diff --git a/libutils/include/utils/RefBase.h b/libutils/include/utils/RefBase.h
index e07f574..f3acd6f 100644
--- a/libutils/include/utils/RefBase.h
+++ b/libutils/include/utils/RefBase.h
@@ -779,6 +779,40 @@
} // 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