BWAPI
|
00001 /**************************************************************************** 00002 * Core Library Version 1.7, August 2004 00003 * Copyright (c) 1995-2004 Exact Computation Project 00004 * All rights reserved. 00005 * 00006 * This file is part of CORE (http://cs.nyu.edu/exact/core/); you may 00007 * redistribute it under the terms of the Q Public License version 1.0. 00008 * See the file LICENSE.QPL distributed with CORE. 00009 * 00010 * Licensees holding a valid commercial license may use this file in 00011 * accordance with the commercial license agreement provided with the 00012 * software. 00013 * 00014 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00015 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00016 * 00017 * 00018 * File: RefCount.h 00019 * Synopsis: 00020 * 1. This file defines two templated classes: 00021 * RCRepImpl<class N> 00022 * to create Reps of the class N. The basic functions provided by 00023 * this class is reference counting. The other class is 00024 * RCImpl<class T> 00025 * for implementing the envelop-letter paradigm for a class whose Rep 00026 * is the class T. So, T is the "letter", and RCImpl<T> the "envelop". 00027 * 00028 * 2. All Rep classes (BigIntRep, BigFloatRep, BigRatRep, ExprRep, etc) 00029 * are derived from RCRepImpl<N>. E.g., 00030 * 00031 * class BigRatRep : public RCRepImp<BigRatRep> { 00032 * ... 00033 * } 00034 * (Note the recursive use of "BigRatRep"). 00035 * 00036 * 3. All Number classes (BigInt, BigFloat, BigRat, Expr, etc) 00037 * are derived from RCImpl<T>. E.g. 00038 * 00039 * typedef RCImpl<BigRatRep> RCBigRat; 00040 * class BigRat : public RCBigRat { 00041 * ... 00042 * } 00043 * 00044 * Written by 00045 * Zilin Du <zilin@cs.nyu.edu> 00046 * Chee Yap <yap@cs.nyu.edu> 00047 * 00048 * WWW URL: http://cs.nyu.edu/exact/ 00049 * Email: exact@cs.nyu.edu 00050 * 00051 * $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Core/include/CGAL/CORE/RefCount.h $ 00052 * $Id: RefCount.h 28567 2006-02-16 14:30:13Z lsaboret $ 00053 ***************************************************************************/ 00054 00055 00056 #ifndef _CORE_REFCOUNT_H_ 00057 #define _CORE_REFCOUNT_H_ 00058 00059 CORE_BEGIN_NAMESPACE 00060 00061 template<class Deriving> 00062 class RCRepImpl { 00063 public: 00064 RCRepImpl() : refCount(1) {} 00065 void incRef() { 00066 ++refCount; 00067 } 00068 // Without static_cast this to Deriving*, 00069 // the destructor of Deriving class will never been called. 00070 // this is an example of simulating dynamic binding from ATL. 00071 void decRef() { 00072 if (--refCount == 0) 00073 delete static_cast<Deriving*>(this); 00074 } 00075 int getRefCount() const { 00076 return refCount; 00077 } 00078 private: 00079 int refCount; 00080 }; 00081 00082 template<class T> 00083 class RCImpl { 00084 protected: 00085 RCImpl(T* p) : rep(p) {} 00086 RCImpl(const RCImpl& x) : rep(x.rep) {} 00087 T* rep; 00088 public: 00090 const T& getRep() const { 00091 return *rep; 00092 } 00094 T& getRep() { 00095 return *rep; 00096 } 00098 void makeCopy() { 00099 if (rep->getRefCount() > 1) { 00100 T* oldValue = rep; 00101 rep->decRef(); // safe since rep has been referred at least once. 00102 rep = oldValue ? new T(*oldValue) : 0; 00103 } 00104 } 00105 #ifdef CORE_RC_DEBUG 00106 00107 int getRefCount() const { 00108 return rep->getRefCount(); 00109 } 00110 #endif 00111 }; 00112 00113 CORE_END_NAMESPACE 00114 #endif // _CORE_REFCOUNT_H_