Loading...
Searching...
No Matches
ref_ptr
// vim:set ft=cpp: -*- Mode: C++ -*-
/*
* (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
* economic rights: Technische Universität Dresden (Germany)
*
* License: see LICENSE.spdx (in this directory or the directories above)
*/
#pragma once
#include "type_traits"
#include <stddef.h>
#include <l4/sys/compiler.h>
namespace cxx {
template< typename T >
struct Default_ref_counter
{
void h_drop_ref(T *p) noexcept
{
if (p->remove_ref() == 0)
delete p;
}
void h_take_ref(T *p) noexcept
{
p->add_ref();
}
};
struct Ref_ptr_base
{
enum Default_value
{ Nil = 0 };
};
template<typename T, template< typename X > class CNT = Default_ref_counter>
class Weak_ptr;
template <
typename T = void,
template< typename X > class CNT = Default_ref_counter
>
class Ref_ptr : public Ref_ptr_base, private CNT<T>
{
private:
typedef decltype(nullptr) Null_type;
typedef Weak_ptr<T, CNT> Wp;
public:
Ref_ptr() noexcept : _p(0) {}
Ref_ptr(Ref_ptr_base::Default_value v)
: _p(reinterpret_cast<T*>(static_cast<unsigned long>(v))) {}
Ref_ptr(Wp const &o) noexcept : _p(o.ptr())
{ __take_ref(); }
Ref_ptr(decltype(nullptr) n) noexcept : _p(n) {}
template<typename X>
explicit Ref_ptr(X *o) noexcept : _p(o)
{ __take_ref(); }
Ref_ptr(T *o, [[maybe_unused]] bool d) noexcept : _p(o) { }
T *get() const noexcept
{
return _p;
}
T *ptr() const noexcept
{
return _p;
}
T *release() noexcept
{
T *p = _p;
_p = 0;
return p;
}
~Ref_ptr() noexcept
{ __drop_ref(); }
template<typename OT>
Ref_ptr(Ref_ptr<OT, CNT> const &o) noexcept
{
_p = o.ptr();
__take_ref();
}
Ref_ptr(Ref_ptr<T> const &o) noexcept
{
_p = o._p;
__take_ref();
}
template< typename OT >
void operator = (Ref_ptr<OT> const &o) noexcept
{
__drop_ref();
_p = o.ptr();
__take_ref();
}
void operator = (Ref_ptr<T> const &o) noexcept
{
if (&o == this)
return;
__drop_ref();
_p = o._p;
__take_ref();
}
void operator = (Null_type) noexcept
{
__drop_ref();
_p = 0;
}
template<typename OT>
Ref_ptr(Ref_ptr<OT, CNT> &&o) noexcept
{ _p = o.release(); }
Ref_ptr(Ref_ptr<T> &&o) noexcept
{ _p = o.release(); }
template< typename OT >
void operator = (Ref_ptr<OT> &&o) noexcept
{
__drop_ref();
_p = o.release();
}
void operator = (Ref_ptr<T> &&o) noexcept
{
if (&o == this)
return;
__drop_ref();
_p = o.release();
}
[[nodiscard]] explicit operator bool () const noexcept { return _p; }
T *operator -> () const noexcept
{ return _p; }
[[nodiscard]] bool operator == (Ref_ptr const &o) const noexcept
{ return _p == o._p; }
[[nodiscard]] bool operator != (Ref_ptr const &o) const noexcept
{ return _p != o._p; }
[[nodiscard]] bool operator < (Ref_ptr const &o) const noexcept
{ return _p < o._p; }
[[nodiscard]] bool operator <= (Ref_ptr const &o) const noexcept
{ return _p <= o._p; }
[[nodiscard]] bool operator > (Ref_ptr const &o) const noexcept
{ return _p > o._p; }
[[nodiscard]] bool operator >= (Ref_ptr const &o) const noexcept
{ return _p >= o._p; }
[[nodiscard]] bool operator == (T const *o) const noexcept
{ return _p == o; }
[[nodiscard]] bool operator < (T const *o) const noexcept
{ return _p < o; }
[[nodiscard]] bool operator <= (T const *o) const noexcept
{ return _p <= o; }
[[nodiscard]] bool operator > (T const *o) const noexcept
{ return _p > o; }
[[nodiscard]] bool operator >= (T const *o) const noexcept
{ return _p >= o; }
private:
void __drop_ref() noexcept
{
if (_p)
static_cast<CNT<T>*>(this)->h_drop_ref(_p);
}
void __take_ref() noexcept
{
if (_p)
static_cast<CNT<T>*>(this)->h_take_ref(_p);
}
T *_p;
};
template<typename T, template< typename X > class CNT>
class Weak_ptr
{
private:
struct Null_type;
typedef Ref_ptr<T, CNT> Rp;
public:
Weak_ptr() = default;
Weak_ptr(decltype(nullptr)) : _p(nullptr) {}
// backwards 0 ctor
explicit Weak_ptr(int x) noexcept
L4_DEPRECATED("Use initialization from 'nullptr'")
: _p(nullptr)
{ if (x != 0) __builtin_trap(); }
Weak_ptr(Rp const &o) noexcept : _p(o.ptr()) {}
explicit Weak_ptr(T *o) noexcept : _p(o) {}
template<typename OT>
Weak_ptr(Weak_ptr<OT, CNT> const &o) noexcept : _p(o.ptr()) {}
Weak_ptr(Weak_ptr<T, CNT> const &o) noexcept : _p(o._p) {}
Weak_ptr<T, CNT> &operator = (const Weak_ptr<T, CNT> &o) = default;
T *get() const noexcept { return _p; }
T *ptr() const noexcept { return _p; }
T *operator -> () const noexcept { return _p; }
operator Null_type const * () const noexcept
{ return reinterpret_cast<Null_type const*>(_p); }
private:
T *_p;
};
template<typename OT, typename T> inline
Ref_ptr<OT> ref_ptr_static_cast(Ref_ptr<T> const &o)
{ return ref_ptr(static_cast<OT*>(o.ptr())); }
template< typename T >
inline Ref_ptr<T> ref_ptr(T *t)
{ return Ref_ptr<T>(t); }
template< typename T >
inline Weak_ptr<T> weak_ptr(T *t)
{ return Weak_ptr<T>(t); }
class Ref_obj
{
private:
mutable int _ref_cnt;
public:
Ref_obj() : _ref_cnt(0) {}
void add_ref() const noexcept { ++_ref_cnt; }
int remove_ref() const noexcept { return --_ref_cnt; }
};
template< typename T, typename... Args >
Ref_ptr<T>
make_ref_obj(Args &&... args)
{ return cxx::Ref_ptr<T>(new T(cxx::forward<Args>(args)...)); }
template<typename T, typename U>
Ref_ptr<T>
dynamic_pointer_cast(Ref_ptr<U> const &p) noexcept
{
// our constructor from a naked pointer increments the counter
return Ref_ptr<T>(dynamic_cast<T *>(p.get()));
}
template<typename T, typename U>
Ref_ptr<T>
static_pointer_cast(Ref_ptr<U> const &p) noexcept
{
// our constructor from a naked pointer increments the counter
return Ref_ptr<T>(static_cast<T *>(p.get()));
}
}
cxx::Ref_ptr
A reference-counting pointer with automatic cleanup.
Definition ref_ptr:71
cxx::Ref_ptr::Ref_ptr
Ref_ptr(Wp const &o) noexcept
Create a shared pointer from a weak pointer.
Definition ref_ptr:88
cxx::Ref_ptr::Ref_ptr
Ref_ptr() noexcept
Default constructor creates a pointer with no managed object.
Definition ref_ptr:78
cxx::Ref_ptr::Ref_ptr
Ref_ptr(decltype(nullptr) n) noexcept
allow creation from nullptr
Definition ref_ptr:92
cxx::Ref_ptr::get
T * get() const noexcept
Return a raw pointer to the object this shared pointer points to.
Definition ref_ptr:121
cxx::Ref_ptr::release
T * release() noexcept
Release the shared pointer without removing the reference.
Definition ref_ptr:138
cxx::Ref_ptr::Ref_ptr
Ref_ptr(X *o) noexcept
Create a shared pointer from a raw pointer.
Definition ref_ptr:101
cxx::Ref_ptr::Ref_ptr
Ref_ptr(T *o, bool d) noexcept
Create a shared pointer from a raw pointer without creating a new reference.
Definition ref_ptr:114
cxx::Ref_ptr::ptr
T * ptr() const noexcept
Return a raw pointer to the object this shared pointer points to.
Definition ref_ptr:127
compiler.h
L4 compiler related defines.
L4_DEPRECATED
#define L4_DEPRECATED(s)
Mark symbol deprecated.
Definition compiler.h:289
cxx
Our C++ library.
Definition arith:11