mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-05 17:30:27 +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
|
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_
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue