00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #ifndef SMARTPTR_INC_
00056 #define SMARTPTR_INC_
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #include <base/SmallObj>
00068 #include <base/TypeManip>
00069 #include <base/NullType>
00070 #include <base/static_check>
00071 #include <functional>
00072 #include <stdexcept>
00073
00074 namespace base
00075 {
00076
00077
00078
00079
00080
00081
00082 template <class T>
00083 class DefaultSPStorage
00084 {
00085 public:
00086 typedef T* StoredType;
00087 typedef T* PointerType;
00088 typedef T& ReferenceType;
00089
00090 DefaultSPStorage() : pointee_(Default())
00091 {}
00092
00093
00094
00095 DefaultSPStorage(const DefaultSPStorage&)
00096 {}
00097
00098 template <class U>
00099 DefaultSPStorage(const DefaultSPStorage<U>&)
00100 {}
00101
00102 DefaultSPStorage(const StoredType& p) : pointee_(p) {}
00103
00104 PointerType operator->() const { return pointee_; }
00105
00106 ReferenceType operator*() const { return *pointee_; }
00107
00108 void Swap(DefaultSPStorage& rhs)
00109 { std::swap(pointee_, rhs.pointee_); }
00110
00111
00112 friend inline PointerType GetImpl(const DefaultSPStorage& sp)
00113 { return sp.pointee_; }
00114
00115 friend inline const StoredType& GetImplRef(const DefaultSPStorage& sp)
00116 { return sp.pointee_; }
00117
00118 friend inline StoredType& GetImplRef(DefaultSPStorage& sp)
00119 { return sp.pointee_; }
00120
00121
00122 static StoredType Default()
00123 { return 0; }
00124
00125 protected:
00126
00127
00128 void Destroy()
00129 { delete pointee_; }
00130
00131 private:
00132
00133 StoredType pointee_;
00134 };
00135
00136
00137
00138
00139
00140
00141
00142 template <class P>
00143 class RefCounted
00144 {
00145 public:
00146 RefCounted()
00147 {
00148 pCount_ = static_cast<unsigned int*>(
00149 SmallObject<>::operator new(sizeof(unsigned int)));
00150 assert(pCount_);
00151 *pCount_ = 1;
00152 }
00153
00154 RefCounted(const RefCounted& rhs)
00155 : pCount_(rhs.pCount_)
00156 {}
00157
00158
00159 template <typename P1>
00160 RefCounted(const RefCounted<P1>& rhs)
00161 : pCount_(reinterpret_cast<const RefCounted&>(rhs).pCount_)
00162 {}
00163
00164 P Clone(const P& val)
00165 {
00166 ++*pCount_;
00167 return val;
00168 }
00169
00170 void OnInit(const P&)
00171 {}
00172
00173 bool Release(const P&)
00174 {
00175 if (!--*pCount_)
00176 {
00177 SmallObject<>::operator delete(pCount_, sizeof(unsigned int));
00178 return true;
00179 }
00180 return false;
00181 }
00182
00183 void Swap(RefCounted& rhs)
00184 { std::swap(pCount_, rhs.pCount_); }
00185
00186 enum { destructiveCopy = false };
00187
00188 private:
00189
00190 unsigned int* pCount_;
00191 };
00192
00193
00194
00195
00196
00197
00198 template <class P,
00199 template <class> class ThreadingModel>
00200 class RefCountedMT : public ThreadingModel< RefCountedMT<P, ThreadingModel> >
00201 {
00202 public:
00203 RefCountedMT()
00204 {
00205 pCount_ = static_cast<unsigned int*>(
00206 SmallObject<ThreadingModel>::operator new(
00207 sizeof(unsigned int)));
00208 assert(pCount_);
00209 *pCount_ = 1;
00210 }
00211
00212 RefCountedMT(const RefCountedMT& rhs)
00213 : pCount_(rhs.pCount_)
00214 {}
00215
00216
00217 template <typename P1>
00218 RefCountedMT(const RefCountedMT<P1, ThreadingModel>& rhs)
00219 : pCount_(reinterpret_cast<const RefCounted<P>&>(rhs).pCount_)
00220 {}
00221
00222 P Clone(const P& val)
00223 {
00224 ThreadingModel<RefCountedMT>::AtomicIncrement(*pCount_);
00225 return val;
00226 }
00227
00228 void OnInit(const P&)
00229 {}
00230
00231 bool Release(const P&)
00232 {
00233 if (!ThreadingModel<RefCountedMT>::AtomicDecrement(*pCount_))
00234 {
00235 SmallObject<ThreadingModel>::operator delete(pCount_,
00236 sizeof(unsigned int));
00237 return true;
00238 }
00239 return false;
00240 }
00241
00242 void Swap(RefCountedMT& rhs)
00243 { std::swap(pCount_, rhs.pCount_); }
00244
00245 enum { destructiveCopy = false };
00246
00247 private:
00248
00249 volatile unsigned int* pCount_;
00250 };
00251
00252
00253
00254
00255
00256
00257
00258 template <class P>
00259 class COMRefCounted
00260 {
00261 public:
00262 COMRefCounted()
00263 {}
00264
00265 template <class U>
00266 COMRefCounted(const COMRefCounted<U>&)
00267 {}
00268
00269 static P Clone(const P& val)
00270 {
00271 val->AddRef();
00272 return val;
00273 }
00274
00275 static void OnInit(const P&)
00276 {}
00277
00278 static bool Release(const P& val)
00279 { val->Release(); return false; }
00280
00281 enum { destructiveCopy = false };
00282
00283 static void Swap(COMRefCounted&)
00284 {}
00285 };
00286
00287
00288
00289
00290
00291
00292
00293 template <class P>
00294 class IntrRefCounted
00295 {
00296 public:
00297 IntrRefCounted()
00298 {}
00299
00300 template <class U>
00301 IntrRefCounted(const IntrRefCounted<U>&)
00302 {}
00303
00304 static P Clone(const P& val)
00305 {
00306 if (val!=0)
00307 val->reference();
00308 return val;
00309 }
00310
00311 static void OnInit(const P& val)
00312 {
00313 if (val!=0)
00314 val->reference();
00315 }
00316
00317 static bool Release(const P& val)
00318 {
00319 if (val!=0)
00320 return val->unreference();
00321 return false;
00322 }
00323
00324 enum { destructiveCopy = false };
00325
00326 static void Swap(IntrRefCounted&)
00327 {}
00328 };
00329
00330
00331
00332
00333
00334
00335
00336 template <class P>
00337 class NonSmartShared
00338 {
00339 public:
00340 NonSmartShared()
00341 {}
00342
00343 template <class U>
00344 NonSmartShared(const NonSmartShared<U>&)
00345 {}
00346
00347 static P Clone(const P& val)
00348 {
00349 return val;
00350 }
00351
00352 static void OnInit(const P& val)
00353 {}
00354
00355 static bool Release(const P& val)
00356 {
00357 return false;
00358 }
00359
00360 enum { destructiveCopy = false };
00361
00362 static void Swap(NonSmartShared&)
00363 {}
00364 };
00365
00366
00367
00368
00369
00370
00371
00372
00373 template <class P>
00374 struct DeepCopy
00375 {
00376 DeepCopy()
00377 {}
00378
00379 template <class P1>
00380 DeepCopy(const DeepCopy<P1>&)
00381 {}
00382
00383 static P Clone(const P& val)
00384 { return val->Clone(); }
00385
00386 static void OnInit(const P&)
00387 {}
00388
00389 static bool Release(const P& val)
00390 { return true; }
00391
00392 static void Swap(DeepCopy&)
00393 {}
00394
00395 enum { destructiveCopy = false };
00396 };
00397
00398
00399
00400
00401
00402
00403
00404 namespace Private
00405 {
00406 class RefLinkedBase
00407 {
00408 public:
00409 RefLinkedBase()
00410 { prev_ = next_ = this; }
00411
00412 RefLinkedBase(const RefLinkedBase& rhs)
00413 {
00414 prev_ = &rhs;
00415 next_ = rhs.next_;
00416 prev_->next_ = this;
00417 next_->prev_ = this;
00418 }
00419
00420 bool Release()
00421 {
00422 if (next_ == this)
00423 {
00424 assert(prev_ == this);
00425 return true;
00426 }
00427 prev_->next_ = next_;
00428 next_->prev_ = prev_;
00429 return false;
00430 }
00431
00432 void Swap(RefLinkedBase& rhs)
00433 {
00434 if (next_ == this)
00435 {
00436 assert(prev_ == this);
00437 if (rhs.next_ == &rhs)
00438 {
00439 assert(rhs.prev_ == &rhs);
00440
00441 return;
00442 }
00443 prev_ = rhs.prev_;
00444 next_ = rhs.next_;
00445 prev_->next_ = next_->prev_ = this;
00446 rhs.next_ = rhs.prev_ = &rhs;
00447 return;
00448 }
00449 if (rhs.next_ == &rhs)
00450 {
00451 rhs.Swap(*this);
00452 return;
00453 }
00454 std::swap(prev_, rhs.prev_);
00455 std::swap(next_, rhs.next_);
00456 std::swap(prev_->next_, rhs.prev_->next_);
00457 std::swap(next_->prev_, rhs.next_->prev_);
00458 }
00459
00460 enum { destructiveCopy = false };
00461
00462 private:
00463 mutable const RefLinkedBase* prev_;
00464 mutable const RefLinkedBase* next_;
00465 };
00466 }
00467
00468 template <class P>
00469 class RefLinked : public Private::RefLinkedBase
00470 {
00471 public:
00472 RefLinked()
00473 {}
00474
00475 template <class P1>
00476 RefLinked(const RefLinked<P1>& rhs)
00477 : Private::RefLinkedBase(rhs)
00478 {}
00479
00480 static P Clone(const P& val)
00481 { return val; }
00482
00483 static void OnInit(const P&)
00484 {}
00485
00486 bool Release(const P&)
00487 { return Private::RefLinkedBase::Release(); }
00488 };
00489
00490
00491
00492
00493
00494
00495
00496 template <class P>
00497 class DestructiveCopy
00498 {
00499 public:
00500 DestructiveCopy()
00501 {}
00502
00503 template <class P1>
00504 DestructiveCopy(const DestructiveCopy<P1>&)
00505 {}
00506
00507 template <class P1>
00508 static P Clone(P1& val)
00509 {
00510 P result(val);
00511 val = P1();
00512 return result;
00513 }
00514
00515 static void OnInit(const P&)
00516 {}
00517
00518 static bool Release(const P&)
00519 { return true; }
00520
00521 static void Swap(DestructiveCopy&)
00522 {}
00523
00524 enum { destructiveCopy = true };
00525 };
00526
00527
00528
00529
00530
00531
00532
00533 template <class P>
00534 class NoCopy
00535 {
00536 public:
00537 NoCopy()
00538 {}
00539
00540 template <class P1>
00541 NoCopy(const NoCopy<P1>&)
00542 {}
00543
00544 static P Clone(const P&)
00545 {
00546 CT_ASSERT(false, This_Policy_Disallows_Value_Copying);
00547 }
00548
00549 static void OnInit(const P&)
00550 {}
00551
00552 static bool Release(const P&)
00553 { return true; }
00554
00555 static void Swap(NoCopy&)
00556 {}
00557
00558 enum { destructiveCopy = false };
00559 };
00560
00561
00562
00563
00564
00565
00566
00567 struct AllowConversion
00568 {
00569 enum { allow = true };
00570
00571 void Swap(AllowConversion&)
00572 {}
00573 };
00574
00575
00576
00577
00578
00579
00580
00581
00582 struct DisallowConversion
00583 {
00584 DisallowConversion()
00585 {}
00586
00587 DisallowConversion(const AllowConversion&)
00588 {}
00589
00590 enum { allow = false };
00591
00592 void Swap(DisallowConversion&)
00593 {}
00594 };
00595
00596
00597
00598
00599
00600
00601
00602 template <class P>
00603 struct NoCheck
00604 {
00605 NoCheck()
00606 {}
00607
00608 template <class P1>
00609 NoCheck(const NoCheck<P1>&)
00610 {}
00611
00612 static void OnDefault(const P&)
00613 {}
00614
00615 static void OnInit(const P&)
00616 {}
00617
00618 static void OnDereference(const P&)
00619 {}
00620
00621 static void Swap(NoCheck&)
00622 {}
00623 };
00624
00625
00626
00627
00628
00629
00630
00631
00632 template <class P>
00633 struct AssertCheck
00634 {
00635 AssertCheck()
00636 {}
00637
00638 template <class P1>
00639 AssertCheck(const AssertCheck<P1>&)
00640 {}
00641
00642 template <class P1>
00643 AssertCheck(const NoCheck<P1>&)
00644 {}
00645
00646 static void OnDefault(const P&)
00647 {}
00648
00649 static void OnInit(const P&)
00650 {}
00651
00652 static void OnDereference(P val)
00653 { assert(val); }
00654
00655 static void Swap(AssertCheck&)
00656 {}
00657 };
00658
00659
00660
00661
00662
00663
00664
00665
00666 template <class P>
00667 struct AssertCheckStrict
00668 {
00669 AssertCheckStrict()
00670 {}
00671
00672 template <class U>
00673 AssertCheckStrict(const AssertCheckStrict<U>&)
00674 {}
00675
00676 template <class U>
00677 AssertCheckStrict(const AssertCheck<U>&)
00678 {}
00679
00680 template <class P1>
00681 AssertCheckStrict(const NoCheck<P1>&)
00682 {}
00683
00684 static void OnDefault(P val)
00685 { assert(val); }
00686
00687 static void OnInit(P val)
00688 { assert(val); }
00689
00690 static void OnDereference(P val)
00691 { assert(val); }
00692
00693 static void Swap(AssertCheckStrict&)
00694 {}
00695 };
00696
00697
00698
00699
00700
00701
00702 struct NullPointerException : public std::runtime_error
00703 {
00704 NullPointerException() : std::runtime_error("")
00705 { }
00706 const char* what() const throw()
00707 { return "Null Pointer Exception"; }
00708 };
00709
00710
00711
00712
00713
00714
00715
00716 template <class P>
00717 struct RejectNullStatic
00718 {
00719 RejectNullStatic()
00720 {}
00721
00722 template <class P1>
00723 RejectNullStatic(const RejectNullStatic<P1>&)
00724 {}
00725
00726 template <class P1>
00727 RejectNullStatic(const NoCheck<P1>&)
00728 {}
00729
00730 template <class P1>
00731 RejectNullStatic(const AssertCheck<P1>&)
00732 {}
00733
00734 template <class P1>
00735 RejectNullStatic(const AssertCheckStrict<P1>&)
00736 {}
00737
00738 static void OnDefault(const P&)
00739 {
00740 CompileTimeError<false>
00741 ERROR_This_Policy_Does_Not_Allow_Default_Initialization;
00742 }
00743
00744 static void OnInit(const P& val)
00745 { if (!val) throw NullPointerException(); }
00746
00747 static void OnDereference(const P& val)
00748 { if (!val) throw NullPointerException(); }
00749
00750 static void Swap(RejectNullStatic&)
00751 {}
00752 };
00753
00754
00755
00756
00757
00758
00759
00760 template <class P>
00761 struct RejectNull
00762 {
00763 RejectNull()
00764 {}
00765
00766 template <class P1>
00767 RejectNull(const RejectNull<P1>&)
00768 {}
00769
00770 static void OnInit(P val)
00771 { if (!val) throw NullPointerException(); }
00772
00773 static void OnDefault(P val)
00774 { OnInit(val); }
00775
00776 void OnDereference(P val)
00777 { OnInit(val); }
00778
00779 void Swap(RejectNull&)
00780 {}
00781 };
00782
00783
00784
00785
00786
00787
00788
00789 template <class P>
00790 struct RejectNullStrict
00791 {
00792 RejectNullStrict()
00793 {}
00794
00795 template <class P1>
00796 RejectNullStrict(const RejectNullStrict<P1>&)
00797 {}
00798
00799 template <class P1>
00800 RejectNullStrict(const RejectNull<P1>&)
00801 {}
00802
00803 static void OnInit(P val)
00804 { if (!val) throw NullPointerException(); }
00805
00806 void OnDereference(P val)
00807 { OnInit(val); }
00808
00809 void Swap(RejectNullStrict&)
00810 {}
00811 };
00812
00813
00814
00815
00816
00817
00818
00819 template <class T>
00820 class ByRef
00821 {
00822 public:
00823 ByRef(T& v) : value_(v) {}
00824 operator T&() { return value_; }
00825
00826
00827 private:
00828 T& value_;
00829 };
00830
00831
00832
00833
00834
00835
00836 template
00837 <
00838 typename T,
00839 template <class> class OwnershipPolicy = IntrRefCounted,
00840 class ConversionPolicy = DisallowConversion,
00841 template <class> class CheckingPolicy = AssertCheck,
00842 template <class> class StoragePolicy = DefaultSPStorage
00843 >
00844 class ref;
00845
00846
00847
00848
00849
00850 template
00851 <
00852 typename T,
00853 template <class> class OwnershipPolicy,
00854 class ConversionPolicy,
00855 template <class> class CheckingPolicy,
00856 template <class> class StoragePolicy
00857 >
00858 class ref
00859 : public StoragePolicy<T>
00860 , public OwnershipPolicy<typename StoragePolicy<T>::PointerType>
00861 , public CheckingPolicy<typename StoragePolicy<T>::StoredType>
00862 , public ConversionPolicy
00863 {
00864 typedef StoragePolicy<T> SP;
00865 typedef OwnershipPolicy<typename StoragePolicy<T>::PointerType> OP;
00866 typedef CheckingPolicy<typename StoragePolicy<T>::StoredType> KP;
00867 typedef ConversionPolicy CP;
00868
00869 public:
00870 typedef typename SP::PointerType PointerType;
00871 typedef typename SP::StoredType StoredType;
00872 typedef typename SP::ReferenceType ReferenceType;
00873
00874 typedef typename Select<OP::destructiveCopy,
00875 ref, const ref>::Result
00876 CopyArg;
00877
00878
00879 ref()
00880 { KP::OnDefault(GetImpl(*this)); }
00881
00882 explicit ref(const StoredType& p) : SP(p)
00883 { KP::OnInit(GetImpl(*this)); OP::OnInit(GetImpl(*this)); }
00884
00885 ref(CopyArg& rhs)
00886 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00887 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
00888
00889 template
00890 <
00891 typename T1,
00892 template <class> class OP1,
00893 class CP1,
00894 template <class> class KP1,
00895 template <class> class SP1
00896 >
00897 ref(const ref<T1, OP1, CP1, KP1, SP1>& rhs)
00898 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00899 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
00900
00901 template
00902 <
00903 typename T1,
00904 template <class> class OP1,
00905 class CP1,
00906 template <class> class KP1,
00907 template <class> class SP1
00908 >
00909 ref(ref<T1, OP1, CP1, KP1, SP1>& rhs)
00910 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00911 { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
00912
00913
00914 ref(ByRef<ref> rhs)
00915 : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
00916 {}
00917
00918 operator ByRef<ref>()
00919 { return ByRef<ref>(*this); }
00920
00921 ref& operator=(CopyArg& rhs)
00922 {
00923 ref temp(rhs);
00924 temp.Swap(*this);
00925 return *this;
00926 }
00927
00928 template
00929 <
00930 typename T1,
00931 template <class> class OP1,
00932 class CP1,
00933 template <class> class KP1,
00934 template <class> class SP1
00935 >
00936 ref& operator=(const ref<T1, OP1, CP1, KP1, SP1>& rhs)
00937 {
00938 ref temp(rhs);
00939 temp.Swap(*this);
00940 return *this;
00941 }
00942
00943 template
00944 <
00945 typename T1,
00946 template <class> class OP1,
00947 class CP1,
00948 template <class> class KP1,
00949 template <class> class SP1
00950 >
00951 ref& operator=(ref<T1, OP1, CP1, KP1, SP1>& rhs)
00952 {
00953 ref temp(rhs);
00954 temp.Swap(*this);
00955 return *this;
00956 }
00957
00958 void Swap(ref& rhs)
00959 {
00960 OP::Swap(rhs);
00961 CP::Swap(rhs);
00962 KP::Swap(rhs);
00963 SP::Swap(rhs);
00964 }
00965
00966 ~ref()
00967 {
00968 if (OP::Release(GetImpl(*static_cast<SP*>(this))))
00969 {
00970 SP::Destroy();
00971 }
00972 }
00973
00974 friend inline void Release(ref& sp, typename SP::StoredType& p)
00975 {
00976 p = GetImplRef(sp);
00977 GetImplRef(sp) = SP::Default();
00978 }
00979
00980 friend inline void Release(ref& sp)
00981 {
00982 GetImplRef(sp) = SP::Default();
00983 }
00984
00985 friend inline void Reset(ref& sp, typename SP::StoredType p)
00986 { ref(p).Swap(sp); }
00987
00988 PointerType operator->()
00989 {
00990 KP::OnDereference(GetImplRef(*this));
00991 return SP::operator->();
00992 }
00993
00994 PointerType operator->() const
00995 {
00996 KP::OnDereference(GetImplRef(*this));
00997 return SP::operator->();
00998 }
00999
01000 ReferenceType operator*()
01001 {
01002 KP::OnDereference(GetImplRef(*this));
01003 return SP::operator*();
01004 }
01005
01006 ReferenceType operator*() const
01007 {
01008 KP::OnDereference(GetImplRef(*this));
01009 return SP::operator*();
01010 }
01011
01012
01013 bool operator!() const
01014 { return GetImpl(*this) == 0; }
01015
01016 inline friend bool operator==(const ref& lhs,
01017 const T* rhs)
01018 { return GetImpl(lhs) == rhs; }
01019
01020 inline friend bool operator==(const T* lhs,
01021 const ref& rhs)
01022 { return rhs == lhs; }
01023
01024 inline friend bool operator!=(const ref& lhs,
01025 const T* rhs)
01026 { return !(lhs == rhs); }
01027
01028 inline friend bool operator!=(const T* lhs,
01029 const ref& rhs)
01030 { return rhs != lhs; }
01031
01032
01033 template
01034 <
01035 typename T1,
01036 template <class> class OP1,
01037 class CP1,
01038 template <class> class KP1,
01039 template <class> class SP1
01040 >
01041 bool operator==(const ref<T1, OP1, CP1, KP1, SP1>& rhs) const
01042 { return *this == GetImpl(rhs); }
01043
01044
01045 template
01046 <
01047 typename T1,
01048 template <class> class OP1,
01049 class CP1,
01050 template <class> class KP1,
01051 template <class> class SP1
01052 >
01053 bool operator!=(const ref<T1, OP1, CP1, KP1, SP1>& rhs) const
01054 { return !(*this == rhs); }
01055
01056
01057 template
01058 <
01059 typename T1,
01060 template <class> class OP1,
01061 class CP1,
01062 template <class> class KP1,
01063 template <class> class SP1
01064 >
01065 bool operator<(const ref<T1, OP1, CP1, KP1, SP1>& rhs) const
01066 { return *this < GetImpl(rhs); }
01067
01068 private:
01069
01070 struct Tester
01071 {
01072 Tester() {}
01073 private:
01074 void operator delete(void*);
01075 };
01076
01077 public:
01078
01079 operator Tester*() const
01080 {
01081 if (!*this) return 0;
01082 static Tester t;
01083 return &t;
01084 }
01085
01086 private:
01087
01088 struct Insipid
01089 {
01090 Insipid(PointerType) {}
01091 };
01092
01093 typedef typename Select<CP::allow, PointerType, Insipid>::Result
01094 AutomaticConversionResult;
01095
01096 public:
01097 operator AutomaticConversionResult() const
01098 { return GetImpl(*this); }
01099 };
01100
01101
01102
01103
01104
01105 template
01106 <
01107 typename Sub,
01108 typename Super,
01109 template <class> class OwnershipPolicy,
01110 class ConversionPolicy,
01111 template <class> class CheckingPolicy,
01112 template <class> class StoragePolicy
01113 >
01114 inline base::ref<Sub, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy>
01115 static_cast_ref(const base::ref<Super, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy>& r)
01116 {
01117 base::ref <Sub, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy> subref;
01118 typedef StoragePolicy<Sub> DSP;
01119 typedef OwnershipPolicy<typename StoragePolicy<Sub>::PointerType> OP;
01120 typename DSP::PointerType subp = static_cast<typename DSP::PointerType>(GetImpl(r));
01121 GetImplRef(subref) = (subp!=0)?subref.OP::Clone(subp):0;
01122 return subref;
01123 }
01124
01125 template
01126 <
01127 typename Sub,
01128 typename Super,
01129 template <class> class OwnershipPolicy,
01130 class ConversionPolicy,
01131 template <class> class CheckingPolicy,
01132 template <class> class StoragePolicy
01133 >
01134 inline base::ref<Sub, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy>
01135 dynamic_cast_ref(const base::ref<Super, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy>& r)
01136 {
01137 base::ref <Sub, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy> subref;
01138 typedef StoragePolicy<Sub> DSP;
01139 typedef OwnershipPolicy<typename StoragePolicy<Sub>::PointerType> OP;
01140 typename DSP::PointerType subp = dynamic_cast<typename DSP::PointerType>(GetImpl(r));
01141 GetImplRef(subref) = (subp!=0)?subref.OP::Clone(subp):0;
01142 return subref;
01143 }
01144
01145
01146 template
01147 <
01148 typename Sub,
01149 typename Super,
01150 template <class> class OwnershipPolicy,
01151 class ConversionPolicy,
01152 template <class> class CheckingPolicy,
01153 template <class> class StoragePolicy
01154 >
01155 inline base::ref<Sub, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy>
01156
01157
01158 narrow_cast_ref(base::ref<Super, OwnershipPolicy, ConversionPolicy, CheckingPolicy, StoragePolicy> r)
01159 {
01160 return static_cast_ref<Sub,Super,OwnershipPolicy,ConversionPolicy,CheckingPolicy,StoragePolicy>(r);
01161 }
01162
01163 #define narrow_ref narrow_cast_ref
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174 template
01175 <
01176 typename T,
01177 template <class> class OP,
01178 class CP,
01179 template <class> class KP,
01180 template <class> class SP,
01181 typename U
01182 >
01183 inline bool operator==(const ref<T, OP, CP, KP, SP>& lhs,
01184 const U* rhs)
01185 { return GetImpl(lhs) == rhs; }
01186
01187
01188
01189
01190
01191 template
01192 <
01193 typename T,
01194 template <class> class OP,
01195 class CP,
01196 template <class> class KP,
01197 template <class> class SP,
01198 typename U
01199 >
01200 inline bool operator==(const U* lhs,
01201 const ref<T, OP, CP, KP, SP>& rhs)
01202 { return rhs == lhs; }
01203
01204
01205
01206
01207
01208 template
01209 <
01210 typename T,
01211 template <class> class OP,
01212 class CP,
01213 template <class> class KP,
01214 template <class> class SP,
01215 typename U
01216 >
01217 inline bool operator!=(const ref<T, OP, CP, KP, SP>& lhs,
01218 const U* rhs)
01219 { return !(lhs == rhs); }
01220
01221
01222
01223
01224
01225 template
01226 <
01227 typename T,
01228 template <class> class OP,
01229 class CP,
01230 template <class> class KP,
01231 template <class> class SP,
01232 typename U
01233 >
01234 inline bool operator!=(const U* lhs,
01235 const ref<T, OP, CP, KP, SP>& rhs)
01236 { return rhs != lhs; }
01237
01238
01239
01240
01241
01242 template
01243 <
01244 typename T,
01245 template <class> class OP,
01246 class CP,
01247 template <class> class KP,
01248 template <class> class SP,
01249 typename U
01250 >
01251 inline bool operator<(const ref<T, OP, CP, KP, SP>& lhs,
01252 const U* rhs);
01253
01254
01255
01256
01257
01258 template
01259 <
01260 typename T,
01261 template <class> class OP,
01262 class CP,
01263 template <class> class KP,
01264 template <class> class SP,
01265 typename U
01266 >
01267 inline bool operator<(const U* lhs,
01268 const ref<T, OP, CP, KP, SP>& rhs);
01269
01270
01271
01272
01273
01274 template
01275 <
01276 typename T,
01277 template <class> class OP,
01278 class CP,
01279 template <class> class KP,
01280 template <class> class SP,
01281 typename U
01282 >
01283 inline bool operator>(const ref<T, OP, CP, KP, SP>& lhs,
01284 const U* rhs)
01285 { return rhs < lhs; }
01286
01287
01288
01289
01290
01291 template
01292 <
01293 typename T,
01294 template <class> class OP,
01295 class CP,
01296 template <class> class KP,
01297 template <class> class SP,
01298 typename U
01299 >
01300 inline bool operator>(const U* lhs,
01301 const ref<T, OP, CP, KP, SP>& rhs)
01302 { return rhs < lhs; }
01303
01304
01305
01306
01307
01308 template
01309 <
01310 typename T,
01311 template <class> class OP,
01312 class CP,
01313 template <class> class KP,
01314 template <class> class SP,
01315 typename U
01316 >
01317 inline bool operator<=(const ref<T, OP, CP, KP, SP>& lhs,
01318 const U* rhs)
01319 { return !(rhs < lhs); }
01320
01321
01322
01323
01324
01325 template
01326 <
01327 typename T,
01328 template <class> class OP,
01329 class CP,
01330 template <class> class KP,
01331 template <class> class SP,
01332 typename U
01333 >
01334 inline bool operator<=(const U* lhs,
01335 const ref<T, OP, CP, KP, SP>& rhs)
01336 { return !(rhs < lhs); }
01337
01338
01339
01340
01341
01342 template
01343 <
01344 typename T,
01345 template <class> class OP,
01346 class CP,
01347 template <class> class KP,
01348 template <class> class SP,
01349 typename U
01350 >
01351 inline bool operator>=(const ref<T, OP, CP, KP, SP>& lhs,
01352 const U* rhs)
01353 { return !(lhs < rhs); }
01354
01355
01356
01357
01358
01359 template
01360 <
01361 typename T,
01362 template <class> class OP,
01363 class CP,
01364 template <class> class KP,
01365 template <class> class SP,
01366 typename U
01367 >
01368 inline bool operator>=(const U* lhs,
01369 const ref<T, OP, CP, KP, SP>& rhs)
01370 { return !(lhs < rhs); }
01371
01372 }
01373
01374
01375
01376
01377
01378 namespace std
01379 {
01380 template
01381 <
01382 typename T,
01383 template <class> class OP,
01384 class CP,
01385 template <class> class KP,
01386 template <class> class SP
01387 >
01388 struct less< base::ref<T, OP, CP, KP, SP> >
01389 : public binary_function<base::ref<T, OP, CP, KP, SP>,
01390 base::ref<T, OP, CP, KP, SP>, bool>
01391 {
01392 bool operator()(const base::ref<T, OP, CP, KP, SP>& lhs,
01393 const base::ref<T, OP, CP, KP, SP>& rhs) const
01394 { return less<T*>()(GetImpl(lhs), GetImpl(rhs)); }
01395 };
01396 }
01397
01398
01399
01400
01401
01402
01403 #endif // SMARTPTR_INC_