1 |
gezelter |
1336 |
/* |
2 |
|
|
* |
3 |
|
|
* Template Numerical Toolkit (TNT) |
4 |
|
|
* |
5 |
|
|
* Mathematical and Computational Sciences Division |
6 |
|
|
* National Institute of Technology, |
7 |
|
|
* Gaithersburg, MD USA |
8 |
|
|
* |
9 |
|
|
* |
10 |
|
|
* This software was developed at the National Institute of Standards and |
11 |
|
|
* Technology (NIST) by employees of the Federal Government in the course |
12 |
|
|
* of their official duties. Pursuant to title 17 Section 105 of the |
13 |
|
|
* United States Code, this software is not subject to copyright protection |
14 |
|
|
* and is in the public domain. NIST assumes no responsibility whatsoever for |
15 |
|
|
* its use by other parties, and makes no guarantees, expressed or implied, |
16 |
|
|
* about its quality, reliability, or any other characteristic. |
17 |
|
|
* |
18 |
|
|
*/ |
19 |
|
|
|
20 |
|
|
|
21 |
|
|
|
22 |
|
|
#ifndef TNT_I_REFVEC_H |
23 |
|
|
#define TNT_I_REFVEC_H |
24 |
|
|
|
25 |
|
|
#include <cstdlib> |
26 |
|
|
#include <iostream> |
27 |
|
|
|
28 |
|
|
#ifdef TNT_BOUNDS_CHECK |
29 |
|
|
#include <assert.h> |
30 |
|
|
#endif |
31 |
|
|
|
32 |
|
|
#ifndef NULL |
33 |
|
|
#define NULL 0 |
34 |
|
|
#endif |
35 |
|
|
|
36 |
|
|
namespace TNT |
37 |
|
|
{ |
38 |
|
|
/* |
39 |
|
|
Internal representation of ref-counted array. The TNT |
40 |
|
|
arrays all use this building block. |
41 |
|
|
|
42 |
|
|
<p> |
43 |
|
|
If an array block is created by TNT, then every time |
44 |
|
|
an assignment is made, the left-hand-side reference |
45 |
|
|
is decreased by one, and the right-hand-side refernce |
46 |
|
|
count is increased by one. If the array block was |
47 |
|
|
external to TNT, the refernce count is a NULL pointer |
48 |
|
|
regardless of how many references are made, since the |
49 |
|
|
memory is not freed by TNT. |
50 |
|
|
|
51 |
|
|
|
52 |
|
|
|
53 |
|
|
*/ |
54 |
|
|
template <class T> |
55 |
|
|
class i_refvec |
56 |
|
|
{ |
57 |
|
|
|
58 |
|
|
|
59 |
|
|
private: |
60 |
|
|
T* data_; |
61 |
|
|
int *ref_count_; |
62 |
|
|
|
63 |
|
|
|
64 |
|
|
public: |
65 |
|
|
|
66 |
|
|
i_refvec(); |
67 |
|
|
explicit i_refvec(int n); |
68 |
|
|
inline i_refvec(T* data); |
69 |
|
|
inline i_refvec(const i_refvec &v); |
70 |
|
|
inline T* begin(); |
71 |
|
|
inline const T* begin() const; |
72 |
|
|
inline T& operator[](int i); |
73 |
|
|
inline const T& operator[](int i) const; |
74 |
|
|
inline i_refvec<T> & operator=(const i_refvec<T> &V); |
75 |
|
|
void copy_(T* p, const T* q, const T* e); |
76 |
|
|
void set_(T* p, const T* b, const T* e); |
77 |
|
|
inline int ref_count() const; |
78 |
|
|
inline int is_null() const; |
79 |
|
|
inline void destroy(); |
80 |
|
|
~i_refvec(); |
81 |
|
|
|
82 |
|
|
}; |
83 |
|
|
|
84 |
|
|
template <class T> |
85 |
|
|
void i_refvec<T>::copy_(T* p, const T* q, const T* e) |
86 |
|
|
{ |
87 |
|
|
for (T* t=p; q<e; t++, q++) |
88 |
|
|
*t= *q; |
89 |
|
|
} |
90 |
|
|
|
91 |
|
|
template <class T> |
92 |
|
|
i_refvec<T>::i_refvec() : data_(NULL), ref_count_(NULL) {} |
93 |
|
|
|
94 |
|
|
/** |
95 |
|
|
In case n is 0 or negative, it does NOT call new. |
96 |
|
|
*/ |
97 |
|
|
template <class T> |
98 |
|
|
i_refvec<T>::i_refvec(int n) : data_(NULL), ref_count_(NULL) |
99 |
|
|
{ |
100 |
|
|
if (n >= 1) |
101 |
|
|
{ |
102 |
|
|
#ifdef TNT_DEBUG |
103 |
|
|
std::cout << "new data storage.\n"; |
104 |
|
|
#endif |
105 |
|
|
data_ = new T[n]; |
106 |
|
|
ref_count_ = new int; |
107 |
|
|
*ref_count_ = 1; |
108 |
|
|
} |
109 |
|
|
} |
110 |
|
|
|
111 |
|
|
template <class T> |
112 |
|
|
inline i_refvec<T>::i_refvec(const i_refvec<T> &V): data_(V.data_), |
113 |
|
|
ref_count_(V.ref_count_) |
114 |
|
|
{ |
115 |
|
|
if (V.ref_count_ != NULL) |
116 |
|
|
(*(V.ref_count_))++; |
117 |
|
|
} |
118 |
|
|
|
119 |
|
|
|
120 |
|
|
template <class T> |
121 |
|
|
i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {} |
122 |
|
|
|
123 |
|
|
template <class T> |
124 |
|
|
inline T* i_refvec<T>::begin() |
125 |
|
|
{ |
126 |
|
|
return data_; |
127 |
|
|
} |
128 |
|
|
|
129 |
|
|
template <class T> |
130 |
|
|
inline const T& i_refvec<T>::operator[](int i) const |
131 |
|
|
{ |
132 |
|
|
return data_[i]; |
133 |
|
|
} |
134 |
|
|
|
135 |
|
|
template <class T> |
136 |
|
|
inline T& i_refvec<T>::operator[](int i) |
137 |
|
|
{ |
138 |
|
|
return data_[i]; |
139 |
|
|
} |
140 |
|
|
|
141 |
|
|
|
142 |
|
|
template <class T> |
143 |
|
|
inline const T* i_refvec<T>::begin() const |
144 |
|
|
{ |
145 |
|
|
return data_; |
146 |
|
|
} |
147 |
|
|
|
148 |
|
|
|
149 |
|
|
|
150 |
|
|
template <class T> |
151 |
|
|
i_refvec<T> & i_refvec<T>::operator=(const i_refvec<T> &V) |
152 |
|
|
{ |
153 |
|
|
if (this == &V) |
154 |
|
|
return *this; |
155 |
|
|
|
156 |
|
|
|
157 |
|
|
if (ref_count_ != NULL) |
158 |
|
|
{ |
159 |
|
|
(*ref_count_) --; |
160 |
|
|
if ((*ref_count_) == 0) |
161 |
|
|
destroy(); |
162 |
|
|
} |
163 |
|
|
|
164 |
|
|
data_ = V.data_; |
165 |
|
|
ref_count_ = V.ref_count_; |
166 |
|
|
|
167 |
|
|
if (V.ref_count_ != NULL) |
168 |
|
|
(*(V.ref_count_))++; |
169 |
|
|
|
170 |
|
|
return *this; |
171 |
|
|
} |
172 |
|
|
|
173 |
|
|
template <class T> |
174 |
|
|
void i_refvec<T>::destroy() |
175 |
|
|
{ |
176 |
|
|
if (ref_count_ != NULL) |
177 |
|
|
{ |
178 |
|
|
#ifdef TNT_DEBUG |
179 |
|
|
std::cout << "destorying data... \n"; |
180 |
|
|
#endif |
181 |
|
|
delete ref_count_; |
182 |
|
|
|
183 |
|
|
#ifdef TNT_DEBUG |
184 |
|
|
std::cout << "deleted ref_count_ ...\n"; |
185 |
|
|
#endif |
186 |
|
|
if (data_ != NULL) |
187 |
|
|
delete []data_; |
188 |
|
|
#ifdef TNT_DEBUG |
189 |
|
|
std::cout << "deleted data_[] ...\n"; |
190 |
|
|
#endif |
191 |
|
|
data_ = NULL; |
192 |
|
|
} |
193 |
|
|
} |
194 |
|
|
|
195 |
|
|
/* |
196 |
|
|
* return 1 is vector is empty, 0 otherwise |
197 |
|
|
* |
198 |
|
|
* if is_null() is false and ref_count() is 0, then |
199 |
|
|
* |
200 |
|
|
*/ |
201 |
|
|
template<class T> |
202 |
|
|
int i_refvec<T>::is_null() const |
203 |
|
|
{ |
204 |
|
|
return (data_ == NULL ? 1 : 0); |
205 |
|
|
} |
206 |
|
|
|
207 |
|
|
/* |
208 |
|
|
* returns -1 if data is external, |
209 |
|
|
* returns 0 if a is NULL array, |
210 |
|
|
* otherwise returns the positive number of vectors sharing |
211 |
|
|
* this data space. |
212 |
|
|
*/ |
213 |
|
|
template <class T> |
214 |
|
|
int i_refvec<T>::ref_count() const |
215 |
|
|
{ |
216 |
|
|
if (data_ == NULL) |
217 |
|
|
return 0; |
218 |
|
|
else |
219 |
|
|
return (ref_count_ != NULL ? *ref_count_ : -1) ; |
220 |
|
|
} |
221 |
|
|
|
222 |
|
|
template <class T> |
223 |
|
|
i_refvec<T>::~i_refvec() |
224 |
|
|
{ |
225 |
|
|
if (ref_count_ != NULL) |
226 |
|
|
{ |
227 |
|
|
(*ref_count_)--; |
228 |
|
|
|
229 |
|
|
if (*ref_count_ == 0) |
230 |
|
|
destroy(); |
231 |
|
|
} |
232 |
|
|
} |
233 |
|
|
|
234 |
|
|
|
235 |
|
|
} /* namespace TNT */ |
236 |
|
|
|
237 |
|
|
|
238 |
|
|
|
239 |
|
|
|
240 |
|
|
|
241 |
|
|
#endif |
242 |
|
|
/* TNT_I_REFVEC_H */ |
243 |
|
|
|