mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-05 09:20:29 +00:00
Basics of make_shared with anonymous union
This commit is contained in:
parent
0b710a112d
commit
da5817816d
2 changed files with 63 additions and 0 deletions
|
@ -2,6 +2,7 @@
|
||||||
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
// vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi
|
||||||
#ifndef COSMOPOLITAN_CTL_SHARED_PTR_H_
|
#ifndef COSMOPOLITAN_CTL_SHARED_PTR_H_
|
||||||
#define COSMOPOLITAN_CTL_SHARED_PTR_H_
|
#define COSMOPOLITAN_CTL_SHARED_PTR_H_
|
||||||
|
#include "new.h"
|
||||||
#include "unique_ptr.h"
|
#include "unique_ptr.h"
|
||||||
|
|
||||||
namespace ctl {
|
namespace ctl {
|
||||||
|
@ -72,6 +73,39 @@ struct shared_pointer : shared_control
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct shared_emplace : shared_control
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
T t;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void construct(Args&&... args) {
|
||||||
|
::new (&t) T(ctl::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unique_ptr<shared_emplace> make_unique()
|
||||||
|
{
|
||||||
|
return new shared_emplace();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit constexpr shared_emplace() noexcept
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_zero_shared() noexcept override
|
||||||
|
{
|
||||||
|
t.~T();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_zero_weak() noexcept override
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace __
|
} // namespace __
|
||||||
|
|
||||||
struct bad_weak_ptr : ctl::exception
|
struct bad_weak_ptr : ctl::exception
|
||||||
|
@ -203,10 +237,28 @@ class shared_ptr
|
||||||
// TODO(mrdomino): owner_before(weak_ptr const&)
|
// TODO(mrdomino): owner_before(weak_ptr const&)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
constexpr shared_ptr(T* const p, __::shared_control* rc) noexcept
|
||||||
|
: p(p), rc(rc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U, typename... Args>
|
||||||
|
friend shared_ptr<U> make_shared(Args&&... args);
|
||||||
|
|
||||||
T* p;
|
T* p;
|
||||||
__::shared_control* rc;
|
__::shared_control* rc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
shared_ptr<T> make_shared(Args&&... args)
|
||||||
|
{
|
||||||
|
auto rc = __::shared_emplace<T>::make_unique();
|
||||||
|
rc->construct(ctl::forward<Args>(args)...);
|
||||||
|
auto r = shared_ptr<T>(&rc->t, rc.get());
|
||||||
|
rc.release();
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(mrdomino): non-member functions (make_shared et al)
|
// TODO(mrdomino): non-member functions (make_shared et al)
|
||||||
// TODO(mrdomino): weak_ptr
|
// TODO(mrdomino): weak_ptr
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using Ptr = ctl::shared_ptr<T>;
|
using Ptr = ctl::shared_ptr<T>;
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
Ptr<T> Mk(Args&&... args) {
|
||||||
|
return ctl::make_shared<T>(ctl::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
#undef ctl
|
#undef ctl
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -62,6 +67,12 @@ main()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
auto x = Mk<int>(5);
|
||||||
|
if (x.use_count() != 1)
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(mrdomino): exercise more of API
|
// TODO(mrdomino): exercise more of API
|
||||||
// TODO(mrdomino): threading stress-test
|
// TODO(mrdomino): threading stress-test
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue