source: sasview/src/sas/sascalc/simulation/iqPy/libiqPy/tnt/tnt_i_refvec.h @ c7634fd

magnetic_scattrelease-4.2.2ticket-1009ticket-1094-headlessticket-1242-2d-resolutionticket-1243ticket-1249unittest-saveload
Last change on this file since c7634fd was d85c194, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 9 years ago

Remaining modules refactored

  • Property mode set to 100644
File size: 4.3 KB
Line 
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
36namespace 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*/
54template <class T>
55class 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
84template <class T>
85void 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
91template <class T>
92i_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*/
97template <class T>
98i_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
111template <class T>
112inline   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
120template <class T>
121i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {}
122
123template <class T>
124inline T* i_refvec<T>::begin()
125{
126        return data_;
127}
128
129template <class T>
130inline const T& i_refvec<T>::operator[](int i) const
131{
132        return data_[i];
133}
134
135template <class T>
136inline T& i_refvec<T>::operator[](int i)
137{
138        return data_[i];
139}
140
141
142template <class T>
143inline const T* i_refvec<T>::begin() const
144{
145        return data_;
146}
147
148
149
150template <class T>
151i_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
173template <class T>
174void 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*/
201template<class T>
202int 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*/
213template <class T>
214int 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
222template <class T>
223i_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
Note: See TracBrowser for help on using the repository browser.