From 00915e89482994a07321fe0788e12cdab0b761fe Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Sun, 20 Jun 2021 10:04:41 +0200 Subject: [PATCH] AK: Add factory methods for creating smart pointers These functions abstract away the need to call the proper new operator ("throwing" or "non-throwing") and manually adopt the resulting raw pointer. Modelled after the existing `NonnullOwnPtr make()` functions, these forward their parameters to the object's constructor. Note: These can't be used in the common "factory method" idiom, as private constructors can't be called from a standalone function. The naming is consistent with AK's and Shell's previous implementation of these: - `make` creates a `NonnullOwnPtr` and aborts if the allocation could not be performed. - `try_make` creates an `OwnPtr`, which may be null if the allocation failed. - `create` creates a `NonnullRefPtr`, and aborts on allocation failure. - `try_create` creates a `RefPtr`, which may be null if the allocation was not successful. --- AK/NonnullOwnPtr.h | 3 +-- AK/NonnullRefPtr.h | 7 +++++++ AK/OwnPtr.h | 7 +++++++ AK/RefPtr.h | 7 +++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/AK/NonnullOwnPtr.h b/AK/NonnullOwnPtr.h index 6e3f3b5963..cd4a862460 100644 --- a/AK/NonnullOwnPtr.h +++ b/AK/NonnullOwnPtr.h @@ -154,8 +154,7 @@ inline NonnullOwnPtr adopt_own(T& object) #endif template -inline NonnullOwnPtr -make(Args&&... args) +inline NonnullOwnPtr make(Args&&... args) { return NonnullOwnPtr(NonnullOwnPtr::Adopt, *new T(forward(args)...)); } diff --git a/AK/NonnullRefPtr.h b/AK/NonnullRefPtr.h index 27d9c06a56..22936a2dfc 100644 --- a/AK/NonnullRefPtr.h +++ b/AK/NonnullRefPtr.h @@ -335,6 +335,12 @@ inline void swap(NonnullRefPtr& a, NonnullRefPtr& b) a.swap(b); } +template +inline NonnullRefPtr create(Args&&... args) +{ + return NonnullRefPtr(NonnullRefPtr::Adopt, *new T(forward(args)...)); +} + } template @@ -346,4 +352,5 @@ struct Traits> : public GenericTraits> { }; using AK::adopt_ref; +using AK::create; using AK::NonnullRefPtr; diff --git a/AK/OwnPtr.h b/AK/OwnPtr.h index 8708f79a24..3eb42d1c36 100644 --- a/AK/OwnPtr.h +++ b/AK/OwnPtr.h @@ -206,6 +206,12 @@ inline OwnPtr adopt_own_if_nonnull(T* object) return {}; } +template +inline OwnPtr try_make(Args&&... args) +{ + return adopt_own_if_nonnull(new (nothrow) T(forward(args)...)); +} + template struct Traits> : public GenericTraits> { using PeekType = T*; @@ -218,3 +224,4 @@ struct Traits> : public GenericTraits> { using AK::adopt_own_if_nonnull; using AK::OwnPtr; +using AK::try_make; diff --git a/AK/RefPtr.h b/AK/RefPtr.h index b8063b17a1..7e8e6b573e 100644 --- a/AK/RefPtr.h +++ b/AK/RefPtr.h @@ -485,8 +485,15 @@ inline RefPtr adopt_ref_if_nonnull(T* object) return {}; } +template +inline RefPtr try_create(Args&&... args) +{ + return adopt_ref_if_nonnull(new (nothrow) T(forward(args)...)); +} + } using AK::adopt_ref_if_nonnull; using AK::RefPtr; using AK::static_ptr_cast; +using AK::try_create;