mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-03 08:20:28 +00:00
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:
parent
17589367b1
commit
9bea7950ce
4 changed files with 25 additions and 9 deletions
|
@ -19,6 +19,9 @@ template<typename _Tp>
|
|||
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
|
||||
|
||||
#endif // CTL_IS_VOID_H_
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<shared_emplace> 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<void>
|
||||
T& operator*() const noexcept
|
||||
template <typename U = T>
|
||||
typename enable_if<!is_void_v<U>, 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 U = T>
|
||||
typename enable_if<!is_void_v<U>, U&>::type
|
||||
operator[](ptrdiff_t i) const
|
||||
{
|
||||
return *(p + i);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#include "ctl/shared_ptr.h"
|
||||
#include "libc/mem/leaks.h"
|
||||
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue