ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkVariableLengthVector.h
Go to the documentation of this file.
00001 /*=========================================================================
00002  *
00003  *  Copyright Insight Software Consortium
00004  *
00005  *  Licensed under the Apache License, Version 2.0 (the "License");
00006  *  you may not use this file except in compliance with the License.
00007  *  You may obtain a copy of the License at
00008  *
00009  *         http://www.apache.org/licenses/LICENSE-2.0.txt
00010  *
00011  *  Unless required by applicable law or agreed to in writing, software
00012  *  distributed under the License is distributed on an "AS IS" BASIS,
00013  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  *  See the License for the specific language governing permissions and
00015  *  limitations under the License.
00016  *
00017  *=========================================================================*/
00018 #ifndef __itkVariableLengthVector_h
00019 #define __itkVariableLengthVector_h
00020 
00021 #include "itkNumericTraits.h"
00022 
00023 namespace itk
00024 {
00075 template< typename TValueType >
00076 class VariableLengthVector
00077 {
00078 public:
00079 
00081   typedef TValueType                                    ValueType;
00082   typedef TValueType                                    ComponentType;
00083   typedef typename NumericTraits< ValueType >::RealType RealValueType;
00084   typedef VariableLengthVector                          Self;
00085 
00087   typedef unsigned int ElementIdentifier;
00088 
00091   VariableLengthVector();
00092 
00094   VariableLengthVector(unsigned int dimension);
00095 
00102   VariableLengthVector(ValueType *data, unsigned int sz,
00103                        bool LetArrayManageMemory = false);
00104 
00111   VariableLengthVector(const ValueType *data, unsigned int sz,
00112                        bool LetArrayManageMemory = false);
00113 
00123   template< class T >
00124   VariableLengthVector(const VariableLengthVector< T > & v)
00125   {
00126     m_NumElements = v.Size();
00127     m_Data = this->AllocateElements(m_NumElements);
00128     m_LetArrayManageMemory = true;
00129     for ( ElementIdentifier i = 0; i < v.Size(); i++ )
00130       {
00131       this->m_Data[i] = static_cast< ValueType >( v[i] );
00132       }
00133   }
00135 
00138   VariableLengthVector(const VariableLengthVector< TValueType > & v);
00139 
00141   void Fill(TValueType const & v);
00142 
00144   template< class T >
00145   const VariableLengthVector< TValueType > & operator=
00146     (const VariableLengthVector< T > & v)
00147   {
00148     if ( m_Data == static_cast< void * >( const_cast< T * >
00149                                           ( ( const_cast< VariableLengthVector< T > & >( v ) ).GetDataPointer() ) ) )
00150       {
00151       return *this;
00152       }
00153     this->SetSize( v.Size() );
00154     for ( ElementIdentifier i = 0; i < v.Size(); i++ )
00155       {
00156       this->m_Data[i] = static_cast< ValueType >( v[i] );
00157       }
00158     return *this;
00159   }
00161 
00163   const Self & operator=(const Self & v);
00164 
00165   const Self & operator=(TValueType const & v);
00166 
00168   inline unsigned int Size(void) const { return m_NumElements; }
00169   inline unsigned int GetNumberOfElements(void) const { return m_NumElements; }
00171 
00173   TValueType       & operator[](unsigned int i) { return this->m_Data[i]; }
00174 
00176   TValueType const & operator[](unsigned int i) const { return this->m_Data[i]; }
00177 
00179   inline const TValueType & GetElement(unsigned int i) const { return m_Data[i]; }
00180 
00182   void SetElement(unsigned int i, const TValueType & value) { m_Data[i] = value; }
00183 
00194   void SetSize(unsigned int sz, bool destroyExistingData = true);
00195 
00198   void DestroyExistingData();
00199 
00200   inline unsigned int GetSize(void) const { return m_NumElements; }
00201 
00207   void SetData(TValueType *data, bool LetArrayManageMemory = false);
00208 
00218   void SetData(TValueType *data, unsigned int sz, bool LetArrayManageMemory = false);
00219 
00222   ~VariableLengthVector();
00223 
00230   void Reserve(ElementIdentifier);
00231 
00233   TValueType * AllocateElements(ElementIdentifier size) const;
00234 
00235   const TValueType * GetDataPointer() const { return m_Data; }
00236 
00241   template< class T >
00242   inline Self operator+(const VariableLengthVector< T > & v) const
00243   {
00244     // if( m_NumElements != v.GetSize() )
00245     //   {
00246     //   itkGenericExceptionMacro( << "Cannot add VariableLengthVector of length
00247     // "
00248     //                             << m_NumElements " and " << v.GetSize() );
00249     //   }
00250     const ElementIdentifier length = v.Size();
00251     Self                    result(length);
00253 
00254     for ( ElementIdentifier i = 0; i < length; i++ )
00255       {
00256       result[i] = ( *this )[i] + static_cast< ValueType >( v[i] );
00257       }
00258     return result;
00259   }
00260 
00261   template< class T >
00262   inline Self operator-(const VariableLengthVector< T > & v) const
00263   {
00264     // if( m_NumElements != v.GetSize() )
00265     //   {
00266     //   itkGenericExceptionMacro( << "Cannot add VariableLengthVector of length
00267     // "
00268     //                             << m_NumElements " and " << v.GetSize() );
00269     //   }
00270     const ElementIdentifier length = v.Size();
00271     Self                    result(length);
00272 
00273     for ( ElementIdentifier i = 0; i < length; i++ )
00274       {
00275       result[i] = ( *this )[i] - static_cast< ValueType >( v[i] );
00276       }
00277     return result;
00278   }
00279 
00280   template< class T >
00281   inline Self operator*(T s) const
00282   {
00283     Self result(m_NumElements);
00284 
00285     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00286       {
00287       result[i] = m_Data[i] * static_cast< ValueType >( s );
00288       }
00289     return result;
00290   }
00291 
00292   template< class T >
00293   inline Self operator/(T s) const
00294   {
00295     Self result(m_NumElements);
00296 
00297     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00298       {
00299       result[i] = static_cast< ValueType >(
00300         static_cast< RealValueType >( m_Data[i] )
00301         / static_cast< RealValueType >( s ) );
00302       }
00303     return result;
00304   }
00305 
00306   inline Self operator+(TValueType s) const
00307   {
00308     Self result(m_NumElements);
00309 
00310     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00311       {
00312       result[i] = m_Data[i] + s;
00313       }
00314     return result;
00315   }
00316 
00317   inline Self operator-(TValueType s) const
00318   {
00319     Self result(m_NumElements);
00320 
00321     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00322       {
00323       result[i] = m_Data[i] - s;
00324       }
00325     return result;
00326   }
00327 
00328   inline Self & operator--()
00329   {
00330     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00331       {
00332       this->m_Data[i] -= static_cast< ValueType >( 1.0 );
00333       }
00334     return *this;
00335   }
00336 
00337   inline Self & operator++() // prefix operator ++v;
00338   {
00339     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00340       {
00341       this->m_Data[i] += static_cast< ValueType >( 1.0 );
00342       }
00343     return *this;
00344   }
00345 
00346   inline Self operator--(int) // postfix operator v--;
00347   {
00348     Self tmp(*this);
00349 
00350     --tmp;
00351     return tmp;
00352   }
00353 
00354   inline Self operator++(int) // postfix operator v++;
00355   {
00356     Self tmp(*this);
00357 
00358     ++tmp;
00359     return tmp;
00360   }
00361 
00362   template< class T >
00363   inline Self & operator-=
00364     (const VariableLengthVector< T > & v)
00365   {
00366     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00367       {
00368       m_Data[i] -= static_cast< ValueType >( v[i] );
00369       }
00370     return *this;
00371   }
00372 
00373   inline Self & operator-=(TValueType s)
00374   {
00375     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00376       {
00377       m_Data[i] -= s;
00378       }
00379     return *this;
00380   }
00381 
00382   template< class T >
00383   inline Self & operator+=
00384     (const VariableLengthVector< T > & v)
00385   {
00386     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00387       {
00388       m_Data[i] += static_cast< ValueType >( v[i] );
00389       }
00390     return *this;
00391   }
00392 
00393   inline Self & operator+=(TValueType s)
00394   {
00395     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00396       {
00397       m_Data[i] += s;
00398       }
00399     return *this;
00400   }
00401 
00402   template< class T >
00403   inline Self & operator*=(T s)
00404   {
00405     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00406       {
00407       m_Data[i] *= ( static_cast< ValueType >( s ) );
00408       }
00409     return *this;
00410   }
00411 
00412   template< class T >
00413   inline Self & operator/=(T s)
00414   {
00415     for ( ElementIdentifier i = 0; i < m_NumElements; i++ )
00416       {
00417       m_Data[i] = static_cast< ValueType >(
00418         static_cast< RealValueType >( m_Data[i] )
00419         / static_cast< RealValueType >( s ) );
00420       }
00421     return *this;
00422   }
00423 
00424   Self & operator-();  // negation operator
00425 
00426   bool operator==(const Self & v) const;
00427 
00428   bool operator!=(const Self & v) const;
00429 
00431   RealValueType GetNorm() const;
00432 
00434   RealValueType GetSquaredNorm() const;
00435 
00436 private:
00437 
00438   bool              m_LetArrayManageMemory; // if true, the array is responsible
00439                                             // for memory of data
00440   TValueType *      m_Data;                 // Array to hold data
00441   ElementIdentifier m_NumElements;
00442 };
00443 
00447 template< class TValueType, class T >
00448 inline
00449 VariableLengthVector< TValueType >
00450 operator*(const T & scalar, const VariableLengthVector< TValueType > & v)
00451 {
00452   return v * scalar;
00453 }
00454 
00455 template< typename TValueType >
00456 std::ostream & operator<<(std::ostream & os, const VariableLengthVector< TValueType > & arr)
00457 {
00458   const unsigned int length = arr.Size();
00459   const signed int   last   = (unsigned int)length - 1;
00460 
00461   os << "[";
00462   for ( signed int i = 0; i < last; ++i )
00463     {
00464     os << arr[i] << ", ";
00465     }
00466   if ( length >= 1 )
00467     {
00468     os << arr[last];
00469     }
00470   os << "]";
00471   return os;
00472 }
00473 } // namespace itk
00474 
00475 #include "itkNumericTraitsVariableLengthVectorPixel.h"
00476 
00477 // Define instantiation macro for this template.
00478 #define ITK_TEMPLATE_VariableLengthVector(_, EXPORT, TypeX, TypeY)                    \
00479   namespace itk                                                                       \
00480   {                                                                                   \
00481   _( 1 ( class EXPORT VariableLengthVector< ITK_TEMPLATE_1 TypeX > ) )                \
00482   namespace Templates                                                                 \
00483   {                                                                                   \
00484   typedef VariableLengthVector< ITK_TEMPLATE_1 TypeX > VariableLengthVector##TypeY; \
00485   }                                                                                   \
00486   }
00487 
00488 #if ITK_TEMPLATE_EXPLICIT
00489 #include "Templates/itkVariableLengthVector+-.h"
00490 #endif
00491 
00492 #if ITK_TEMPLATE_TXX
00493 #include "itkVariableLengthVector.hxx"
00494 #endif
00495 
00496 #endif
00497