00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef INCLUDED_RTL_INSTANCE_HXX
00021 #define INCLUDED_RTL_INSTANCE_HXX
00022
00023 #include "osl/doublecheckedlocking.h"
00024 #include "osl/getglobalmutex.hxx"
00025
00026 namespace {
00027
00261 template< typename Inst, typename InstCtor,
00262 typename Guard, typename GuardCtor,
00263 typename Data = int, typename DataCtor = int >
00264 class rtl_Instance
00265 {
00266 public:
00267 static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor)
00268 {
00269 #if defined _MSC_VER
00270 static Inst * m_pInstance = 0;
00271 #endif // _MSC_VER
00272 Inst * p = m_pInstance;
00273 if (!p)
00274 {
00275 Guard aGuard(aGuardCtor());
00276 p = m_pInstance;
00277 if (!p)
00278 {
00279 p = aInstCtor();
00280 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
00281 m_pInstance = p;
00282 }
00283 }
00284 else
00285 {
00286 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
00287 }
00288 return p;
00289 }
00290
00291 static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor,
00292 DataCtor aDataCtor)
00293 {
00294 #if defined _MSC_VER
00295 static Inst * m_pInstance = 0;
00296 #endif // _MSC_VER
00297 Inst * p = m_pInstance;
00298 if (!p)
00299 {
00300 Data aData(aDataCtor());
00301 Guard aGuard(aGuardCtor());
00302 p = m_pInstance;
00303 if (!p)
00304 {
00305 p = aInstCtor(aData);
00306 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
00307 m_pInstance = p;
00308 }
00309 }
00310 else
00311 {
00312 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
00313 }
00314 return p;
00315 }
00316
00317 static inline Inst * create(InstCtor aInstCtor, GuardCtor aGuardCtor,
00318 const Data &rData)
00319 {
00320 #if defined _MSC_VER
00321 static Inst * m_pInstance = 0;
00322 #endif // _MSC_VER
00323 Inst * p = m_pInstance;
00324 if (!p)
00325 {
00326 Guard aGuard(aGuardCtor());
00327 p = m_pInstance;
00328 if (!p)
00329 {
00330 p = aInstCtor(rData);
00331 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
00332 m_pInstance = p;
00333 }
00334 }
00335 else
00336 {
00337 OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
00338 }
00339 return p;
00340 }
00341
00342 private:
00343 #if !defined _MSC_VER
00344 static Inst * m_pInstance;
00345 #endif // _MSC_VER
00346 };
00347
00348 #if !defined _MSC_VER
00349 template< typename Inst, typename InstCtor,
00350 typename Guard, typename GuardCtor,
00351 typename Data, typename DataCtor >
00352 Inst *
00353 rtl_Instance< Inst, InstCtor, Guard, GuardCtor, Data, DataCtor >::m_pInstance
00354 = 0;
00355 #endif // _MSC_VER
00356
00357 }
00358
00359 namespace rtl {
00360
00380 #if defined HAVE_THREADSAFE_STATICS
00381 template<typename T, typename Unique>
00382 class Static {
00383 public:
00390 static T & get() {
00391 static T instance;
00392 return instance;
00393 }
00394 };
00395 #else
00396 template<typename T, typename Unique>
00397 class Static {
00398 public:
00405 static T & get() {
00406 return *rtl_Instance<
00407 T, StaticInstance,
00408 ::osl::MutexGuard, ::osl::GetGlobalMutex >::create(
00409 StaticInstance(), ::osl::GetGlobalMutex() );
00410 }
00411 private:
00412 struct StaticInstance {
00413 T * operator () () {
00414 static T instance;
00415 return &instance;
00416 }
00417 };
00418 };
00419 #endif
00420
00440 #if defined HAVE_THREADSAFE_STATICS
00441 template<typename T, typename Data, typename Unique>
00442 class StaticWithArg {
00443 public:
00450 static T & get(const Data& rData) {
00451 static T instance(rData);
00452 return instance;
00453 }
00454
00461 static T & get(Data& rData) {
00462 static T instance(rData);
00463 return instance;
00464 }
00465 };
00466 #else
00467 template<typename T, typename Data, typename Unique>
00468 class StaticWithArg {
00469 public:
00476 static T & get(const Data& rData) {
00477 return *rtl_Instance<
00478 T, StaticInstanceWithArg,
00479 ::osl::MutexGuard, ::osl::GetGlobalMutex,
00480 Data >::create( StaticInstanceWithArg(),
00481 ::osl::GetGlobalMutex(),
00482 rData );
00483 }
00484
00491 static T & get(Data& rData) {
00492 return *rtl_Instance<
00493 T, StaticInstanceWithArg,
00494 ::osl::MutexGuard, ::osl::GetGlobalMutex,
00495 Data >::create( StaticInstanceWithArg(),
00496 ::osl::GetGlobalMutex(),
00497 rData );
00498 }
00499 private:
00500 struct StaticInstanceWithArg {
00501 T * operator () (const Data& rData) {
00502 static T instance(rData);
00503 return &instance;
00504 }
00505
00506 T * operator () (Data& rData) {
00507 static T instance(rData);
00508 return &instance;
00509 }
00510 };
00511 };
00512 #endif
00513
00522 #if defined HAVE_THREADSAFE_STATICS
00523 template<typename T, typename InitAggregate>
00524 class StaticAggregate {
00525 public:
00533 static T * get() {
00534 static T *instance = InitAggregate()();
00535 return instance;
00536 }
00537 };
00538 #else
00539 template<typename T, typename InitAggregate>
00540 class StaticAggregate {
00541 public:
00548 static T * get() {
00549 return rtl_Instance<
00550 T, InitAggregate,
00551 ::osl::MutexGuard, ::osl::GetGlobalMutex >::create(
00552 InitAggregate(), ::osl::GetGlobalMutex() );
00553 }
00554 };
00555 #endif
00556
00587 #if defined HAVE_THREADSAFE_STATICS
00588 template<typename T, typename InitData,
00589 typename Unique = InitData, typename Data = T>
00590 class StaticWithInit {
00591 public:
00598 static T & get() {
00599 static T instance = InitData()();
00600 return instance;
00601 }
00602 };
00603 #else
00604 template<typename T, typename InitData,
00605 typename Unique = InitData, typename Data = T>
00606 class StaticWithInit {
00607 public:
00614 static T & get() {
00615 return *rtl_Instance<
00616 T, StaticInstanceWithInit,
00617 ::osl::MutexGuard, ::osl::GetGlobalMutex,
00618 Data, InitData >::create( StaticInstanceWithInit(),
00619 ::osl::GetGlobalMutex(),
00620 InitData() );
00621 }
00622 private:
00623 struct StaticInstanceWithInit {
00624 T * operator () ( Data d ) {
00625 static T instance(d);
00626 return &instance;
00627 }
00628 };
00629 };
00630 #endif
00631 }
00632
00633 #endif // INCLUDED_RTL_INSTANCE_HXX
00634
00635