KWStyle - itkVariableLengthVector.h
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkVariableLengthVector.h.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:49 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12      This software is distributed WITHOUT ANY WARRANTY; without even 
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14      PURPOSE.  See the above copyright notices for more information.
15
16 =========================================================================*/
17 #ifndef __itkVariableLengthVector_h
18 #define __itkVariableLengthVector_h
19
20 #include "itkMacro.h"
21
22 namespace itk
23 {
24 /** \class VariableLengthVector 
25  * \brief VariableLengthVector is intended to reperesent an array whose
26  * length can be defined at run-time. 
27  *
28  * This class is templated over the data type. This data-type is meant
29  * to a scalar, such as float, double etc...
30  *
31  * \note
32  * ITK itself provides several classes that can serve as \c Arrays.
33  * 1. FixedArray - Compile time fixed length arrays that's intended to 
34  * represent an enumerated collection of \c n entities. 
35  * 2. Array - Run time resizeable array that is intended to hold a collection
36  * of \c n entities
37  * 3. Vector - Compile time fixed length array that is intended to hold
38 LEN  * a collection of \c n data types. A vector usually has a mathematical meaning. 
39  * It should only be used when mathematical operations such as addition, 
40  * multiplication by a scalar, product etc make sense. 
41 LEN  * 4. VariableLengthVector - Run time array that is intended to hold a collection
42  * of scalar data types. Again, it should be used only when mathematical
43  * operations on it are relevant. If not, use an Array. 
44 LEN  * 5. Point - Represents the spatial coordinates of a spatial location. Operators
45  * on Point reflect geometrical concepts.
46  *
47  * \par For the reasons listed above, you cannot instantiate 
48  * \code VariableLengthVector< bool > \endcode.
49  *
50  * \par
51  * Design Considerations: We do not derive from \c vnl_vector to avoid being
52  * limited by the explicit template instantiations of vnl_vector and other 
53  * hacks that vnl folks have been forced to use.
54  * 
55  * \note
56  * This work is part of the National Alliance for Medical Image Computing 
57  * (NAMIC), funded by the National Institutes of Health through the NIH Roadmap
58  * for Medical Research, Grant U54 EB005149.
59  *
60  * \sa CovariantVector
61  * \sa SymmetricSecondRankTensor
62  * \sa RGBPixel
63  * \sa DiffusionTensor3D
64  * \ingroup DataRepresentation 
65  */
66 template <typename TValueType >
67 class VariableLengthVector
68 {
69 public:
70  
71   /** The element type stored at each location in the Array. */
72   typedef TValueType           ValueType;
73   typedef TValueType           ComponentType;
74   typedef VariableLengthVector Self;
75
76   /** Typedef used to indicate the number of elements in the vector */
77   typedef unsigned int ElementIdentifier;
78   
79   /** Default constructor. It is created with an empty array
80    *  it has to be allocated later by assignment              */
81   VariableLengthVector(); 
82
83   /** Constructor with size. Size can only be changed by assignment */
84   VariableLengthVector(unsigned int dimension);
85
86   /** Constructor that initializes array with contents from a user supplied
87    * buffer. The pointer to the buffer and the length is specified. By default,
88    * the array does not manage the memory of the buffer. It merely points to 
89    * that location and it is the user's responsibility to delete it. 
90    * If "LetArrayManageMemory" is true, then this class will free the
91    * memory when this object is destroyed. */ 
92   VariableLengthVector( ValueType* data, unsigned int sz, 
93                                         bool LetArrayManageMemory = false);
94   
95   /** Constructor that initializes array with contents from a user supplied
96    * buffer. The pointer to the buffer and the length is specified. By default,
97    * the array does not manage the memory of the buffer. It merely points to 
98    * that location and it is the user's responsibility to delete it. 
99    * If "LetArrayManageMemory" is true, then this class will free the
100    * memory when this object is destroyed. */ 
101   VariableLengthVector( const ValueType* data, unsigned int sz, 
102                                         bool LetArrayManageMemory = false);
103
104
105   /** Copy constructor. The reason why the copy constructor and the assignment
106    * operator are templated is that it will allow implicit casts to be 
107    * performed. For instance
108    * \code
109    * VariableLengthVector< int > vI;
110    * VariableLengthVector< float > vF( vI );
111    * or for instance vF = static_cast< VariableLengthVector< float > >( vI );
112    * \endcode
113    **/
114   template< class T >
115   VariableLengthVector(const VariableLengthVector< T > & v)
116     {
117     m_NumElements = v.Size();
118     m_Data = this->AllocateElements(m_NumElements);
119     m_LetArrayManageMemory = true;
120     for( ElementIdentifier i=0; i< v.Size(); i++ )
121       {
122       this->m_Data[i] = static_cast< ValueType >( v[i] );
123       }
124     }
125
126   /** Copy constructer.. Override the default non-templated copy constructor
127    * that the compiler provides */
128   VariableLengthVector(const VariableLengthVector< TValueType > & v);
129   
130   /** Set the all the elements of the array to the specified value */
131   void Fill (TValueType const& v); 
132
133   /** Assignment operator  **/
134   template< class T >
135   const VariableLengthVector< TValueType > & operator= 
136 IND **************************(const VariableLengthVector< T > & v)
137     {
138     if( m_Data == static_cast< void * >(const_cast< T * >
139 LEN               ((const_cast< VariableLengthVector< T > & >(v)).GetDataPointer())) )
140       {
141       return *this;
142       }
143     this->SetSize( v.Size() );
144     for( ElementIdentifier i=0; i< v.Size(); i++ )
145       {
146       this->m_Data[i] = static_cast< ValueType >( v[i] );
147       }
148     return *this;
149     }
150   
151   /** Assignment operator  **/
152   const Self & operator=(const Self & v);
153      
154   /** Return the number of elements in the Array  */
155   inline unsigned int Size (void ) const 
156 IND ******{ return m_NumElements; }
157   inline unsigned int GetNumberOfElements(void) const 
158 IND ******{ return m_NumElements; }
159
160   /** Return reference to the element at specified index. No range checking. */
161   TValueType       & operator[](unsigned int i) { return this->m_Data[i]; }
162   /** Return reference to the element at specified index. No range checking. */
163 LEN   TValueType const & operator[](unsigned int i) const { return this->m_Data[i]; }
164
165   /** Get one element */
166   inline const TValueType & GetElement( unsigned int i ) const
167     { return m_Data[i]; }
168
169   /** Set one element */
170   void SetElement( unsigned int i, const TValueType & value )
171     { m_Data[i] = value; }
172
173   /** Set the size to that given. 
174    * 
175    * If \c destroyExistingData is \c false:
176    * If the array already contains data, the existing data is copied over and 
177    * new space is allocated, if necessary. If the length to reserve is less 
178    * than the current number of elements, then an appropriate number of elements
179    * are discarded. 
180    *    If \c true, the size is set destructively to the length given. If the 
181    * length is different from the current length, existing data will be lost.
182    * The default is \c true. */
183   void SetSize(unsigned int sz, bool destroyExistingData=true);
184   inline unsigned int GetSize(void) const 
185 IND ******{ return m_NumElements; }
186
187   /** Set the pointer from which the data is imported.
188    * If "LetArrayManageMemory" is false, then the application retains
189    * the responsibility of freeing the memory for this data.  If
190    * "LetArrayManageMemory" is true, then this class will free the
191    * memory when this object is destroyed. */
192   void SetData(TValueType* data,bool LetArrayManageMemory = false);
193
194   /** Similar to the previous method. In the above method, the size must be 
195    * seperately set prior to using user-supplied data. This introduces an
196    * unnecessary allocation step to be performed. This method avoids it 
197    * and should be used to import data whereever possible to avoid this.
198    * Set the pointer from which the data is imported.
199    * If "LetArrayManageMemory" is false, then the application retains
200    * the responsibility of freeing the memory for this data.  If
201    * "LetArrayManageMemory" is true, then this class will free the
202    * memory when this object is destroyed. */
203 LEN   void SetData(TValueType* data, unsigned int sz, bool LetArrayManageMemory = false);
204
205   
206   /** This destructor is not virtual for performance reasons. However, this
207    * means that subclasses cannot allocate memory. */
208   ~VariableLengthVector();
209
210
211   /** Reserves memory of a certain length. 
212    *
213    * If the array already contains data, the existing data is copied over and 
214    * new space is allocated, if necessary. If the length to reserve is less 
215    * than the current number of elements, then an appropriate number of elements
216    * are discarded. */
217   void Reserve( ElementIdentifier );
218
219   /** Allocate memory of certain size and return it.  */
220   TValueType * AllocateElements( ElementIdentifier size ) const;
221
222   const TValueType* GetDataPointer() { return m_Data; }
223
224   /** Mathematical operators.
225    * \note For efficiency, the operators do not check to see of the length of 
226    * the vectors are the same. For instance it is assumed that if you are adding
227    * VariableLengthVector a and b, they are of the same length. */
228   template< class T > 
229   inline Self operator+(const VariableLengthVector< T > &v) const
230     {
231     // if( m_NumElements != v.GetSize() ) 
232     //   { 
233 LEN,IND ****//   itkGenericExceptionMacro( << "Cannot add VariableLengthVector of length " 
234     //                             << m_NumElements " and " << v.GetSize() );
235     //   }      
236     const ElementIdentifier length = v.Size();
237     Self result( length );
238     for( ElementIdentifier i=0; i< length; i++ )
239       {
240       result[i] = (*this)[i] + static_cast< ValueType >( v[i] );
241       }
242     return result;
243     }
244   template< class T > 
245   inline Self operator-(const VariableLengthVector< T > &v) const
246     {
247     // if( m_NumElements != v.GetSize() ) 
248     //   { 
249 LEN,IND ****//   itkGenericExceptionMacro( << "Cannot add VariableLengthVector of length " 
250     //                             << m_NumElements " and " << v.GetSize() );
251     //   }      
252     const ElementIdentifier length = v.Size();
253     Self result( length );
254     for( ElementIdentifier i=0; i< length; i++ )
255       {
256       result[i] = (*this)[i] - static_cast< ValueType >( v[i] );
257       }
258     return result;
259     }
260   template< class T > inline Self operator*( T s ) const
261     {
262     Self result( m_NumElements );
263     for( ElementIdentifier i=0; i< m_NumElements; i++ )
264       {
265       result[i] = m_Data[i] * static_cast< ValueType >( s );
266       }
267     return result;
268     }
269   template< class T > inline Self operator/( T s ) const
270     {
271     Self result( m_NumElements );
272     for( ElementIdentifier i=0; i< m_NumElements; i++ )
273       {
274       result[i] = m_Data[i] / (static_cast< ValueType >( s ));
275       }
276     return result;
277     }
278   inline Self operator+( TValueType s ) const
279     {
280     Self result( m_NumElements );
281     for( ElementIdentifier i=0; i< m_NumElements; i++ )
282       {
283       result[i] = m_Data[i] + s;
284       }
285     return result;
286     }
287   inline Self operator-( TValueType s ) const
288     {
289     Self result( m_NumElements );
290     for( ElementIdentifier i=0; i< m_NumElements; i++ )
291       {
292       result[i] = m_Data[i] - s;
293       }
294     return result;
295     }
296   inline Self& operator--()
297     {
298     for( ElementIdentifier i=0; i< m_NumElements; i++ )
299       {
300       this->m_Data[i] -= static_cast< ValueType >( 1.0 );
301       }
302     return *this;
303     }
304   inline Self& operator++() // prefix operator ++v;
305     {
306     for( ElementIdentifier i=0; i< m_NumElements; i++ )
307       {
308       this->m_Data[i] += static_cast< ValueType >( 1.0 );
309       }
310     return *this;
311     }
312   inline Self& operator--(int)
313     {
314     for( ElementIdentifier i=0; i< m_NumElements; i++ )
315       {
316       this->m_Data[i] -= static_cast< ValueType >( 1.0 );
317       }
318     return *this;
319     }
320   inline Self& operator++(int) // postfix operator v++;
321     {
322     for( ElementIdentifier i=0; i< m_NumElements; i++ )
323       {
324       this->m_Data[i] += static_cast< ValueType >( 1.0 );
325       }
326     return *this;
327     }
328 IND ***template< class T > inline Self& operator-=
329 IND ******************( const VariableLengthVector< T > &v )
330     {
331     for( ElementIdentifier i=0; i< m_NumElements; i++ )
332       {
333       m_Data[i] -= static_cast< ValueType >( v[i] );
334       }
335     return *this;
336     }
337   inline Self& operator-=( TValueType s )
338     {
339     for( ElementIdentifier i=0; i< m_NumElements; i++ )
340       {
341 SEM       m_Data[i] -= s ;
342       }
343     return *this;
344     }
345   template< class T > inline Self& operator+=
346 IND ******************( const VariableLengthVector< T > &v )
347     {
348     for( ElementIdentifier i=0; i< m_NumElements; i++ )
349       {
350       m_Data[i] += static_cast< ValueType >( v[i] );
351       }
352     return *this;
353     }
354   inline Self& operator+=( TValueType s )
355     {
356     for( ElementIdentifier i=0; i< m_NumElements; i++ )
357       {
358       m_Data[i] += s;
359       }
360     return *this;
361     }
362   template< class T > inline Self& operator*=( T s )
363     {
364     for( ElementIdentifier i=0; i< m_NumElements; i++ )
365       {
366       m_Data[i] *= (static_cast< ValueType >( s ));
367       }
368     return *this;
369     }
370   template< class T > inline Self& operator/=( T s )
371     {
372     for( ElementIdentifier i=0; i< m_NumElements; i++ )
373       {
374       m_Data[i] /= (static_cast< ValueType >( s ));
375       }
376     return *this;
377     }
378   Self & operator- (); // negation operator
379   bool operator==( const Self &v) const;
380   bool operator!=( const Self &v) const;
381     
382
383
384 private:
385
386   bool m_LetArrayManageMemory; // if true, the array is responsible for memory 
387 IND *******************************// of data
388   TValueType *m_Data; // Array to hold data
389   ElementIdentifier m_NumElements;
390 };
391
392
393   
394 template <typename TValueType >
395 LEN std::ostream & operator<<(std::ostream &os, const VariableLengthVector<TValueType> &arr)
396 {
397   const unsigned int length = arr.Size();
398   const signed int last   = (unsigned int) length - 1;
399
400   os << "[";
401   for (signed int i=0; i < last; ++i)
402     {
403     os << arr[i] << ", ";
404     }
405   if (length >= 1)
406     {
407     os << arr[last];
408     }
409   os << "]";
410   return os;
411 }
412
413 // namespace itk
414
415
416 #ifndef ITK_MANUAL_INSTANTIATION
417 #include "itkVariableLengthVector.txx"
418 #endif
419
420 #endif
421

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:51PM
© Kitware Inc.