PLaSK library

Loading...
Searching...
No Matches
tnt_i_refvec.h
Go to the documentation of this file.
1/*
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
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