Add weak self make_shared variant (#1299)

This extends the CTL version of make_shared with functionality not found
in the STL, with inspiration taken from Rust's Rc class.
This commit is contained in:
Steven Dee (Jōshin) 2024-09-17 18:46:23 -04:00 committed by GitHub
parent aaed879ec7
commit 1bfb348403
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 97 additions and 8 deletions

View file

@ -16,6 +16,7 @@
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include "ctl/is_same.h"
#include "ctl/shared_ptr.h"
#include "ctl/vector.h"
#include "libc/mem/leaks.h"
@ -88,6 +89,21 @@ class SharedThis : public enable_shared_from_this<SharedThis>
class CanShareThis : public enable_shared_from_this<CanShareThis>
{};
// Sample class used to demonstrate the CTL shared_ptr's weak_self feature.
struct Tree : ctl::weak_self_base
{
ctl::shared_ptr<Tree> l, r;
ctl::weak_ptr<Tree> p;
Tree(ctl::weak_ptr<Tree> const& self, auto&& l2, auto&& r2)
: l(ctl::forward<decltype(l2)>(l2)), r(ctl::forward<decltype(r2)>(r2))
{
if (l)
l->p = self;
if (r)
r->p = self;
}
};
int
main()
{
@ -276,6 +292,19 @@ main()
return 25;
}
if constexpr (ctl::is_same_v<shared_ptr<Tree>, ctl::shared_ptr<Tree>>) {
// Exercise our off-STL make_shared with weak self support.
auto t = ctl::make_shared<Tree>(
ctl::make_shared<Tree>(ctl::make_shared<Tree>(nullptr, nullptr),
nullptr),
ctl::make_shared<Tree>(nullptr, nullptr));
auto t2 = t->l->l->p.lock()->p.lock();
if (t.owner_before(t2) || t2.owner_before(t))
return 26;
if (!t.owner_before(t->l) && !t->l.owner_before(t))
return 27;
}
// TODO(mrdomino): exercise threads / races. The reference count should be
// atomically maintained.