1254721Semaste//===---------------------SharingPtr.h --------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#ifndef utility_SharingPtr_h_ 11254721Semaste#define utility_SharingPtr_h_ 12254721Semaste 13254721Semaste#include <algorithm> 14254721Semaste#include <memory> 15254721Semaste 16263363Semaste// Microsoft Visual C++ currently does not enable std::atomic to work 17263363Semaste// in CLR mode - as such we need to "hack around it" for MSVC++ builds only 18263363Semaste// using Windows specific instrinsics instead of the C++11 atomic support 19263363Semaste#ifdef _MSC_VER 20263363Semaste#include <intrin.h> 21263363Semaste#else 22263363Semaste#include <atomic> 23263363Semaste#endif 24263363Semaste 25254721Semaste//#define ENABLE_SP_LOGGING 1 // DON'T CHECK THIS LINE IN UNLESS COMMENTED OUT 26254721Semaste#if defined (ENABLE_SP_LOGGING) 27254721Semaste 28254721Semasteextern "C" void track_sp (void *sp_this, void *ptr, long count); 29254721Semaste 30254721Semaste#endif 31254721Semaste 32254721Semastenamespace lldb_private { 33254721Semaste 34254721Semastenamespace imp { 35254721Semaste 36254721Semasteclass shared_count 37254721Semaste{ 38254721Semaste shared_count(const shared_count&); 39254721Semaste shared_count& operator=(const shared_count&); 40254721Semaste 41254721Semasteprotected: 42263363Semaste#ifdef _MSC_VER 43254721Semaste long shared_owners_; 44263363Semaste#else 45263363Semaste std::atomic<long> shared_owners_; 46263363Semaste#endif 47254721Semaste virtual ~shared_count(); 48254721Semasteprivate: 49254721Semaste virtual void on_zero_shared() = 0; 50254721Semaste 51254721Semastepublic: 52254721Semaste explicit shared_count(long refs = 0) 53254721Semaste : shared_owners_(refs) {} 54254721Semaste 55254721Semaste void add_shared(); 56254721Semaste void release_shared(); 57254721Semaste long use_count() const {return shared_owners_ + 1;} 58254721Semaste}; 59254721Semaste 60254721Semastetemplate <class T> 61254721Semasteclass shared_ptr_pointer 62254721Semaste : public shared_count 63254721Semaste{ 64254721Semaste T data_; 65254721Semastepublic: 66254721Semaste shared_ptr_pointer(T p) 67254721Semaste : data_(p) {} 68254721Semaste 69254721Semasteprivate: 70254721Semaste virtual void on_zero_shared(); 71254721Semaste 72254721Semaste // Outlaw copy constructor and assignment operator to keep effictive C++ 73254721Semaste // warnings down to a minumum 74254721Semaste shared_ptr_pointer (const shared_ptr_pointer &); 75254721Semaste shared_ptr_pointer & operator=(const shared_ptr_pointer &); 76254721Semaste}; 77254721Semaste 78254721Semastetemplate <class T> 79254721Semastevoid 80254721Semasteshared_ptr_pointer<T>::on_zero_shared() 81254721Semaste{ 82254721Semaste delete data_; 83254721Semaste} 84254721Semaste 85254721Semastetemplate <class T> 86254721Semasteclass shared_ptr_emplace 87254721Semaste : public shared_count 88254721Semaste{ 89254721Semaste T data_; 90254721Semastepublic: 91254721Semaste 92254721Semaste shared_ptr_emplace() 93254721Semaste : data_() {} 94254721Semaste 95254721Semaste template <class A0> 96254721Semaste shared_ptr_emplace(A0& a0) 97254721Semaste : data_(a0) {} 98254721Semaste 99254721Semaste template <class A0, class A1> 100254721Semaste shared_ptr_emplace(A0& a0, A1& a1) 101254721Semaste : data_(a0, a1) {} 102254721Semaste 103254721Semaste template <class A0, class A1, class A2> 104254721Semaste shared_ptr_emplace(A0& a0, A1& a1, A2& a2) 105254721Semaste : data_(a0, a1, a2) {} 106254721Semaste 107254721Semaste template <class A0, class A1, class A2, class A3> 108254721Semaste shared_ptr_emplace(A0& a0, A1& a1, A2& a2, A3& a3) 109254721Semaste : data_(a0, a1, a2, a3) {} 110254721Semaste 111254721Semaste template <class A0, class A1, class A2, class A3, class A4> 112254721Semaste shared_ptr_emplace(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) 113254721Semaste : data_(a0, a1, a2, a3, a4) {} 114254721Semaste 115254721Semasteprivate: 116254721Semaste virtual void on_zero_shared(); 117254721Semastepublic: 118254721Semaste T* get() {return &data_;} 119254721Semaste}; 120254721Semaste 121254721Semastetemplate <class T> 122254721Semastevoid 123254721Semasteshared_ptr_emplace<T>::on_zero_shared() 124254721Semaste{ 125254721Semaste} 126254721Semaste 127254721Semaste} // namespace 128254721Semaste 129254721Semastetemplate<class T> 130254721Semasteclass SharingPtr 131254721Semaste{ 132254721Semastepublic: 133254721Semaste typedef T element_type; 134254721Semasteprivate: 135254721Semaste element_type* ptr_; 136254721Semaste imp::shared_count* cntrl_; 137254721Semaste 138254721Semaste struct nat {int for_bool_;}; 139254721Semastepublic: 140254721Semaste SharingPtr(); 141254721Semaste template<class Y> explicit SharingPtr(Y* p); 142254721Semaste template<class Y> explicit SharingPtr(Y* p, imp::shared_count *ctrl_block); 143254721Semaste template<class Y> SharingPtr(const SharingPtr<Y>& r, element_type *p); 144254721Semaste SharingPtr(const SharingPtr& r); 145254721Semaste template<class Y> 146254721Semaste SharingPtr(const SharingPtr<Y>& r); 147254721Semaste 148254721Semaste ~SharingPtr(); 149254721Semaste 150254721Semaste SharingPtr& operator=(const SharingPtr& r); 151254721Semaste template<class Y> SharingPtr& operator=(const SharingPtr<Y>& r); 152254721Semaste 153254721Semaste void swap(SharingPtr& r); 154254721Semaste void reset(); 155254721Semaste template<class Y> void reset(Y* p); 156254721Semaste 157254721Semaste element_type* get() const {return ptr_;} 158254721Semaste element_type& operator*() const {return *ptr_;} 159254721Semaste element_type* operator->() const {return ptr_;} 160254721Semaste long use_count() const {return cntrl_ ? cntrl_->use_count() : 0;} 161254721Semaste bool unique() const {return use_count() == 1;} 162254721Semaste bool empty() const {return cntrl_ == 0;} 163254721Semaste operator nat*() const {return (nat*)get();} 164254721Semaste 165254721Semaste static SharingPtr<T> make_shared(); 166254721Semaste 167254721Semaste template<class A0> 168254721Semaste static SharingPtr<T> make_shared(A0&); 169254721Semaste 170254721Semaste template<class A0, class A1> 171254721Semaste static SharingPtr<T> make_shared(A0&, A1&); 172254721Semaste 173254721Semaste template<class A0, class A1, class A2> 174254721Semaste static SharingPtr<T> make_shared(A0&, A1&, A2&); 175254721Semaste 176254721Semaste template<class A0, class A1, class A2, class A3> 177254721Semaste static SharingPtr<T> make_shared(A0&, A1&, A2&, A3&); 178254721Semaste 179254721Semaste template<class A0, class A1, class A2, class A3, class A4> 180254721Semaste static SharingPtr<T> make_shared(A0&, A1&, A2&, A3&, A4&); 181254721Semaste 182254721Semasteprivate: 183254721Semaste 184254721Semaste template <class U> friend class SharingPtr; 185254721Semaste}; 186254721Semaste 187254721Semastetemplate<class T> 188254721Semasteinline 189254721SemasteSharingPtr<T>::SharingPtr() 190254721Semaste : ptr_(0), 191254721Semaste cntrl_(0) 192254721Semaste{ 193254721Semaste} 194254721Semaste 195254721Semastetemplate<class T> 196254721Semastetemplate<class Y> 197254721SemasteSharingPtr<T>::SharingPtr(Y* p) 198254721Semaste : ptr_(p), cntrl_(0) 199254721Semaste{ 200254721Semaste std::unique_ptr<Y> hold(p); 201254721Semaste typedef imp::shared_ptr_pointer<Y*> _CntrlBlk; 202254721Semaste cntrl_ = new _CntrlBlk(p); 203254721Semaste hold.release(); 204254721Semaste} 205254721Semaste 206254721Semastetemplate<class T> 207254721Semastetemplate<class Y> 208254721SemasteSharingPtr<T>::SharingPtr(Y* p, imp::shared_count *cntrl_block) 209254721Semaste : ptr_(p), cntrl_(cntrl_block) 210254721Semaste{ 211254721Semaste} 212254721Semaste 213254721Semastetemplate<class T> 214254721Semastetemplate<class Y> 215254721Semasteinline 216254721SemasteSharingPtr<T>::SharingPtr(const SharingPtr<Y>& r, element_type *p) 217254721Semaste : ptr_(p), 218254721Semaste cntrl_(r.cntrl_) 219254721Semaste{ 220254721Semaste if (cntrl_) 221254721Semaste cntrl_->add_shared(); 222254721Semaste} 223254721Semaste 224254721Semastetemplate<class T> 225254721Semasteinline 226254721SemasteSharingPtr<T>::SharingPtr(const SharingPtr& r) 227254721Semaste : ptr_(r.ptr_), 228254721Semaste cntrl_(r.cntrl_) 229254721Semaste{ 230254721Semaste if (cntrl_) 231254721Semaste cntrl_->add_shared(); 232254721Semaste} 233254721Semaste 234254721Semastetemplate<class T> 235254721Semastetemplate<class Y> 236254721Semasteinline 237254721SemasteSharingPtr<T>::SharingPtr(const SharingPtr<Y>& r) 238254721Semaste : ptr_(r.ptr_), 239254721Semaste cntrl_(r.cntrl_) 240254721Semaste{ 241254721Semaste if (cntrl_) 242254721Semaste cntrl_->add_shared(); 243254721Semaste} 244254721Semaste 245254721Semastetemplate<class T> 246254721SemasteSharingPtr<T>::~SharingPtr() 247254721Semaste{ 248254721Semaste if (cntrl_) 249254721Semaste cntrl_->release_shared(); 250254721Semaste} 251254721Semaste 252254721Semastetemplate<class T> 253254721Semasteinline 254254721SemasteSharingPtr<T>& 255254721SemasteSharingPtr<T>::operator=(const SharingPtr& r) 256254721Semaste{ 257254721Semaste SharingPtr(r).swap(*this); 258254721Semaste return *this; 259254721Semaste} 260254721Semaste 261254721Semastetemplate<class T> 262254721Semastetemplate<class Y> 263254721Semasteinline 264254721SemasteSharingPtr<T>& 265254721SemasteSharingPtr<T>::operator=(const SharingPtr<Y>& r) 266254721Semaste{ 267254721Semaste SharingPtr(r).swap(*this); 268254721Semaste return *this; 269254721Semaste} 270254721Semaste 271254721Semastetemplate<class T> 272254721Semasteinline 273254721Semastevoid 274254721SemasteSharingPtr<T>::swap(SharingPtr& r) 275254721Semaste{ 276254721Semaste std::swap(ptr_, r.ptr_); 277254721Semaste std::swap(cntrl_, r.cntrl_); 278254721Semaste} 279254721Semaste 280254721Semastetemplate<class T> 281254721Semasteinline 282254721Semastevoid 283254721SemasteSharingPtr<T>::reset() 284254721Semaste{ 285254721Semaste SharingPtr().swap(*this); 286254721Semaste} 287254721Semaste 288254721Semastetemplate<class T> 289254721Semastetemplate<class Y> 290254721Semasteinline 291254721Semastevoid 292254721SemasteSharingPtr<T>::reset(Y* p) 293254721Semaste{ 294254721Semaste SharingPtr(p).swap(*this); 295254721Semaste} 296254721Semaste 297254721Semastetemplate<class T> 298254721SemasteSharingPtr<T> 299254721SemasteSharingPtr<T>::make_shared() 300254721Semaste{ 301254721Semaste typedef imp::shared_ptr_emplace<T> CntrlBlk; 302254721Semaste SharingPtr<T> r; 303254721Semaste r.cntrl_ = new CntrlBlk(); 304254721Semaste r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get(); 305254721Semaste return r; 306254721Semaste} 307254721Semaste 308254721Semastetemplate<class T> 309254721Semastetemplate<class A0> 310254721SemasteSharingPtr<T> 311254721SemasteSharingPtr<T>::make_shared(A0& a0) 312254721Semaste{ 313254721Semaste typedef imp::shared_ptr_emplace<T> CntrlBlk; 314254721Semaste SharingPtr<T> r; 315254721Semaste r.cntrl_ = new CntrlBlk(a0); 316254721Semaste r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get(); 317254721Semaste return r; 318254721Semaste} 319254721Semaste 320254721Semastetemplate<class T> 321254721Semastetemplate<class A0, class A1> 322254721SemasteSharingPtr<T> 323254721SemasteSharingPtr<T>::make_shared(A0& a0, A1& a1) 324254721Semaste{ 325254721Semaste typedef imp::shared_ptr_emplace<T> CntrlBlk; 326254721Semaste SharingPtr<T> r; 327254721Semaste r.cntrl_ = new CntrlBlk(a0, a1); 328254721Semaste r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get(); 329254721Semaste return r; 330254721Semaste} 331254721Semaste 332254721Semastetemplate<class T> 333254721Semastetemplate<class A0, class A1, class A2> 334254721SemasteSharingPtr<T> 335254721SemasteSharingPtr<T>::make_shared(A0& a0, A1& a1, A2& a2) 336254721Semaste{ 337254721Semaste typedef imp::shared_ptr_emplace<T> CntrlBlk; 338254721Semaste SharingPtr<T> r; 339254721Semaste r.cntrl_ = new CntrlBlk(a0, a1, a2); 340254721Semaste r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get(); 341254721Semaste return r; 342254721Semaste} 343254721Semaste 344254721Semastetemplate<class T> 345254721Semastetemplate<class A0, class A1, class A2, class A3> 346254721SemasteSharingPtr<T> 347254721SemasteSharingPtr<T>::make_shared(A0& a0, A1& a1, A2& a2, A3& a3) 348254721Semaste{ 349254721Semaste typedef imp::shared_ptr_emplace<T> CntrlBlk; 350254721Semaste SharingPtr<T> r; 351254721Semaste r.cntrl_ = new CntrlBlk(a0, a1, a2, a3); 352254721Semaste r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get(); 353254721Semaste return r; 354254721Semaste} 355254721Semaste 356254721Semastetemplate<class T> 357254721Semastetemplate<class A0, class A1, class A2, class A3, class A4> 358254721SemasteSharingPtr<T> 359254721SemasteSharingPtr<T>::make_shared(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) 360254721Semaste{ 361254721Semaste typedef imp::shared_ptr_emplace<T> CntrlBlk; 362254721Semaste SharingPtr<T> r; 363254721Semaste r.cntrl_ = new CntrlBlk(a0, a1, a2, a3, a4); 364254721Semaste r.ptr_ = static_cast<CntrlBlk*>(r.cntrl_)->get(); 365254721Semaste return r; 366254721Semaste} 367254721Semaste 368254721Semastetemplate<class T> 369254721Semasteinline 370254721SemasteSharingPtr<T> 371254721Semastemake_shared() 372254721Semaste{ 373254721Semaste return SharingPtr<T>::make_shared(); 374254721Semaste} 375254721Semaste 376254721Semastetemplate<class T, class A0> 377254721Semasteinline 378254721SemasteSharingPtr<T> 379254721Semastemake_shared(A0& a0) 380254721Semaste{ 381254721Semaste return SharingPtr<T>::make_shared(a0); 382254721Semaste} 383254721Semaste 384254721Semastetemplate<class T, class A0, class A1> 385254721Semasteinline 386254721SemasteSharingPtr<T> 387254721Semastemake_shared(A0& a0, A1& a1) 388254721Semaste{ 389254721Semaste return SharingPtr<T>::make_shared(a0, a1); 390254721Semaste} 391254721Semaste 392254721Semastetemplate<class T, class A0, class A1, class A2> 393254721Semasteinline 394254721SemasteSharingPtr<T> 395254721Semastemake_shared(A0& a0, A1& a1, A2& a2) 396254721Semaste{ 397254721Semaste return SharingPtr<T>::make_shared(a0, a1, a2); 398254721Semaste} 399254721Semaste 400254721Semastetemplate<class T, class A0, class A1, class A2, class A3> 401254721Semasteinline 402254721SemasteSharingPtr<T> 403254721Semastemake_shared(A0& a0, A1& a1, A2& a2, A3& a3) 404254721Semaste{ 405254721Semaste return SharingPtr<T>::make_shared(a0, a1, a2, a3); 406254721Semaste} 407254721Semaste 408254721Semastetemplate<class T, class A0, class A1, class A2, class A3, class A4> 409254721Semasteinline 410254721SemasteSharingPtr<T> 411254721Semastemake_shared(A0& a0, A1& a1, A2& a2, A3& a3, A4& a4) 412254721Semaste{ 413254721Semaste return SharingPtr<T>::make_shared(a0, a1, a2, a3, a4); 414254721Semaste} 415254721Semaste 416254721Semaste 417254721Semastetemplate<class T, class U> 418254721Semasteinline 419254721Semastebool 420254721Semasteoperator==(const SharingPtr<T>& __x, const SharingPtr<U>& __y) 421254721Semaste{ 422254721Semaste return __x.get() == __y.get(); 423254721Semaste} 424254721Semaste 425254721Semastetemplate<class T, class U> 426254721Semasteinline 427254721Semastebool 428254721Semasteoperator!=(const SharingPtr<T>& __x, const SharingPtr<U>& __y) 429254721Semaste{ 430254721Semaste return !(__x == __y); 431254721Semaste} 432254721Semaste 433254721Semastetemplate<class T, class U> 434254721Semasteinline 435254721Semastebool 436254721Semasteoperator<(const SharingPtr<T>& __x, const SharingPtr<U>& __y) 437254721Semaste{ 438254721Semaste return __x.get() < __y.get(); 439254721Semaste} 440254721Semaste 441254721Semastetemplate<class T> 442254721Semasteinline 443254721Semastevoid 444254721Semasteswap(SharingPtr<T>& __x, SharingPtr<T>& __y) 445254721Semaste{ 446254721Semaste __x.swap(__y); 447254721Semaste} 448254721Semaste 449254721Semastetemplate<class T, class U> 450254721Semasteinline 451254721SemasteSharingPtr<T> 452254721Semastestatic_pointer_cast(const SharingPtr<U>& r) 453254721Semaste{ 454254721Semaste return SharingPtr<T>(r, static_cast<T*>(r.get())); 455254721Semaste} 456254721Semaste 457254721Semastetemplate<class T, class U> 458254721SemasteSharingPtr<T> 459254721Semasteconst_pointer_cast(const SharingPtr<U>& r) 460254721Semaste{ 461254721Semaste return SharingPtr<T>(r, const_cast<T*>(r.get())); 462254721Semaste} 463254721Semaste 464254721Semastetemplate <class T> 465254721Semasteclass LoggingSharingPtr 466254721Semaste : public SharingPtr<T> 467254721Semaste{ 468254721Semaste typedef SharingPtr<T> base; 469254721Semaste 470254721Semastepublic: 471254721Semaste typedef void (*Callback)(void*, const LoggingSharingPtr&, bool action); 472254721Semaste // action: false means increment just happened 473254721Semaste // true means decrement is about to happen 474254721Semaste 475254721Semasteprivate: 476254721Semaste Callback cb_; 477254721Semaste void* baton_; 478254721Semaste 479254721Semastepublic: 480254721Semaste LoggingSharingPtr() : cb_(0), baton_(0) {} 481254721Semaste LoggingSharingPtr(Callback cb, void* baton) 482254721Semaste : cb_(cb), baton_(baton) 483254721Semaste { 484254721Semaste if (cb_) 485254721Semaste cb_(baton_, *this, false); 486254721Semaste } 487254721Semaste 488254721Semaste template <class Y> 489254721Semaste LoggingSharingPtr(Y* p) 490254721Semaste : base(p), cb_(0), baton_(0) {} 491254721Semaste 492254721Semaste template <class Y> 493254721Semaste LoggingSharingPtr(Y* p, Callback cb, void* baton) 494254721Semaste : base(p), cb_(cb), baton_(baton) 495254721Semaste { 496254721Semaste if (cb_) 497254721Semaste cb_(baton_, *this, false); 498254721Semaste } 499254721Semaste 500254721Semaste ~LoggingSharingPtr() 501254721Semaste { 502254721Semaste if (cb_) 503254721Semaste cb_(baton_, *this, true); 504254721Semaste } 505254721Semaste 506254721Semaste LoggingSharingPtr(const LoggingSharingPtr& p) 507254721Semaste : base(p), cb_(p.cb_), baton_(p.baton_) 508254721Semaste { 509254721Semaste if (cb_) 510254721Semaste cb_(baton_, *this, false); 511254721Semaste } 512254721Semaste 513254721Semaste LoggingSharingPtr& operator=(const LoggingSharingPtr& p) 514254721Semaste { 515254721Semaste if (cb_) 516254721Semaste cb_(baton_, *this, true); 517254721Semaste base::operator=(p); 518254721Semaste cb_ = p.cb_; 519254721Semaste baton_ = p.baton_; 520254721Semaste if (cb_) 521254721Semaste cb_(baton_, *this, false); 522254721Semaste return *this; 523254721Semaste } 524254721Semaste 525254721Semaste void reset() 526254721Semaste { 527254721Semaste if (cb_) 528254721Semaste cb_(baton_, *this, true); 529254721Semaste base::reset(); 530254721Semaste } 531254721Semaste 532254721Semaste template <class Y> 533254721Semaste void reset(Y* p) 534254721Semaste { 535254721Semaste if (cb_) 536254721Semaste cb_(baton_, *this, true); 537254721Semaste base::reset(p); 538254721Semaste if (cb_) 539254721Semaste cb_(baton_, *this, false); 540254721Semaste } 541254721Semaste 542254721Semaste void SetCallback(Callback cb, void* baton) 543254721Semaste { 544254721Semaste cb_ = cb; 545254721Semaste baton_ = baton; 546254721Semaste } 547254721Semaste 548254721Semaste void ClearCallback() 549254721Semaste { 550254721Semaste cb_ = 0; 551254721Semaste baton_ = 0; 552254721Semaste } 553254721Semaste}; 554254721Semaste 555254721Semaste 556254721Semastetemplate <class T> 557254721Semasteclass IntrusiveSharingPtr; 558254721Semaste 559254721Semastetemplate <class T> 560254721Semasteclass ReferenceCountedBase 561254721Semaste{ 562254721Semastepublic: 563254721Semaste explicit ReferenceCountedBase() 564254721Semaste : shared_owners_(-1) 565254721Semaste { 566254721Semaste } 567254721Semaste 568254721Semaste void 569254721Semaste add_shared(); 570254721Semaste 571254721Semaste void 572254721Semaste release_shared(); 573254721Semaste 574254721Semaste long 575254721Semaste use_count() const 576254721Semaste { 577254721Semaste return shared_owners_ + 1; 578254721Semaste } 579254721Semaste 580254721Semasteprotected: 581254721Semaste long shared_owners_; 582254721Semaste 583254721Semaste friend class IntrusiveSharingPtr<T>; 584254721Semaste 585254721Semasteprivate: 586254721Semaste ReferenceCountedBase(const ReferenceCountedBase&); 587254721Semaste ReferenceCountedBase& operator=(const ReferenceCountedBase&); 588254721Semaste}; 589254721Semaste 590254721Semaste template <class T> 591254721Semaste void 592254721Semaste lldb_private::ReferenceCountedBase<T>::add_shared() 593254721Semaste { 594263363Semaste#ifdef _MSC_VER 595263363Semaste _InterlockedIncrement(&shared_owners_); 596263363Semaste#else 597263363Semaste ++shared_owners_; 598263363Semaste#endif 599254721Semaste } 600254721Semaste 601254721Semaste template <class T> 602254721Semaste void 603254721Semaste lldb_private::ReferenceCountedBase<T>::release_shared() 604254721Semaste { 605263363Semaste#ifdef _MSC_VER 606263363Semaste if (_InterlockedDecrement(&shared_owners_) == -1) 607263363Semaste#else 608263363Semaste if (--shared_owners_ == -1) 609263363Semaste#endif 610254721Semaste delete static_cast<T*>(this); 611254721Semaste } 612254721Semaste 613254721Semaste 614254721Semastetemplate <class T> 615254721Semasteclass ReferenceCountedBaseVirtual : public imp::shared_count 616254721Semaste{ 617254721Semastepublic: 618254721Semaste explicit ReferenceCountedBaseVirtual () : 619254721Semaste imp::shared_count(-1) 620254721Semaste { 621254721Semaste } 622254721Semaste 623254721Semaste virtual 624254721Semaste ~ReferenceCountedBaseVirtual () 625254721Semaste { 626254721Semaste } 627254721Semaste 628254721Semaste virtual void on_zero_shared (); 629254721Semaste 630254721Semaste}; 631254721Semaste 632254721Semastetemplate <class T> 633254721Semastevoid 634254721SemasteReferenceCountedBaseVirtual<T>::on_zero_shared() 635254721Semaste{ 636254721Semaste} 637254721Semaste 638254721Semastetemplate <typename T> 639254721Semasteclass IntrusiveSharingPtr 640254721Semaste{ 641254721Semastepublic: 642254721Semaste typedef T element_type; 643254721Semaste 644254721Semaste explicit 645254721Semaste IntrusiveSharingPtr () : 646254721Semaste ptr_(0) 647254721Semaste { 648254721Semaste } 649254721Semaste 650254721Semaste explicit 651254721Semaste IntrusiveSharingPtr (T* ptr) : 652254721Semaste ptr_(ptr) 653254721Semaste { 654254721Semaste add_shared(); 655254721Semaste } 656254721Semaste 657254721Semaste IntrusiveSharingPtr (const IntrusiveSharingPtr& rhs) : 658254721Semaste ptr_(rhs.ptr_) 659254721Semaste { 660254721Semaste add_shared(); 661254721Semaste } 662254721Semaste 663254721Semaste template <class X> 664254721Semaste IntrusiveSharingPtr (const IntrusiveSharingPtr<X>& rhs) 665254721Semaste : ptr_(rhs.get()) 666254721Semaste { 667254721Semaste add_shared(); 668254721Semaste } 669254721Semaste 670254721Semaste IntrusiveSharingPtr& 671254721Semaste operator= (const IntrusiveSharingPtr& rhs) 672254721Semaste { 673254721Semaste reset(rhs.get()); 674254721Semaste return *this; 675254721Semaste } 676254721Semaste 677254721Semaste template <class X> IntrusiveSharingPtr& 678254721Semaste operator= (const IntrusiveSharingPtr<X>& rhs) 679254721Semaste { 680254721Semaste reset(rhs.get()); 681254721Semaste return *this; 682254721Semaste } 683254721Semaste 684254721Semaste IntrusiveSharingPtr& 685254721Semaste operator= (T *ptr) 686254721Semaste { 687254721Semaste reset(ptr); 688254721Semaste return *this; 689254721Semaste } 690254721Semaste 691254721Semaste ~IntrusiveSharingPtr() 692254721Semaste { 693254721Semaste release_shared(); 694254721Semaste#if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 695254721Semaste // NULL out the pointer in objects which can help with leaks detection. 696254721Semaste // We don't enable this for LLDB_CONFIGURATION_BUILD_AND_INTEGRATION or 697254721Semaste // when none of the LLDB_CONFIGURATION_XXX macros are defined since 698254721Semaste // those would be builds for release. But for debug and release builds 699254721Semaste // that are for development, we NULL out the pointers to catch potential 700254721Semaste // issues. 701254721Semaste ptr_ = NULL; 702254721Semaste#endif // #if defined (LLDB_CONFIGURATION_DEBUG) || defined (LLDB_CONFIGURATION_RELEASE) 703254721Semaste } 704254721Semaste 705254721Semaste T& 706254721Semaste operator*() const 707254721Semaste { 708254721Semaste return *ptr_; 709254721Semaste } 710254721Semaste 711254721Semaste T* 712254721Semaste operator->() const 713254721Semaste { 714254721Semaste return ptr_; 715254721Semaste } 716254721Semaste 717254721Semaste T* 718254721Semaste get() const 719254721Semaste { 720254721Semaste return ptr_; 721254721Semaste } 722254721Semaste 723263363Semaste explicit operator bool() const 724254721Semaste { 725254721Semaste return ptr_ != 0; 726254721Semaste } 727254721Semaste 728254721Semaste void 729254721Semaste swap (IntrusiveSharingPtr& rhs) 730254721Semaste { 731254721Semaste std::swap(ptr_, rhs.ptr_); 732254721Semaste#if defined (ENABLE_SP_LOGGING) 733254721Semaste track_sp (this, ptr_, use_count()); 734254721Semaste track_sp (&rhs, rhs.ptr_, rhs.use_count()); 735254721Semaste#endif 736254721Semaste } 737254721Semaste 738254721Semaste void 739254721Semaste reset(T* ptr = NULL) 740254721Semaste { 741254721Semaste IntrusiveSharingPtr(ptr).swap(*this); 742254721Semaste } 743254721Semaste 744254721Semaste long 745254721Semaste use_count () const 746254721Semaste { 747254721Semaste if (ptr_) 748254721Semaste return ptr_->use_count(); 749254721Semaste return 0; 750254721Semaste } 751254721Semaste 752254721Semaste bool 753254721Semaste unique () const 754254721Semaste { 755254721Semaste return use_count () == 1; 756254721Semaste } 757254721Semaste 758254721Semasteprivate: 759254721Semaste element_type *ptr_; 760254721Semaste 761254721Semaste void 762254721Semaste add_shared() 763254721Semaste { 764254721Semaste if (ptr_) 765254721Semaste { 766254721Semaste ptr_->add_shared(); 767254721Semaste#if defined (ENABLE_SP_LOGGING) 768254721Semaste track_sp (this, ptr_, ptr_->use_count()); 769254721Semaste#endif 770254721Semaste } 771254721Semaste } 772254721Semaste void 773254721Semaste release_shared() 774254721Semaste { 775254721Semaste if (ptr_) 776254721Semaste { 777254721Semaste#if defined (ENABLE_SP_LOGGING) 778254721Semaste track_sp (this, NULL, ptr_->use_count() - 1); 779254721Semaste#endif 780254721Semaste ptr_->release_shared(); 781254721Semaste } 782254721Semaste } 783254721Semaste}; 784254721Semaste 785254721Semastetemplate<class T, class U> 786254721Semasteinline bool operator== (const IntrusiveSharingPtr<T>& lhs, const IntrusiveSharingPtr<U>& rhs) 787254721Semaste{ 788254721Semaste return lhs.get() == rhs.get(); 789254721Semaste} 790254721Semaste 791254721Semastetemplate<class T, class U> 792254721Semasteinline bool operator!= (const IntrusiveSharingPtr<T>& lhs, const IntrusiveSharingPtr<U>& rhs) 793254721Semaste{ 794254721Semaste return lhs.get() != rhs.get(); 795254721Semaste} 796254721Semaste 797254721Semastetemplate<class T, class U> 798254721Semasteinline bool operator== (const IntrusiveSharingPtr<T>& lhs, U* rhs) 799254721Semaste{ 800254721Semaste return lhs.get() == rhs; 801254721Semaste} 802254721Semaste 803254721Semastetemplate<class T, class U> 804254721Semasteinline bool operator!= (const IntrusiveSharingPtr<T>& lhs, U* rhs) 805254721Semaste{ 806254721Semaste return lhs.get() != rhs; 807254721Semaste} 808254721Semaste 809254721Semastetemplate<class T, class U> 810254721Semasteinline bool operator== (T* lhs, const IntrusiveSharingPtr<U>& rhs) 811254721Semaste{ 812254721Semaste return lhs == rhs.get(); 813254721Semaste} 814254721Semaste 815254721Semastetemplate<class T, class U> 816254721Semasteinline bool operator!= (T* lhs, const IntrusiveSharingPtr<U>& rhs) 817254721Semaste{ 818254721Semaste return lhs != rhs.get(); 819254721Semaste} 820254721Semaste 821254721Semaste} // namespace lldb_private 822254721Semaste 823254721Semaste#endif // utility_SharingPtr_h_ 824