ITK  4.0.0
Insight Segmentation and Registration Toolkit
itkIndex.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 __itkIndex_h
00019 #define __itkIndex_h
00020 
00021 #include "itkOffset.h"
00022 #include "itkFixedArray.h"
00023 #include "itkMath.h"
00024 
00025 #include <memory>
00026 
00027 
00028 namespace itk
00029 {
00030 namespace Functor
00031 {
00032 template< unsigned int VIndexDimension >
00033 class IndexLexicographicCompare;
00034 }
00035 
00071 template< unsigned int VIndexDimension = 2 >
00072 class Index
00073 {
00074 public:
00076   typedef Index Self;
00077 
00079   typedef   Index< VIndexDimension > IndexType;
00080   typedef   ::itk::IndexValueType    IndexValueType;
00081 
00083   itkStaticConstMacro(Dimension, unsigned int, VIndexDimension);
00084 
00086   static unsigned int GetIndexDimension() { return VIndexDimension; }
00087 
00089   typedef   Size< VIndexDimension > SizeType;
00090 
00092   typedef   Offset< VIndexDimension >            OffsetType;
00093   typedef   ::itk::OffsetValueType               OffsetValueType;
00094 
00096   typedef Functor::IndexLexicographicCompare< VIndexDimension > LexicographicCompare;
00097 
00099   const Self
00100   operator+(const SizeType & size) const
00101   {
00102     Self result;
00103 
00104     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00105                 { result[i] = m_Index[i] + static_cast< IndexValueType >( size[i] ); }
00106     return result;
00107   }
00108 
00110   const Self &
00111   operator+=(const SizeType & size)
00112   {
00113     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00114                 { m_Index[i] += static_cast< IndexValueType >( size[i] ); }
00115     return *this;
00116   }
00118 
00121   const Self
00122   operator-(const SizeType & size) const
00123   {
00124     Self result;
00125 
00126     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00127                 { result[i] = m_Index[i] - static_cast< IndexValueType >( size[i] ); }
00128     return result;
00129   }
00130 
00132   const Self &
00133   operator-=(const SizeType & size)
00134   {
00135     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00136                 { m_Index[i] -= static_cast< IndexValueType >( size[i] ); }
00137     return *this;
00138   }
00140 
00142   const Self
00143   operator+(const OffsetType & offset) const
00144   {
00145     Self result;
00146 
00147     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00148                 { result[i] = m_Index[i] + offset[i]; }
00149     return result;
00150   }
00151 
00153   const Self &
00154   operator+=(const OffsetType & offset)
00155   {
00156     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00157                 { m_Index[i] += offset[i]; }
00158     return *this;
00159   }
00161 
00163   const Self &
00164   operator-=(const OffsetType & offset)
00165   {
00166     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00167                 { m_Index[i] -= offset[i]; }
00168     return *this;
00169   }
00171 
00173   const Self
00174   operator-(const OffsetType & off) const
00175   {
00176     Self result;
00177 
00178     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00179                 { result[i] = m_Index[i] - off.m_Offset[i]; }
00180     return result;
00181   }
00182 
00184   const OffsetType
00185   operator-(const Self & vec) const
00186   {
00187     OffsetType result;
00188 
00189     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00190                 { result[i] = m_Index[i] - vec.m_Index[i]; }
00191     return result;
00192   }
00193 
00196   const Self
00197   operator*(const SizeType & vec) const
00198   {
00199     Self result;
00200 
00201     for ( unsigned int i = 0; i < VIndexDimension; i++ )
00202                 { result[i] = m_Index[i] * static_cast< IndexValueType >( vec.m_Size[i] ); }
00203     return result;
00204   }
00205 
00207   bool
00208   operator==(const Self & vec) const
00209   {
00210     bool same = true;
00211 
00212     for ( unsigned int i = 0; i < VIndexDimension && same; i++ )
00213                 { same = ( m_Index[i] == vec.m_Index[i] ); }
00214     return same;
00215   }
00216 
00218   bool
00219   operator!=(const Self & vec) const
00220   {
00221     bool same = true;
00222 
00223     for ( unsigned int i = 0; i < VIndexDimension && same; i++ )
00224                 { same = ( m_Index[i] == vec.m_Index[i] ); }
00225     return !same;
00226   }
00227 
00230   IndexValueType & operator[](unsigned int dim)
00231   { return m_Index[dim]; }
00232 
00236   IndexValueType operator[](unsigned int dim) const
00237   { return m_Index[dim]; }
00238 
00241   const IndexValueType * GetIndex() const { return m_Index; }
00242 
00247   void SetIndex(const IndexValueType val[VIndexDimension])
00248   { memcpy(m_Index, val, sizeof( IndexValueType ) * VIndexDimension); }
00249 
00256   void SetElement(unsigned long element, IndexValueType val)
00257   { m_Index[element] = val;  }
00258 
00265   IndexValueType GetElement(unsigned long element) const
00266   { return m_Index[element]; }
00267 
00271   static Self GetBasisIndex(unsigned int dim);
00272 
00275   void Fill(IndexValueType value)
00276   { for ( unsigned int i = 0; i < VIndexDimension; ++i ) { m_Index[i] = value; } }
00277 
00283   IndexValueType m_Index[VIndexDimension];
00284 
00286   template< class TCoordRep >
00287   inline void CopyWithRound(const FixedArray< TCoordRep, VIndexDimension > & point)
00288   {
00289     itkForLoopRoundingAndAssignmentMacro(IndexType,
00290                                          ContinuousIndexType,
00291                                          IndexValueType,
00292                                          m_Index,
00293                                          point,
00294                                          VIndexDimension);
00295     /* NON TEMPLATE_META_PROGRAMMING_LOOP_UNROLLING data version
00296      * Leaving here for documentation purposes
00297      * for ( unsigned int i = 0; i < VIndexDimension; ++i )
00298      *   {
00299      *   m_Index[i] = Math::Round< IndexValueType >(point[i]);
00300      *   }
00301      */
00302   }
00304 
00306   template< class TCoordRep >
00307   inline void CopyWithCast(const FixedArray< TCoordRep, VIndexDimension > & point)
00308   {
00309     for ( unsigned int i = 0; i < VIndexDimension; ++i )
00310       {
00311       m_Index[i] = static_cast< IndexValueType >( point[i] );
00312       }
00313   }
00315 
00316 // force gccxml to find the constructors found before the internal upgrade to
00317 // gcc 4.2
00318 #if defined( CABLE_CONFIGURATION )
00319   Index();                      //purposely not implemented
00320   Index(const Self &);          //purposely not implemented
00321   void operator=(const Self &); //purposely not implemented
00322 
00323 #endif
00324 };
00325 
00326 namespace Functor
00327 {
00336 template< unsigned int VIndexDimension >
00337 class IndexLexicographicCompare
00338 {
00339 public:
00340   bool operator()(Index< VIndexDimension > const & l,
00341                   Index< VIndexDimension > const & r) const
00342   {
00343     for ( unsigned int i = 0; i < VIndexDimension; ++i )
00344       {
00345       if ( l.m_Index[i] < r.m_Index[i] )
00346         {
00347         return true;
00348         }
00349       else if ( l.m_Index[i] > r.m_Index[i] )
00350         {
00351         return false;
00352         }
00353       }
00354     return false;
00355   }
00356 };
00357 }
00358 
00359 template< unsigned int VIndexDimension >
00360 Index< VIndexDimension >
00361 Index< VIndexDimension >
00362 ::GetBasisIndex(unsigned int dim)
00363 {
00364   Self ind;
00365 
00366   memset(ind.m_Index, 0, sizeof( IndexValueType ) * VIndexDimension);
00367   ind.m_Index[dim] = 1;
00368   return ind;
00369 }
00370 
00371 template< unsigned int VIndexDimension >
00372 std::ostream & operator<<(std::ostream & os, const Index< VIndexDimension > & ind)
00373 {
00374   os << "[";
00375   for ( unsigned int i = 0; i + 1 < VIndexDimension; ++i )
00376     {
00377     os << ind[i] << ", ";
00378     }
00379   if ( VIndexDimension >= 1 )
00380     {
00381     os << ind[VIndexDimension - 1];
00382     }
00383   os << "]";
00384   return os;
00385 }
00386 } // end namespace itk
00387 
00388 #endif
00389