wip modernize/continue implementation

- Adds is_void_v.

- Uses enable_if to disable operator* and operator[] for void types.

- Uses the new school C++-compatible atomic hack.

- There is no implicit conversion from raw pointers to unique_ptr.

Test compiles and passes now.
This commit is contained in:
Steven Dee (Jōshin) 2024-08-25 21:42:10 -07:00
parent 17589367b1
commit 9bea7950ce
No known key found for this signature in database
4 changed files with 25 additions and 9 deletions

View file

@ -19,6 +19,9 @@ template<typename _Tp>
struct is_void : public is_void_<typename ctl::remove_cv<_Tp>::type>::type struct is_void : public is_void_<typename ctl::remove_cv<_Tp>::type>::type
{}; {};
template <typename T>
constexpr bool is_void_v = is_void<T>::value;
} // namespace ctl } // namespace ctl
#endif // CTL_IS_VOID_H_ #endif // CTL_IS_VOID_H_

View file

@ -23,7 +23,7 @@
namespace { namespace {
inline void inline void
incref(_Atomic(size_t)* r) incref(_CTL_ATOMIC(size_t)* r)
{ {
size_t r2 = atomic_fetch_add_explicit(r, 1, memory_order_relaxed); size_t r2 = atomic_fetch_add_explicit(r, 1, memory_order_relaxed);
if (r2 > ((size_t)-1) >> 1) if (r2 > ((size_t)-1) >> 1)
@ -31,7 +31,7 @@ incref(_Atomic(size_t)* r)
} }
inline int inline int
decref(_Atomic(size_t)* r) decref(_CTL_ATOMIC(size_t)* r)
{ {
if (!atomic_fetch_sub_explicit(r, 1, memory_order_release)) { if (!atomic_fetch_sub_explicit(r, 1, memory_order_release)) {
atomic_thread_fence(memory_order_acquire); atomic_thread_fence(memory_order_acquire);
@ -41,7 +41,7 @@ decref(_Atomic(size_t)* r)
} }
inline size_t inline size_t
getref(const _Atomic(size_t)* r) getref(const _CTL_ATOMIC(size_t)* r)
{ {
return atomic_load_explicit(r, memory_order_relaxed); return atomic_load_explicit(r, memory_order_relaxed);
} }

View file

@ -2,9 +2,18 @@
// 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 "enable_if.h"
#include "is_void.h"
#include "new.h" #include "new.h"
#include "unique_ptr.h" #include "unique_ptr.h"
// TODO(mrdomino): move
#ifndef __cplusplus
#define _CTL_ATOMIC(x) _Atomic(x)
#else
#define _CTL_ATOMIC(x) x
#endif
namespace ctl { namespace ctl {
// TODO(mrdomino): move // TODO(mrdomino): move
@ -20,8 +29,8 @@ namespace __ {
struct shared_control struct shared_control
{ {
_Atomic(size_t) shared; _CTL_ATOMIC(size_t) shared;
_Atomic(size_t) weak; _CTL_ATOMIC(size_t) weak;
constexpr shared_control() noexcept : shared(0), weak(0) constexpr shared_control() noexcept : shared(0), weak(0)
{ {
@ -91,7 +100,7 @@ struct shared_emplace : shared_control
static unique_ptr<shared_emplace> make_unique() static unique_ptr<shared_emplace> make_unique()
{ {
return new shared_emplace(); return unique_ptr(new shared_emplace());
} }
private: private:
@ -201,8 +210,9 @@ class shared_ptr
return p; return p;
} }
// TODO(mrdomino): fix for shared_ptr<void> template <typename U = T>
T& operator*() const noexcept typename enable_if<!is_void_v<U>, U&>::type
operator*() const noexcept
{ {
if (!p) if (!p)
__builtin_trap(); __builtin_trap();
@ -217,7 +227,9 @@ class shared_ptr
return *p; return *p;
} }
element_type& operator[](ptrdiff_t i) const template <typename U = T>
typename enable_if<!is_void_v<U>, U&>::type
operator[](ptrdiff_t i) const
{ {
return *(p + i); return *(p + i);
} }

View file

@ -17,6 +17,7 @@
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
#include "ctl/shared_ptr.h" #include "ctl/shared_ptr.h"
#include "libc/mem/leaks.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"