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