ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/math/tnt_i_refvec.hpp
Revision: 1336
Committed: Tue Apr 7 20:16:26 2009 UTC (16 years ago) by gezelter
File size: 4396 byte(s)
Log Message:
adding jama and tnt libraries for various linear algebra routines

File Contents

# User Rev Content
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