1 // ********** DO NOT REMOVE THIS BANNER **********
2 // ORIG-DATE:    29 fev 2005
3 // -*- Mode : c++ -*-
4 //
5 // SUMMARY  : array modelisation
6 // USAGE    : LGPL
7 // ORG      : LJLL Universite Pierre et Marie Curie, Paris,  FRANCE
8 // AUTHOR   : Frederic Hecht
9 // E-MAIL   : frederic.hecht@ann.jussieu.fr
10 //
11 
12 /*
13 
14 
15 
16  Freefem++ is free software; you can redistribute it and/or modify
17  it under the terms of the GNU Lesser General Public License as published by
18  the Free Software Foundation; either version 2.1 of the License, or
19  (at your option) any later version.
20 
21  Freefem++  is distributed in the hope that it will be useful,
22  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  GNU Lesser General Public License for more details.
25 
26  You should have received a copy of the GNU Lesser General Public License
27  along with Freefem++; if not, write to the Free Software
28  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
29 
30 
31  */
32 
33 #ifndef REFCOUNTER_HPP
34 #define REFCOUNTER_HPP
35 
36 #include "showverb.hpp"
37 #include "error.hpp"
38 
39 class RefCounter;
40 class baseCountPointer;
41 
42 
43 // ruse pour utiliser le prive c RefCounter de
44 //  pas de syntaxe pour des friends template
45 class baseCountPointer { protected:
46  void  add(const  RefCounter * c)  const;
47  void  destroyPtr(const RefCounter *  c)  const;
48 };
49 
50 // <<RefCounter>>
51 class RefCounter {
52   static RefCounter *tnull;
53   mutable int count;
54   protected:
~RefCounter()55   virtual ~RefCounter() {}
RefCounter()56   RefCounter() : count(0) {}
57   public:
destroy() const58   int destroy() const {
59       if(this!=tnull) {throwassert(count>=0);
60         if ( count--==0) {
61 	            SHOWVERB( cout << "True  destruction of " << this <<  endl);
62              delete this;
63              return true;}
64         else{ SHOWVERB(cout << " no destruction count=" << count+1 << " " << this <<  endl);
65               return false;}}
66    else return false;}
increment() const67    void increment() const {count++;SHOWVERB( cout << "increment  of " << this << " "<< count <<  endl);}
decrement() const68     void decrement() const {destroy();}// count--;SHOWVERB( cout << "decrement  of " << this << " "<< count <<  endl);ffassert(count>=0);}
69  friend   class baseCountPointer;
70 // private:
RefCounter(const RefCounter &)71   RefCounter(const RefCounter &) : count(0) {}
operator =(const RefCounter &)72   void operator=(const RefCounter &) { count=0;}
dump(ostream & f) const73     ostream &dump(ostream & f) const { return f <<count;}
74 
75 };
76 
add(const RefCounter * c) const77 inline void baseCountPointer::add(const RefCounter * c)  const
78    { if (c) c->count++; SHOWVERB( cout << "baseCountPointer add  of " << this << " "<< c->count <<  endl);}
destroyPtr(const RefCounter * c) const79 inline void baseCountPointer::destroyPtr(const RefCounter *   c)  const
80    { if (c) c->destroy();}
81 
82 template<class T>
83 class CountPointer: private baseCountPointer {
84  T * c;
85  public:
CountPointer()86  CountPointer() : c(0) {}
CountPointer(T * a,bool mmaster=false)87  CountPointer( T * a,bool mmaster=false) :c(a) { if(!mmaster) add(c);}
CountPointer(T & a)88  CountPointer(  T & a) :c(&a) { add(c);}
CountPointer(const CountPointer & a)89  CountPointer(const CountPointer & a) :c(a.c) { add(c);}
~CountPointer()90  ~CountPointer()  { destroyPtr(c);c=0;}
91  //void destroy() const { destroyPtr(c);}
destroy()92  void destroy()  { destroyPtr(c);c=0;}
operator T*() const93  operator  T * ()   const { return c;}
operator T&() const94  operator   T & () const  {return *c;}
operator *() const95   T& operator*() const {return *c;}
operator ->() const96   T* operator->() const {return c;}
operator ==(const CountPointer & n) const97  bool operator==(const  CountPointer & n) const {return  n.c ==c;}
operator !=(const CountPointer & n) const98  bool operator!=(const  CountPointer & n) const {return  n.c !=c;}
operator !() const99  bool operator!() const { return !c;}
operator =(const CountPointer & n)100  void operator=(const  CountPointer & n) {
101   if(*this != n) { destroyPtr(c);
102                 c=n.c;
103                 add(c);
104               }}
cswap(CountPointer & n)105  void cswap(CountPointer & n) {if(*this != n) swap(c,n.c)    ;}
operator =(T * t)106  void operator=( T * t) {
107   if( c != t) { if(c) destroyPtr(c);
108                 c=t;
109                 add(c);
110               }}
111 //  for the compile time
init()112  void init() {c=0;} //
master(T * t)113  void master(T *t) {
114      destroyPtr(c);
115      c=t;}
116 };
117 
118 #endif
119