acsComponentSmartPtr.h
Go to the documentation of this file.00001
#ifndef ACSSMARTPOINTER_H
00002
#define ACSSMARTPOINTER_H
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
#ifndef __cplusplus
00039
#error This is a C++ include file and cannot be used from plain C
00040
#endif
00041
00042
#include <logging.h>
00043
#include <lokiThreads.h>
00044
#include <lokiSmartPtr.h>
00045
#include <maciErrType.h>
00046
00047
namespace maci {
00048
00049
00056
template <
class T,
class H>
00057 class ComponentStorage
00058 {
00059
public:
00060 typedef T*
StoredType;
00061 typedef T*
PointerType;
00062 typedef T&
ReferenceType;
00063
00067 ComponentStorage() :
handle(0),
sticky(true),
pointee_(
Default())
00068 {}
00069
00073 ComponentStorage(
const StoredType& p) :
handle(0),
sticky(true),
pointee_(p)
00074 {}
00075
00076
00077
00081 ComponentStorage(
const ComponentStorage& rhs) :
handle(rhs.
handle),
sticky(rhs.
sticky),
pointee_(0)
00082 {}
00083
00088
template <
typename U,
typename V>
00089 ComponentStorage(
const ComponentStorage<U,V>&) :
handle(0),
sticky(true),
pointee_(0)
00090 {}
00091
00101 void setValues(H *h,
bool s,
const StoredType& p)
00102 {
00103
handle = h;
00104
sticky = s;
00105
pointee_ = p;
00106 };
00107
00111 PointerType operator->()
const {
return pointee_; }
00112
00116 ReferenceType operator*()
const {
return *
pointee_; }
00117
00123 void Swap(
ComponentStorage& rhs)
00124 {
00125 std::swap(
pointee_, rhs.
pointee_);
00126 std::swap(
sticky, rhs.
sticky);
00127 std::swap(
handle, rhs.
handle);
00128 }
00129
00130
00135 friend inline PointerType GetImpl(
const ComponentStorage& sp)
00136 {
return sp.
pointee_; }
00137
00142 friend inline const StoredType&
GetImplRef(
const ComponentStorage& sp)
00143 {
return sp.
pointee_; }
00144
00149 friend inline StoredType&
GetImplRef(
ComponentStorage& sp)
00150 {
return sp.
pointee_; }
00151
00152
protected:
00153
00158 void Destroy()
00159 {
00160
try
00161 {
00162
if (
handle &&
pointee_ &&
sticky)
00163 {
00164
handle->releaseComponent(
pointee_->name());
00165 }
00166 }
00167
catch(maciErrType::CannotReleaseComponentExImpl& ex)
00168 {
00169
ACS_LOG(
LM_RUNTIME_CONTEXT,
"maci::ComponentStorage::Destroy",
00170 (LM_ERROR,
"Unable to release component"));
00171 }
00172
catch(...)
00173 {
00174
ACS_LOG(
LM_RUNTIME_CONTEXT,
"maci::ComponentStorage::Destroy",
00175 (LM_ERROR,
"Unexpected exception caught when releasing component."));
00176 }
00177 }
00178
00179 static StoredType Default()
00180 {
return 0; }
00181
00182
private:
00183
00184 H *
handle;
00185 bool sticky;
00186 StoredType pointee_;
00187 };
00188
00189
00190
class ContainerServices;
00191
00192
00193
00194
00195
00196
00197
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00212
00213
template
00214 <
00215
typename T,
00216
typename H =
ContainerServices,
00217
template <
class>
class OwnershipPolicy = Loki::RefCountedMTAdj<Loki::ObjectLevelLockable>::RefCountedMT,
00218
class ConversionPolicy = Loki::DisallowConversion,
00219
template <
class>
class CheckingPolicy = Loki::NoCheck,
00220
template <
class,
class>
class StoragePolicy =
ComponentStorage,
00221
template<
class>
class ConstnessPolicy = Loki::LOKI_DEFAULT_CONSTNESS
00222 >
00223 class SmartPtr
00224 :
public StoragePolicy<T,H>
00225 ,
public OwnershipPolicy<typename StoragePolicy<T,H>::PointerType>
00226 ,
public CheckingPolicy<typename StoragePolicy<T,H>::StoredType>
00227 ,
public ConversionPolicy
00228 {
00229 typedef StoragePolicy<T,H>
SP;
00230 typedef OwnershipPolicy<typename StoragePolicy<T,H>
::PointerType>
OP;
00231 typedef CheckingPolicy<typename StoragePolicy<T,H>
::StoredType>
KP;
00232 typedef ConversionPolicy
CP;
00233
00234
public:
00235 typedef typename ConstnessPolicy<T>::Type*
ConstPointerType;
00236 typedef typename ConstnessPolicy<T>::Type&
ConstReferenceType;
00237
00238 typedef typename SP::PointerType
PointerType;
00239 typedef typename SP::StoredType
StoredType;
00240 typedef typename SP::ReferenceType
ReferenceType;
00241
00242 typedef typename Loki::Select<OP::destructiveCopy,SmartPtr, const SmartPtr>::Result
CopyArg;
00243
00244
private:
00245
struct NeverMatched;
00246
00247
#ifdef LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY
00248
typedef typename Loki::Select< CP::allow, const StoredType&, NeverMatched>::Result
ImplicitArg;
00249
typedef typename Loki::Select<!CP::allow, const StoredType&, NeverMatched>::Result
ExplicitArg;
00250
#else
00251 typedef const StoredType&
ImplicitArg;
00252 typedef typename Loki::Select<false, const StoredType&, NeverMatched>::Result
ExplicitArg;
00253
#endif
00254
00255
public:
00256
00257 SmartPtr()
00258 { KP::OnDefault(GetImpl(*
this)); }
00259
00269 SmartPtr(H* h,
bool s, T* p)
00270 {
00271 setValues(h, s, p);
00272 }
00273
00274
explicit
00275 SmartPtr(
ExplicitArg p) :
SP(p)
00276 { KP::OnInit(GetImpl(*
this)); }
00277
00278 SmartPtr(
ImplicitArg p) :
SP(p)
00279 { KP::OnInit(GetImpl(*
this)); }
00280
00281 SmartPtr(
CopyArg& rhs)
00282 :
SP(rhs),
OP(rhs),
KP(rhs),
CP(rhs)
00283 { GetImplRef(*
this) = OP::Clone(GetImplRef(rhs)); }
00284
00285
template
00286 <
00287
typename T1,
00288
typename H1,
00289
template <
class>
class OP1,
00290
class CP1,
00291
template <
class>
class KP1,
00292
template <
class,
class>
class SP1,
00293
template <
class>
class CNP1
00294 >
00295 SmartPtr(
const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00296 :
SP(rhs),
OP(rhs),
KP(rhs),
CP(rhs)
00297 { GetImplRef(*
this) = OP::Clone(GetImplRef(rhs)); }
00298
00299
template
00300 <
00301
typename T1,
00302
typename H1,
00303
template <
class>
class OP1,
00304
class CP1,
00305
template <
class>
class KP1,
00306
template <
class,
class>
class SP1,
00307
template <
class>
class CNP1
00308 >
00309 SmartPtr(
SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00310 :
SP(rhs),
OP(rhs),
KP(rhs),
CP(rhs)
00311 { GetImplRef(*
this) = OP::Clone(GetImplRef(rhs)); }
00312
00313 SmartPtr(Loki::RefToValue<SmartPtr> rhs)
00314 :
SP(rhs),
OP(rhs),
KP(rhs),
CP(rhs)
00315 {}
00316
00317 operator Loki::RefToValue<SmartPtr>()
00318 {
return Loki::RefToValue<SmartPtr>(*this); }
00319
00320 SmartPtr& operator=(
CopyArg& rhs)
00321 {
00322
SmartPtr temp(rhs);
00323 temp.
Swap(*
this);
00324
return *
this;
00325 }
00326
00327
template
00328 <
00329
typename T1,
00330
typename H1,
00331
template <
class>
class OP1,
00332
class CP1,
00333
template <
class>
class KP1,
00334
template <
class,
class>
class SP1,
00335
template <
class>
class CNP1
00336 >
00337 SmartPtr& operator=(
const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00338 {
00339
SmartPtr temp(rhs);
00340 temp.
Swap(*
this);
00341
return *
this;
00342 }
00343
00344
template
00345 <
00346
typename T1,
00347
typename H1,
00348
template <
class>
class OP1,
00349
class CP1,
00350
template <
class>
class KP1,
00351
template <
class,
class>
class SP1,
00352
template <
class>
class CNP1
00353 >
00354 SmartPtr& operator=(
SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
00355 {
00356
SmartPtr temp(rhs);
00357 temp.
Swap(*
this);
00358
return *
this;
00359 }
00360
00361 void Swap(
SmartPtr& rhs)
00362 {
00363 OP::Swap(rhs);
00364 CP::Swap(rhs);
00365 KP::Swap(rhs);
00366 SP::Swap(rhs);
00367 }
00368
00369 ~
SmartPtr()
00370 {
00371
if (OP::Release(GetImpl(*static_cast<SP*>(
this))))
00372 {
00373 SP::Destroy();
00374 }
00375 }
00376
00377 friend inline void Release(
SmartPtr& sp,
typename SP::StoredType& p)
00378 {
00379 p = GetImplRef(sp);
00380 GetImplRef(sp) = SP::Default();
00381 }
00382
00383 friend inline void Reset(
SmartPtr& sp,
typename SP::StoredType p)
00384 {
SmartPtr(p).Swap(sp); }
00385
00386
template
00387 <
00388
typename T1,
00389
typename H1,
00390
template <
class>
class OP1,
00391
class CP1,
00392
template <
class>
class KP1,
00393
template <
class,
class>
class SP1,
00394
template <
class>
class CNP1
00395 >
00396 bool Merge(
SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00397 {
00398
if ( GetImpl( *
this ) != GetImpl( rhs ) )
00399 {
00400
return false;
00401 }
00402
return OP::Merge( rhs );
00403 }
00404
00405 PointerType operator->()
00406 {
00407 KP::OnDereference(GetImplRef(*
this));
00408
return SP::operator->();
00409 }
00410
00411 ConstPointerType operator->()
const
00412
{
00413 KP::OnDereference(GetImplRef(*
this));
00414
return SP::operator->();
00415 }
00416
00417 ReferenceType operator*()
00418 {
00419 KP::OnDereference(GetImplRef(*
this));
00420
return SP::operator*();
00421 }
00422
00423 ConstReferenceType operator*()
const
00424
{
00425 KP::OnDereference(GetImplRef(*
this));
00426
return SP::operator*();
00427 }
00428
00429 bool operator!() const
00430 {
return GetImpl(*
this) == 0; }
00431
00432 static inline T * GetPointer(
const SmartPtr & sp )
00433 {
return GetImpl( sp ); }
00434
00435
00436
template
00437 <
00438
typename T1,
00439
typename H1,
00440
template <
class>
class OP1,
00441
class CP1,
00442
template <
class>
class KP1,
00443
template <
class,
class>
class SP1,
00444
template <
class>
class CNP1
00445 >
00446 bool operator==(
const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
const
00447
{
return GetImpl(*
this) == GetImpl(rhs); }
00448
00449
00450
template
00451 <
00452
typename T1,
00453
typename H1,
00454
template <
class>
class OP1,
00455
class CP1,
00456
template <
class>
class KP1,
00457
template <
class,
class>
class SP1,
00458
template <
class>
class CNP1
00459 >
00460 bool operator!=(
const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
const
00461
{
return !(*
this == rhs); }
00462
00463
00464
template
00465 <
00466
typename T1,
00467
typename H1,
00468
template <
class>
class OP1,
00469
class CP1,
00470
template <
class>
class KP1,
00471
template <
class,
class>
class SP1,
00472
template <
class>
class CNP1
00473 >
00474 bool operator<(const SmartPtr<T1, H1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
const
00475 {
return GetImpl(*
this) < GetImpl(rhs); }
00476
00477
00478
template
00479 <
00480
typename T1,
00481
typename H1,
00482
template <
class>
class OP1,
00483
class CP1,
00484
template <
class>
class KP1,
00485
template <
class,
class>
class SP1,
00486
template <
class>
class CNP1
00487 >
00488 inline bool operator > (
const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00489 {
00490
return ( GetImpl( rhs ) < GetImpl( *
this ) );
00491 }
00492
00493
00494
template
00495 <
00496
typename T1,
00497
typename H1,
00498
template <
class>
class OP1,
00499
class CP1,
00500
template <
class>
class KP1,
00501
template <
class,
class>
class SP1,
00502
template <
class>
class CNP1
00503 >
00504 inline bool operator <= ( const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00505 {
00506
return !( GetImpl( rhs ) < GetImpl( *
this ) );
00507 }
00508
00509
00510
template
00511 <
00512
typename T1,
00513
typename H1,
00514
template <
class>
class OP1,
00515
class CP1,
00516
template <
class>
class KP1,
00517
template <
class,
class>
class SP1,
00518
template <
class>
class CNP1
00519 >
00520 inline bool operator >= (
const SmartPtr< T1, H1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
00521 {
00522
return !( GetImpl( *
this ) < GetImpl( rhs ) );
00523 }
00524
00525
private:
00526
00527 struct Tester
00528 {
00529 Tester(
int) {}
00530 void dummy() {}
00531 };
00532
00533 typedef void (Tester::*
unspecified_boolean_type_)();
00534
00535
typedef typename Loki::Select<CP::allow, Tester, unspecified_boolean_type_>::Result
00536 unspecified_boolean_type;
00537
00538
public:
00539
00540 operator unspecified_boolean_type()
const
00541
{
00542
return !*
this ? 0 : &Tester::dummy;
00543 }
00544
00545
private:
00546
00547 struct Insipid
00548 {
00549 Insipid(
PointerType) {}
00550 };
00551
00552
typedef typename Loki::Select<CP::allow, PointerType, Insipid>::Result
00553 AutomaticConversionResult;
00554
00555
public:
00556 operator AutomaticConversionResult()
const
00557
{
return GetImpl(*
this); }
00558 };
00559
00561
00563
00568
00569
template
00570 <
00571
typename T,
00572
typename H,
00573
template <
class>
class OP,
00574
class CP,
00575
template <
class>
class KP,
00576
template <
class,
class>
class SP,
00577
template <
class>
class CNP1,
00578
typename U
00579 >
00580 inline bool operator==(
const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& lhs,
00581 U* rhs)
00582 {
return GetImpl(lhs) == rhs; }
00583
00588
00589
template
00590 <
00591
typename T,
00592
typename H,
00593
template <
class>
class OP,
00594
class CP,
00595
template <
class>
class KP,
00596
template <
class,
class>
class SP,
00597
template <
class>
class CNP1,
00598
typename U
00599 >
00600 inline bool operator==(U* lhs,
00601
const SmartPtr<T, H, OP, CP, KP, SP, CNP1 >& rhs)
00602 {
return rhs == lhs; }
00603
00608
00609
template
00610 <
00611
typename T,
00612
typename H,
00613
template <
class>
class OP,
00614
class CP,
00615
template <
class>
class KP,
00616
template <
class,
class>
class SP,
00617
template <
class>
class CNP,
00618
typename U
00619 >
00620 inline bool operator!=(
const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00621 U* rhs)
00622 {
return !(lhs == rhs); }
00623
00628
00629
template
00630 <
00631
typename T,
00632
typename H,
00633
template <
class>
class OP,
00634
class CP,
00635
template <
class>
class KP,
00636
template <
class,
class>
class SP,
00637
template <
class>
class CNP,
00638
typename U
00639 >
00640 inline bool operator!=(U* lhs,
00641
const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00642 {
return rhs != lhs; }
00643
00648
00649
template
00650 <
00651
typename T,
00652
typename H,
00653
template <
class>
class OP,
00654
class CP,
00655
template <
class>
class KP,
00656
template <
class,
class>
class SP,
00657
template <
class>
class CNP,
00658
typename U
00659 >
00660 inline bool operator<(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00661 U* rhs)
00662 {
00663
return ( GetImpl( lhs ) < rhs );
00664 }
00665
00670
00671
template
00672 <
00673
typename T,
00674
typename H,
00675
template <
class>
class OP,
00676
class CP,
00677
template <
class>
class KP,
00678
template <
class,
class>
class SP,
00679
template <
class>
class CNP,
00680
typename U
00681 >
00682 inline bool operator<(U* lhs,
00683
const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00684 {
00685
return ( GetImpl( rhs ) < lhs );
00686 }
00687
00689
00692
00693
template
00694 <
00695
typename T,
00696
typename H,
00697
template <
class>
class OP,
00698
class CP,
00699
template <
class>
class KP,
00700
template <
class,
class>
class SP,
00701
template <
class>
class CNP,
00702
typename U
00703 >
00704 inline bool operator>(
const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00705 U* rhs)
00706 {
return rhs < lhs; }
00707
00712
00713
template
00714 <
00715
typename T,
00716
typename H,
00717
template <
class>
class OP,
00718
class CP,
00719
template <
class>
class KP,
00720
template <
class,
class>
class SP,
00721
template <
class>
class CNP,
00722
typename U
00723 >
00724 inline bool operator>(U* lhs,
00725
const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00726 {
return rhs < lhs; }
00727
00732
00733
template
00734 <
00735
typename T,
00736
typename H,
00737
template <
class>
class OP,
00738
class CP,
00739
template <
class>
class KP,
00740
template <
class,
class>
class SP,
00741
template <
class>
class CNP,
00742
typename U
00743 >
00744 inline bool operator<=(const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00745 U* rhs)
00746 {
return !(rhs < lhs); }
00747
00752
00753
template
00754 <
00755
typename T,
00756
typename H,
00757
template <
class>
class OP,
00758
class CP,
00759
template <
class>
class KP,
00760
template <
class,
class>
class SP,
00761
template <
class>
class CNP,
00762
typename U
00763 >
00764 inline bool operator<=(U* lhs,
00765
const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00766 {
return !(rhs < lhs); }
00767
00772
00773
template
00774 <
00775
typename T,
00776
typename H,
00777
template <
class>
class OP,
00778
class CP,
00779
template <
class>
class KP,
00780
template <
class,
class>
class SP,
00781
template <
class>
class CNP,
00782
typename U
00783 >
00784 inline bool operator>=(
const SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00785 U* rhs)
00786 {
return !(lhs < rhs); }
00787
00792
00793
template
00794 <
00795
typename T,
00796
typename H,
00797
template <
class>
class OP,
00798
class CP,
00799
template <
class>
class KP,
00800
template <
class,
class>
class SP,
00801
template <
class>
class CNP,
00802
typename U
00803 >
00804 inline bool operator>=(U* lhs,
00805
const SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
00806 {
return !(lhs < rhs); }
00807
00808 };
00809
00814
00815 namespace std
00816 {
00817
template
00818 <
00819
typename T,
00820
typename H,
00821
template <
class>
class OP,
00822
class CP,
00823
template <
class>
class KP,
00824
template <
class,
class>
class SP,
00825
template <
class>
class CNP
00826 >
00827 struct less< maci::SmartPtr<T, H, OP, CP, KP, SP, CNP > >
00828 :
public binary_function<maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >,
00829 maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >, bool>
00830 {
00831 bool operator()(
const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& lhs,
00832
const maci::SmartPtr<T, H, OP, CP, KP, SP, CNP >& rhs)
const
00833
{
return less<T*>()(GetImpl(lhs), GetImpl(rhs)); }
00834 };
00835 };
00836
00837
#endif
Generated on Thu Apr 30 02:30:48 2009 for ACS C++ API by
1.3.8