diff --git a/ctl/is_void.h b/ctl/is_void.h index 04c33145c..29ae4ab8a 100644 --- a/ctl/is_void.h +++ b/ctl/is_void.h @@ -19,6 +19,9 @@ template struct is_void : public is_void_::type>::type {}; +template +constexpr bool is_void_v = is_void::value; + } // namespace ctl #endif // CTL_IS_VOID_H_ diff --git a/ctl/shared_ptr.cc b/ctl/shared_ptr.cc index 3da50a074..98dd115b3 100644 --- a/ctl/shared_ptr.cc +++ b/ctl/shared_ptr.cc @@ -23,7 +23,7 @@ namespace { 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); if (r2 > ((size_t)-1) >> 1) @@ -31,7 +31,7 @@ incref(_Atomic(size_t)* r) } inline int -decref(_Atomic(size_t)* r) +decref(_CTL_ATOMIC(size_t)* r) { if (!atomic_fetch_sub_explicit(r, 1, memory_order_release)) { atomic_thread_fence(memory_order_acquire); @@ -41,7 +41,7 @@ decref(_Atomic(size_t)* r) } inline size_t -getref(const _Atomic(size_t)* r) +getref(const _CTL_ATOMIC(size_t)* r) { return atomic_load_explicit(r, memory_order_relaxed); } diff --git a/ctl/shared_ptr.h b/ctl/shared_ptr.h index 8cb5a021f..ed33a3a98 100644 --- a/ctl/shared_ptr.h +++ b/ctl/shared_ptr.h @@ -2,9 +2,18 @@ // vi: set et ft=cpp ts=4 sts=4 sw=4 fenc=utf-8 :vi #ifndef COSMOPOLITAN_CTL_SHARED_PTR_H_ #define COSMOPOLITAN_CTL_SHARED_PTR_H_ +#include "enable_if.h" +#include "is_void.h" #include "new.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 { // TODO(mrdomino): move @@ -20,8 +29,8 @@ namespace __ { struct shared_control { - _Atomic(size_t) shared; - _Atomic(size_t) weak; + _CTL_ATOMIC(size_t) shared; + _CTL_ATOMIC(size_t) weak; constexpr shared_control() noexcept : shared(0), weak(0) { @@ -91,7 +100,7 @@ struct shared_emplace : shared_control static unique_ptr make_unique() { - return new shared_emplace(); + return unique_ptr(new shared_emplace()); } private: @@ -201,8 +210,9 @@ class shared_ptr return p; } - // TODO(mrdomino): fix for shared_ptr - T& operator*() const noexcept + template + typename enable_if, U&>::type + operator*() const noexcept { if (!p) __builtin_trap(); @@ -217,7 +227,9 @@ class shared_ptr return *p; } - element_type& operator[](ptrdiff_t i) const + template + typename enable_if, U&>::type + operator[](ptrdiff_t i) const { return *(p + i); } diff --git a/test/ctl/shared_ptr_test.cc b/test/ctl/shared_ptr_test.cc index 2e3b40ab8..46d76504c 100644 --- a/test/ctl/shared_ptr_test.cc +++ b/test/ctl/shared_ptr_test.cc @@ -17,6 +17,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include "ctl/shared_ptr.h" +#include "libc/mem/leaks.h" #include "libc/runtime/runtime.h"