Essentia  2.1-beta6-dev
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>
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>
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>
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>
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>
215 {
216  if (data_ == NULL)
217  return 0;
218  else
219  return (ref_count_ != NULL ? *ref_count_ : -1) ;
220 }
221 
222 template <class T>
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 
Definition: tnt_i_refvec.h:56
int is_null() const
Definition: tnt_i_refvec.h:202
void set_(T *p, const T *b, const T *e)
void copy_(T *p, const T *q, const T *e)
Definition: tnt_i_refvec.h:85
void destroy()
Definition: tnt_i_refvec.h:174
T * begin()
Definition: tnt_i_refvec.h:124
T * data_
Definition: tnt_i_refvec.h:60
i_refvec(const i_refvec &v)
int * ref_count_
Definition: tnt_i_refvec.h:61
T & operator[](int i)
Definition: tnt_i_refvec.h:136
i_refvec()
Definition: tnt_i_refvec.h:92
i_refvec< T > & operator=(const i_refvec< T > &V)
Definition: tnt_i_refvec.h:151
~i_refvec()
Definition: tnt_i_refvec.h:223
int ref_count() const
Definition: tnt_i_refvec.h:214
Definition: tnt_array1d.h:36
#define NULL
Definition: tnt_i_refvec.h:33