Kinetic Visualization
 All Classes Functions Variables Pages
tnt_i_refvec.h
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