13 #if __cplusplus
<201103L
14 # error c++11
required 21 #include <pv/epicsException.h> 27 #define HAVE_SHOW_REFS 33 class shared_ptr_base;
36 friend class shared_ptr_base;
38 friend class shared_ptr;
40 friend class weak_ptr;
42 typedef std::shared_ptr<tracker> track_t;
45 ptr_base()
noexcept : track() {}
46 ptr_base(
const track_t& track) :track(track) {}
47 ptr_base(
const ptr_base&) =
delete;
48 ptr_base(ptr_base&&) =
delete;
50 ptr_base& operator=(
const ptr_base&) =
delete;
53 typedef std::set<
const shared_ptr_base *> ref_set_t;
54 void show_refs(std::ostream&,
bool self=
true,
bool weak=
false)
const;
55 void spy_refs(ref_set_t&)
const;
61 weak_ptr_base(
const track_t& track) :ptr_base(track) {}
66 shared_ptr_base()
noexcept 67 #ifndef EXCEPT_USE_NONE 68 :m_stack(), m_depth(0)
71 shared_ptr_base(
const track_t& track) :ptr_base(track)
72 #ifndef EXCEPT_USE_NONE 73 ,m_stack(), m_depth(0)
76 ~shared_ptr_base() {track_clear();}
81 void track_new(
void* ptr);
83 void track_assign(
const shared_ptr_base& o);
85 void swap(shared_ptr_base& o);
88 #ifndef EXCEPT_USE_NONE 94 void show_stack(std::ostream&)
const;
104 class enable_shared_from_this;
106 template<
typename Store,
typename Actual>
108 do_enable_shared_from_this(
const shared_ptr<Store>& dest,
109 enable_shared_from_this<Actual>* self
114 do_enable_shared_from_this(
const shared_ptr<T>&, ...) {}
117 class shared_ptr :
public shared_ptr_base {
118 typedef ::std::shared_ptr<T> real_type;
123 friend class shared_ptr;
125 friend class weak_ptr;
128 shared_ptr(
const real_type& r,
const ptr_base::track_t& t)
129 :shared_ptr_base(t), real(r)
132 typedef typename real_type::element_type element_type;
133 typedef weak_ptr<T> weak_type;
136 shared_ptr()
noexcept {}
138 shared_ptr(
const shared_ptr& o) :shared_ptr_base(o.track), real(o.real) {track_new();}
141 shared_ptr(
const shared_ptr<A>& o) :shared_ptr_base(o.track), real(o.real) {track_new();}
144 template<
typename A,
class ... Args>
145 explicit shared_ptr(A* a, Args ... args) : shared_ptr_base(), real(a, args...) {
147 do_enable_shared_from_this(*
this, a);
152 shared_ptr(
const weak_ptr<A>& o) :shared_ptr_base(o.track), real(o.real) {track_new();}
156 shared_ptr(std::unique_ptr<A>&& a) : shared_ptr_base(), real(a.release()) {track_new();}
160 shared_ptr& operator=(
const shared_ptr& o) {
168 shared_ptr& operator=(
const shared_ptr<A>& o) {
176 void reset()
noexcept { real.reset(); track_clear(); }
177 template<
typename A,
class ... Args>
178 void reset(A* a, Args ... args)
180 real.reset(a, args...);
182 do_enable_shared_from_this(*
this, a);
184 void swap(shared_ptr &o)
noexcept 188 shared_ptr_base::swap(o);
194 T* get()
const noexcept {
return real.get(); }
195 typename std::add_lvalue_reference<T>::type operator*()
const noexcept {
return *real; }
196 T* operator->()
const noexcept {
return real.get(); }
197 long use_count()
const noexcept {
return real.use_count(); }
198 bool unique()
const noexcept {
return real.unique(); }
199 explicit operator
bool()
const noexcept {
return bool(real); }
201 bool operator==(
const shared_ptr<T>& o)
const {
return real==o.real; }
202 bool operator!=(
const shared_ptr<T>& o)
const {
return real!=o.real; }
203 bool operator<(
const shared_ptr<T>& o)
const {
return real<o.real; }
206 bool owner_before(
const shared_ptr<A>& o) {
return real.owner_before(o); }
208 bool owner_before(
const weak_ptr<A>& o) {
return real.owner_before(o); }
210 template<
typename TO,
typename FROM>
212 shared_ptr<TO> static_pointer_cast(
const shared_ptr<FROM>& src);
213 template<
typename TO,
typename FROM>
215 shared_ptr<TO> const_pointer_cast(
const shared_ptr<FROM>& src);
216 template<
typename TO,
typename FROM>
218 shared_ptr<TO> dynamic_pointer_cast(
const shared_ptr<FROM>& src);
219 template<
typename Store,
typename Actual>
221 do_enable_shared_from_this(
const shared_ptr<Store>& dest,
222 enable_shared_from_this<Actual>* self
226 template<
typename TO,
typename FROM>
227 shared_ptr<TO> static_pointer_cast(
const shared_ptr<FROM>& src) {
228 return shared_ptr<TO>(std::static_pointer_cast<TO>(src.real), src.track);
231 template<
typename TO,
typename FROM>
232 shared_ptr<TO> const_pointer_cast(
const shared_ptr<FROM>& src) {
233 return shared_ptr<TO>(std::const_pointer_cast<TO>(src.real), src.track);
236 template<
typename TO,
typename FROM>
237 shared_ptr<TO> dynamic_pointer_cast(
const shared_ptr<FROM>& src) {
238 return shared_ptr<TO>(std::dynamic_pointer_cast<TO>(src.real), src.track);
242 class weak_ptr :
public weak_ptr_base {
243 typedef ::std::weak_ptr<T> real_type;
248 friend class shared_ptr;
250 friend class weak_ptr;
253 typedef typename real_type::element_type element_type;
254 typedef weak_ptr<T> weak_type;
257 weak_ptr()
noexcept {}
259 weak_ptr(
const weak_ptr& o) :weak_ptr_base(o.track), real(o.real) {}
262 weak_ptr(
const weak_ptr<A>& o) :weak_ptr_base(o.track), real(o.real) {}
266 weak_ptr(
const shared_ptr<A>& o) :weak_ptr_base(o.track), real(o.real) {}
270 weak_ptr& operator=(
const weak_ptr& o) {
278 weak_ptr& operator=(
const shared_ptr<A>& o) {
284 shared_ptr<T> lock()
const noexcept {
return shared_ptr<T>(real.lock(), track); }
285 void reset()
noexcept { track.reset(); real.reset(); }
287 long use_count()
const noexcept {
return real.use_count(); }
288 bool unique()
const noexcept {
return real.unique(); }
292 class enable_shared_from_this {
293 mutable weak_ptr<Base> xxInternalSelf;
295 template<
typename Store,
typename Actual>
298 do_enable_shared_from_this(
const shared_ptr<Store>& dest,
299 enable_shared_from_this<Actual>* self
302 shared_ptr<Base> shared_from_this()
const {
303 return shared_ptr<Base>(xxInternalSelf);
307 template<
typename Store,
typename Actual>
309 do_enable_shared_from_this(
const shared_ptr<Store>& dest,
310 enable_shared_from_this<Actual>* self
313 shared_ptr<Actual> actual(dynamic_pointer_cast<Actual>(dest));
315 throw std::logic_error(
"epics::debug::enabled_shared_from_this fails");
316 self->xxInternalSelf = actual;
322 inline std::ostream& operator<<(std::ostream& strm,
const epics::debug::shared_ptr<T>& ptr)