1e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton//===---------------------SharingPtr.h --------------------------*- C++ -*-===//
2e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton//
3e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton//                     The LLVM Compiler Infrastructure
4e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton//
5e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton// This file is distributed under the University of Illinois Open Source
6e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton// License. See LICENSE.TXT for details.
7e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton//
8e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton//===----------------------------------------------------------------------===//
9e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
10e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton#ifndef utility_SharingPtr_h_
11e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton#define utility_SharingPtr_h_
12e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
13e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton#include <algorithm>
14576b9655c887f7ec0d7389ac856d5d7e3f3ec8ffGreg Clayton#include <memory>
15e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
16666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton//#define ENABLE_SP_LOGGING 1 // DON'T CHECK THIS LINE IN UNLESS COMMENTED OUT
17666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton#if defined (ENABLE_SP_LOGGING)
18666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton
19666c553ca803df25b7fc1e53cb8616449f4ce308Greg Claytonextern "C" void track_sp (void *sp_this, void *ptr, long count);
20666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton
21666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton#endif
22666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton
236a5aa8ab240a13f397e3e09f2ca1ea3f16b451c2Greg Claytonnamespace lldb_private {
24e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
25e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonnamespace imp {
26987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton
27987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Claytontemplate <class T>
28987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Claytoninline T
29987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Claytonincrement(T& t)
30987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton{
31987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    return __sync_add_and_fetch(&t, 1);
32987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton}
33987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton
34987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Claytontemplate <class T>
35987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Claytoninline T
36987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Claytondecrement(T& t)
37987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton{
38987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    return __sync_add_and_fetch(&t, -1);
39987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton}
40e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
41e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonclass shared_count
42e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
43e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    shared_count(const shared_count&);
44e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    shared_count& operator=(const shared_count&);
45e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
46e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonprotected:
47e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    long shared_owners_;
48e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    virtual ~shared_count();
49e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonprivate:
50e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    virtual void on_zero_shared() = 0;
51e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
52e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonpublic:
53e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    explicit shared_count(long refs = 0)
54e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton        : shared_owners_(refs) {}
55e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
56e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    void add_shared();
57e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    void release_shared();
58e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    long use_count() const {return shared_owners_ + 1;}
59e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton};
60e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
61e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate <class T>
62e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonclass shared_ptr_pointer
63e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    : public shared_count
64e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
65e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    T data_;
66e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonpublic:
67e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    shared_ptr_pointer(T p)
68e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton        :  data_(p) {}
69e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
70e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonprivate:
71e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    virtual void on_zero_shared();
72bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton
73bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton    // Outlaw copy constructor and assignment operator to keep effictive C++
74bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton    // warnings down to a minumum
75bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton    shared_ptr_pointer (const shared_ptr_pointer &);
76bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton    shared_ptr_pointer & operator=(const shared_ptr_pointer &);
77e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton};
78e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
79e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate <class T>
80e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonvoid
81e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonshared_ptr_pointer<T>::on_zero_shared()
82e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
83e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    delete data_;
84e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
85e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
86101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate <class T>
87101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonclass shared_ptr_emplace
88101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    : public shared_count
89101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
90101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    T data_;
91101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonpublic:
92101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
93101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    shared_ptr_emplace()
94101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        :  data_() {}
95101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
96101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template <class A0>
97101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        shared_ptr_emplace(A0& a0)
98101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton            :  data_(a0) {}
99101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
100101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template <class A0, class A1>
101101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        shared_ptr_emplace(A0& a0, A1& a1)
102101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton            :  data_(a0, a1) {}
103101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
104101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template <class A0, class A1, class A2>
105101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        shared_ptr_emplace(A0& a0, A1& a1, A2& a2)
106101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton            :  data_(a0, a1, a2) {}
107101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
108101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template <class A0, class A1, class A2, class A3>
109101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        shared_ptr_emplace(A0& a0, A1& a1, A2& a2, A3& a3)
110101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton            :  data_(a0, a1, a2, a3) {}
111101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
112101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template <class A0, class A1, class A2, class A3, class A4>
113101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        shared_ptr_emplace(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4)
114101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton            :  data_(a0, a1, a2, a3, a4) {}
115101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
116101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonprivate:
117101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    virtual void on_zero_shared();
118101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonpublic:
119101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    T* get() {return &data_;}
120101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton};
121101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
122101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate <class T>
123101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonvoid
124101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonshared_ptr_emplace<T>::on_zero_shared()
125101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
126101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
127101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
128e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}  // namespace
129e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
130e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
131e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonclass SharingPtr
132e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
133e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonpublic:
134e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    typedef T element_type;
135e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonprivate:
136e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    element_type*      ptr_;
137e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    imp::shared_count* cntrl_;
138e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
13917b71361774cce1c5cbc2b31e0181a932634073dEli Friedman    struct nat {int for_bool_;};
140e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonpublic:
141e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    SharingPtr();
142e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    template<class Y> explicit SharingPtr(Y* p);
14347da810225d8674eb9158bcf5f1f5b847cbaeedfJim Ingham    template<class Y> explicit SharingPtr(Y* p, imp::shared_count *ctrl_block);
144e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    template<class Y> SharingPtr(const SharingPtr<Y>& r, element_type *p);
145e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    SharingPtr(const SharingPtr& r);
146e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    template<class Y>
147e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton        SharingPtr(const SharingPtr<Y>& r);
148e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
149e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    ~SharingPtr();
150e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
151e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    SharingPtr& operator=(const SharingPtr& r);
152e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    template<class Y> SharingPtr& operator=(const SharingPtr<Y>& r);
153e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
154e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    void swap(SharingPtr& r);
155e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    void reset();
156e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    template<class Y> void reset(Y* p);
157e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
158e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    element_type* get() const {return ptr_;}
159e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    element_type& operator*() const {return *ptr_;}
160e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    element_type* operator->() const {return ptr_;}
161e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    long use_count() const {return cntrl_ ? cntrl_->use_count() : 0;}
162e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    bool unique() const {return use_count() == 1;}
163e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    bool empty() const {return cntrl_ == 0;}
16417b71361774cce1c5cbc2b31e0181a932634073dEli Friedman    operator nat*() const {return (nat*)get();}
165e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
166101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    static SharingPtr<T> make_shared();
167101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
168101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template<class A0>
169101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        static SharingPtr<T> make_shared(A0&);
170101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
171101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template<class A0, class A1>
172101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        static SharingPtr<T> make_shared(A0&, A1&);
173101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
174101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template<class A0, class A1, class A2>
175101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        static SharingPtr<T> make_shared(A0&, A1&, A2&);
176101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
177101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template<class A0, class A1, class A2, class A3>
178101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        static SharingPtr<T> make_shared(A0&, A1&, A2&, A3&);
179101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
180101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    template<class A0, class A1, class A2, class A3, class A4>
181101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton        static SharingPtr<T> make_shared(A0&, A1&, A2&, A3&, A4&);
182101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
183e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonprivate:
184e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
185e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    template <class U> friend class SharingPtr;
186e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton};
187e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
188e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
189e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
190e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::SharingPtr()
191e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    : ptr_(0),
192e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton      cntrl_(0)
193e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
194e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
195e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
196e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
197e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class Y>
198e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::SharingPtr(Y* p)
199bdcb6abaa287df2c5f312c51d993c1d0b0cb120cGreg Clayton    : ptr_(p), cntrl_(0)
200e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
201102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton    std::unique_ptr<Y> hold(p);
202e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    typedef imp::shared_ptr_pointer<Y*> _CntrlBlk;
203e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    cntrl_ = new _CntrlBlk(p);
204e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    hold.release();
205e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
206e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
207e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
208e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class Y>
20947da810225d8674eb9158bcf5f1f5b847cbaeedfJim InghamSharingPtr<T>::SharingPtr(Y* p, imp::shared_count *cntrl_block)
21047da810225d8674eb9158bcf5f1f5b847cbaeedfJim Ingham    : ptr_(p), cntrl_(cntrl_block)
21147da810225d8674eb9158bcf5f1f5b847cbaeedfJim Ingham{
21247da810225d8674eb9158bcf5f1f5b847cbaeedfJim Ingham}
21347da810225d8674eb9158bcf5f1f5b847cbaeedfJim Ingham
21447da810225d8674eb9158bcf5f1f5b847cbaeedfJim Inghamtemplate<class T>
21547da810225d8674eb9158bcf5f1f5b847cbaeedfJim Inghamtemplate<class Y>
216e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
217e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::SharingPtr(const SharingPtr<Y>& r, element_type *p)
218e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    : ptr_(p),
219e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton      cntrl_(r.cntrl_)
220e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
221e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    if (cntrl_)
222e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton        cntrl_->add_shared();
223e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
224e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
225e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
226e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
227e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::SharingPtr(const SharingPtr& r)
228e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    : ptr_(r.ptr_),
229e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton      cntrl_(r.cntrl_)
230e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
231e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    if (cntrl_)
232e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton        cntrl_->add_shared();
233e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
234e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
235e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
236e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class Y>
237e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
238e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::SharingPtr(const SharingPtr<Y>& r)
239e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    : ptr_(r.ptr_),
240e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton      cntrl_(r.cntrl_)
241e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
242e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    if (cntrl_)
243e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton        cntrl_->add_shared();
244e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
245e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
246e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
247e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::~SharingPtr()
248e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
249e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    if (cntrl_)
250e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton        cntrl_->release_shared();
251e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
252e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
253e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
254e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
255e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>&
256e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::operator=(const SharingPtr& r)
257e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
258e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    SharingPtr(r).swap(*this);
259e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    return *this;
260e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
261e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
262e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
263e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class Y>
264e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
265e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>&
266e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::operator=(const SharingPtr<Y>& r)
267e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
268e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    SharingPtr(r).swap(*this);
269e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    return *this;
270e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
271e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
272e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
273e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
274e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonvoid
275e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::swap(SharingPtr& r)
276e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
277e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    std::swap(ptr_, r.ptr_);
278e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    std::swap(cntrl_, r.cntrl_);
279e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
280e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
281e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
282e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
283e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonvoid
284e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::reset()
285e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
286e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    SharingPtr().swap(*this);
287e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
288e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
289e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
290e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class Y>
291e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
292e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonvoid
293e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>::reset(Y* p)
294e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
295e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    SharingPtr(p).swap(*this);
296e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
297e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
298101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T>
299101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
300101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>::make_shared()
301101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
302101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    typedef imp::shared_ptr_emplace<T> CntrlBlk;
303101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    SharingPtr<T> r;
304101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.cntrl_ = new CntrlBlk();
305e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton    r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
306101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return r;
307101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
308101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
309101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T>
310101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class A0>
311101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
312101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>::make_shared(A0& a0)
313101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
314101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    typedef imp::shared_ptr_emplace<T> CntrlBlk;
315101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    SharingPtr<T> r;
316101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.cntrl_ = new CntrlBlk(a0);
317101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
318101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return r;
319101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
320101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
321101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T>
322101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class A0, class A1>
323101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
324101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>::make_shared(A0& a0, A1& a1)
325101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
326101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    typedef imp::shared_ptr_emplace<T> CntrlBlk;
327101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    SharingPtr<T> r;
328101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.cntrl_ = new CntrlBlk(a0, a1);
329101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
330101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return r;
331101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
332101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
333101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T>
334101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class A0, class A1, class A2>
335101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
336101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>::make_shared(A0& a0, A1& a1, A2& a2)
337101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
338101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    typedef imp::shared_ptr_emplace<T> CntrlBlk;
339101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    SharingPtr<T> r;
340101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.cntrl_ = new CntrlBlk(a0, a1, a2);
341101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
342101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return r;
343101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
344101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
345101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T>
346101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class A0, class A1, class A2, class A3>
347101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
348101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>::make_shared(A0& a0, A1& a1, A2& a2, A3& a3)
349101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
350101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    typedef imp::shared_ptr_emplace<T> CntrlBlk;
351101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    SharingPtr<T> r;
352101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.cntrl_ = new CntrlBlk(a0, a1, a2, a3);
353101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
354101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return r;
355101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
356101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
357101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T>
358101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class A0, class A1, class A2, class A3, class A4>
359101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
360101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>::make_shared(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4)
361101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
362101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    typedef imp::shared_ptr_emplace<T> CntrlBlk;
363101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    SharingPtr<T> r;
364101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.cntrl_ = new CntrlBlk(a0, a1, a2, a3, a4);
365101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get();
366101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return r;
367101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
368101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
369101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T>
370101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytoninline
371101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
372101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonmake_shared()
373101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
374101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return SharingPtr<T>::make_shared();
375101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
376101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
377101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T, class A0>
378101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytoninline
379101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
380101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonmake_shared(A0& a0)
381101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
382101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return SharingPtr<T>::make_shared(a0);
383101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
384101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
385101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T, class A0, class A1>
386101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytoninline
387101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
388101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonmake_shared(A0& a0, A1& a1)
389101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
390101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return SharingPtr<T>::make_shared(a0, a1);
391101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
392101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
393101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T, class A0, class A1, class A2>
394101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytoninline
395101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
396101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonmake_shared(A0& a0, A1& a1, A2& a2)
397101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
398101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return SharingPtr<T>::make_shared(a0, a1, a2);
399101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
400101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
401101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T, class A0, class A1, class A2, class A3>
402101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytoninline
403101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
404101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonmake_shared(A0& a0, A1& a1, A2& a2, A3& a3)
405101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
406101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return SharingPtr<T>::make_shared(a0, a1, a2, a3);
407101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
408101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
409101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytontemplate<class T, class A0, class A1, class A2, class A3, class A4>
410101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytoninline
411101530ac16d5309953e1fe4416cfc407f10fae0aGreg ClaytonSharingPtr<T>
412101530ac16d5309953e1fe4416cfc407f10fae0aGreg Claytonmake_shared(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4)
413101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton{
414101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton    return SharingPtr<T>::make_shared(a0, a1, a2, a3, a4);
415101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton}
416101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
417101530ac16d5309953e1fe4416cfc407f10fae0aGreg Clayton
418e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T, class U>
419e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
420e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonbool
421e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonoperator==(const SharingPtr<T>& __x, const SharingPtr<U>& __y)
422e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
423e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    return __x.get() == __y.get();
424e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
425e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
426e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T, class U>
427e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
428e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonbool
429e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonoperator!=(const SharingPtr<T>& __x, const SharingPtr<U>& __y)
430e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
431e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    return !(__x == __y);
432e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
433e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
434e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T, class U>
435e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
436e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonbool
437e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonoperator<(const SharingPtr<T>& __x, const SharingPtr<U>& __y)
438e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
439e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    return __x.get() < __y.get();
440e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
441e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
442e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T>
443e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
444e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonvoid
445e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonswap(SharingPtr<T>& __x, SharingPtr<T>& __y)
446e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
447e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    __x.swap(__y);
448e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
449e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
450e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T, class U>
451e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytoninline
452e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>
453e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonstatic_pointer_cast(const SharingPtr<U>& r)
454e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
455e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    return SharingPtr<T>(r, static_cast<T*>(r.get()));
456e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
457e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
458e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytontemplate<class T, class U>
459e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg ClaytonSharingPtr<T>
460e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Claytonconst_pointer_cast(const SharingPtr<U>& r)
461e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton{
462e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton    return SharingPtr<T>(r, const_cast<T*>(r.get()));
463e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton}
464e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
465c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Claytontemplate <class T>
466c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Claytonclass LoggingSharingPtr
467c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    : public SharingPtr<T>
468c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton{
469c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    typedef SharingPtr<T> base;
470c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
471c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Claytonpublic:
472c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    typedef void (*Callback)(void*, const LoggingSharingPtr&, bool action);
473c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    // action:  false means increment just happened
474c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    //          true  means decrement is about to happen
475c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
476c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Claytonprivate:
477c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    Callback cb_;
478c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    void* baton_;
479c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
480c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Claytonpublic:
481c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    LoggingSharingPtr() : cb_(0), baton_(0) {}
482c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    LoggingSharingPtr(Callback cb, void* baton)
483c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        : cb_(cb), baton_(baton)
484c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    {
485c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        if (cb_)
486c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton            cb_(baton_, *this, false);
487c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    }
488c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
489c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    template <class Y>
490c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    LoggingSharingPtr(Y* p)
491c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        : base(p), cb_(0), baton_(0) {}
492c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
493c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    template <class Y>
494c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    LoggingSharingPtr(Y* p, Callback cb, void* baton)
495c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        : base(p), cb_(cb), baton_(baton)
496c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    {
497c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        if (cb_)
498c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton            cb_(baton_, *this, false);
499c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    }
500c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
501c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    ~LoggingSharingPtr()
502c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    {
503c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        if (cb_)
504c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton            cb_(baton_, *this, true);
505c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    }
506c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
507c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    LoggingSharingPtr(const LoggingSharingPtr& p)
508c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        : base(p), cb_(p.cb_), baton_(p.baton_)
509c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    {
510c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        if (cb_)
511c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton            cb_(baton_, *this, false);
512c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    }
513c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
514c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    LoggingSharingPtr& operator=(const LoggingSharingPtr& p)
515c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    {
516c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        if (cb_)
517c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton            cb_(baton_, *this, true);
518c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        base::operator=(p);
519c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        cb_ = p.cb_;
520c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        baton_ = p.baton_;
521c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        if (cb_)
522c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton            cb_(baton_, *this, false);
523c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        return *this;
524c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    }
525c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
526c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    void reset()
527c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    {
528c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        if (cb_)
529c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton            cb_(baton_, *this, true);
530c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        base::reset();
531c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    }
532c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
533c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    template <class Y>
534c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    void reset(Y* p)
535c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    {
536c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        if (cb_)
537c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton            cb_(baton_, *this, true);
538c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        base::reset(p);
539c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        if (cb_)
540c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton            cb_(baton_, *this, false);
541c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    }
542c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
543c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    void SetCallback(Callback cb, void* baton)
544c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    {
545c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        cb_ = cb;
546c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        baton_ = baton;
547c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    }
548c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
549c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    void ClearCallback()
550c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    {
551c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        cb_ = 0;
552c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton        baton_ = 0;
553c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton    }
554c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton};
5556e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
5566e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
5576e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate <class T>
5586e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonclass IntrusiveSharingPtr;
5596e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
5606e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate <class T>
5616e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonclass ReferenceCountedBase
5626e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
5636e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonpublic:
564987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    explicit ReferenceCountedBase()
565987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton        : shared_owners_(-1)
5666e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
5676e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
5686e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
5696e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    void
570987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    add_shared();
571987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton
5726e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    void
573987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    release_shared();
5746e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
5756e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    long
5766e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    use_count() const
5776e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
5786e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return shared_owners_ + 1;
5796e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
5806e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
5816e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonprotected:
5826e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    long shared_owners_;
5836e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
5846e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    friend class IntrusiveSharingPtr<T>;
5856e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
5866e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonprivate:
5876e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    ReferenceCountedBase(const ReferenceCountedBase&);
5886e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    ReferenceCountedBase& operator=(const ReferenceCountedBase&);
5896e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton};
5906e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
591987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    template <class T>
592987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    void
593987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    lldb_private::ReferenceCountedBase<T>::add_shared()
594987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    {
595987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton        imp::increment(shared_owners_);
596987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    }
5976e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
598987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    template <class T>
599987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    void
600987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    lldb_private::ReferenceCountedBase<T>::release_shared()
601987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    {
602987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton        if (imp::decrement(shared_owners_) == -1)
603987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton            delete static_cast<T*>(this);
604987c7ebe1daa425ba7abfa9643800e3237146fc0Greg Clayton    }
6056e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6066e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6076e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate <class T>
6086e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonclass ReferenceCountedBaseVirtual : public imp::shared_count
6096e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
6106e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonpublic:
6116e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    explicit ReferenceCountedBaseVirtual () :
6126e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        imp::shared_count(-1)
6136e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6146e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6156e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6166e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    virtual
6176e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    ~ReferenceCountedBaseVirtual ()
6186e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6196e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6206e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6216e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    virtual void on_zero_shared ();
6226e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6236e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton};
6246e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6256e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate <class T>
6266e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonvoid
6276e0101c86555a06b3bd4cb6104b35abfae0b0057Greg ClaytonReferenceCountedBaseVirtual<T>::on_zero_shared()
6286e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
6296e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton}
6306e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6316e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate <typename T>
6326e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonclass IntrusiveSharingPtr
6336e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
6346e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonpublic:
6356e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    typedef T element_type;
6366e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6376e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    explicit
6386e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    IntrusiveSharingPtr () :
6396e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        ptr_(0)
6406e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6416e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6426e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6436e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    explicit
6446e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    IntrusiveSharingPtr (T* ptr) :
6456e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        ptr_(ptr)
6466e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6476e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        add_shared();
6486e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6496e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6506e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    IntrusiveSharingPtr (const IntrusiveSharingPtr& rhs) :
6516e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        ptr_(rhs.ptr_)
6526e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6536e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        add_shared();
6546e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6556e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6566e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    template <class X>
6576e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    IntrusiveSharingPtr (const IntrusiveSharingPtr<X>& rhs)
6586e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        : ptr_(rhs.get())
6596e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6606e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        add_shared();
6616e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6626e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6636e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    IntrusiveSharingPtr&
6646e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    operator= (const IntrusiveSharingPtr& rhs)
6656e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6666e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        reset(rhs.get());
6676e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return *this;
6686e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6696e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6706e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    template <class X> IntrusiveSharingPtr&
6716e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    operator= (const IntrusiveSharingPtr<X>& rhs)
6726e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6736e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        reset(rhs.get());
6746e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return *this;
6756e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6766e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6776e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    IntrusiveSharingPtr&
6786e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    operator= (T *ptr)
6796e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6806e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        reset(ptr);
6816e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return *this;
6826e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6836e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6846e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    ~IntrusiveSharingPtr()
6856e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
6866e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        release_shared();
687b17bf82e7f3a5e125abc79b6b75725c601f1c6ceGreg Clayton#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
688b17bf82e7f3a5e125abc79b6b75725c601f1c6ceGreg Clayton        // NULL out the pointer in objects which can help with leaks detection.
689b17bf82e7f3a5e125abc79b6b75725c601f1c6ceGreg Clayton        // We don't enable this for LLDB_CONFIGURATION_BUILD_AND_INTEGRATION or
690b17bf82e7f3a5e125abc79b6b75725c601f1c6ceGreg Clayton        // when none of the LLDB_CONFIGURATION_XXX macros are defined since
691b17bf82e7f3a5e125abc79b6b75725c601f1c6ceGreg Clayton        // those would be builds for release. But for debug and release builds
692b17bf82e7f3a5e125abc79b6b75725c601f1c6ceGreg Clayton        // that are for development, we NULL out the pointers to catch potential
693b17bf82e7f3a5e125abc79b6b75725c601f1c6ceGreg Clayton        // issues.
694b17bf82e7f3a5e125abc79b6b75725c601f1c6ceGreg Clayton        ptr_ = NULL;
695b17bf82e7f3a5e125abc79b6b75725c601f1c6ceGreg Clayton#endif  // #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE)
6966e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
6976e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
6986e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    T&
6996e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    operator*() const
7006e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7016e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return *ptr_;
7026e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7036e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7046e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    T*
7056e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    operator->() const
7066e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7076e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return ptr_;
7086e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7096e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7106e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    T*
7116e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    get() const
7126e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7136e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return ptr_;
7146e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7156e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7166e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    operator bool() const
7176e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7186e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return ptr_ != 0;
7196e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7206e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7216e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    void
7226e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    swap (IntrusiveSharingPtr& rhs)
7236e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7246e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        std::swap(ptr_, rhs.ptr_);
725666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton#if defined (ENABLE_SP_LOGGING)
726666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton        track_sp (this, ptr_, use_count());
727666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton        track_sp (&rhs, rhs.ptr_, rhs.use_count());
728666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton#endif
7296e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7306e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7316e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    void
7326e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    reset(T* ptr = NULL)
7336e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7346e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        IntrusiveSharingPtr(ptr).swap(*this);
7356e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7366e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7376e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    long
7386e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    use_count () const
7396e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7406e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        if (ptr_)
7416e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton            return ptr_->use_count();
7426e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return 0;
7436e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7446e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7456e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    bool
7466e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    unique () const
7476e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7486e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        return use_count () == 1;
7496e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7506e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7516e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytonprivate:
7526e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    element_type *ptr_;
753666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton
7546e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    void
7556e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    add_shared()
7566e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7576e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        if (ptr_)
758666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton        {
7596e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton            ptr_->add_shared();
760666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton#if defined (ENABLE_SP_LOGGING)
761666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton            track_sp (this, ptr_, ptr_->use_count());
762666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton#endif
763666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton        }
7646e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7656e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    void
7666e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    release_shared()
7676e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    {
7686e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton        if (ptr_)
769666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton        {
770666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton#if defined (ENABLE_SP_LOGGING)
771666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton            track_sp (this, NULL, ptr_->use_count() - 1);
772666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton#endif
7736e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton            ptr_->release_shared();
774666c553ca803df25b7fc1e53cb8616449f4ce308Greg Clayton        }
7756e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    }
7766e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton};
7776e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7786e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate<class T, class U>
7796e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytoninline bool operator== (const IntrusiveSharingPtr<T>& lhs, const IntrusiveSharingPtr<U>& rhs)
7806e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
7816e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    return lhs.get() == rhs.get();
7826e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton}
7836e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7846e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate<class T, class U>
7856e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytoninline bool operator!= (const IntrusiveSharingPtr<T>& lhs, const IntrusiveSharingPtr<U>& rhs)
7866e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
7876e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    return lhs.get() != rhs.get();
7886e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton}
7896e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7906e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate<class T, class U>
7916e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytoninline bool operator== (const IntrusiveSharingPtr<T>& lhs, U* rhs)
7926e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
7936e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    return lhs.get() == rhs;
7946e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton}
7956e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
7966e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate<class T, class U>
7976e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytoninline bool operator!= (const IntrusiveSharingPtr<T>& lhs, U* rhs)
7986e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
7996e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    return lhs.get() != rhs;
8006e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton}
8016e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
8026e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate<class T, class U>
8036e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytoninline bool operator== (T* lhs, const IntrusiveSharingPtr<U>& rhs)
8046e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
8056e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    return lhs == rhs.get();
8066e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton}
8076e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton
8086e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytontemplate<class T, class U>
8096e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Claytoninline bool operator!= (T* lhs, const IntrusiveSharingPtr<U>& rhs)
8106e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton{
8116e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton    return lhs != rhs.get();
8126e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton}
813c51ffbf896e398ada5f7e89b2fa5aec6f2224f09Greg Clayton
8146e0101c86555a06b3bd4cb6104b35abfae0b0057Greg Clayton} // namespace lldb_private
815e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton
816e49f79dd0afe39829873fa2dcede8ef68b2485f0Greg Clayton#endif  // utility_SharingPtr_h_
817