Follow this link to skip to the main content

2d_array_iterator.h

Go to the documentation of this file.
00001 // -*-c++-*-
00002 //----------------------------< /-/ CLARAty /-/ >------------------------------
00003 /**
00004  * @file  2d_array_iterator.h
00005  *
00006  * This header provides iterator and const_iterator classes for the
00007  * Array_2D hierarchy. These classes have to exist to support
00008  * subarrays. They're heavier than simply using pointers, but allow
00009  * one to use Array_2D's without caring whether or not the underlying
00010  * memory is contiguous (i.e. without worrying about subarrays).
00011  *
00012  * The constructors are private; these can only be built by Array_2D's
00013  * themselves (and copied from other iterators) -- this is so that we
00014  * can change the implementation without messing everyone up.
00015  *
00016  * <br>@b Designer(s):  Clay Kunz
00017  * <br>@b Author(s):    Clay Kunz
00018  * <br>@b Date:         January 9, 2002
00019  *
00020  * <b>Software License:</b><br>
00021  * <code> http://claraty.jpl.nasa.gov/license/open_src/  or 
00022  *        file: license/open_src.txt </code>
00023  *
00024  * &copy; 2006, Jet Propulsion Laboratory, California Institute of Technology<br>
00025  * &copy; 2006, NASA Ames Research Center
00026  *
00027  * $Revision: 1.4 $
00028  */
00029 //-----------------------------------------------------------------------------
00030 
00031 #ifndef N_2D_ARRAY_ITERATOR_H
00032 #define N_2D_ARRAY_ITERATOR_H
00033 
00034 #include "claraty/share.h"
00035 
00036 #include <stddef.h>
00037 #include <iterator>
00038 
00039 namespace claraty {
00040 
00041 template <class T> class N_2D_Array;
00042 template <class T> class N_2D_Array_const_Iterator;
00043 
00044 // Question: operator==. Should it check just the pointer, or should it check
00045 // everything? Is it enough to point to the same thing, or should it also
00046 // point to the same kind of subarray?
00047 
00048 // Also: these iterators are currently bidirectional, but not
00049 // random-access. To support random access operations, these operators need to
00050 // be added: [], +(int), -(int), and -(iterator) for returning the distance
00051 // between two pointers.
00052 
00053 template <class T>
00054 class N_2D_Array_Iterator {
00055 
00056   T *ptr;
00057   int offset;
00058   const int width, stride;
00059   const bool fromSubarray;
00060 
00061   friend class N_2D_Array<T>;
00062   friend class N_2D_Array_const_Iterator<T>;
00063 
00064   N_2D_Array_Iterator(T *pt, bool sub = false, int w = 0, int s = 0)
00065     : ptr(pt), offset(0), width(w), stride(s), fromSubarray(sub) { }
00066 
00067 public:
00068 
00069   typedef std::bidirectional_iterator_tag iterator_category; // needs STL
00070   typedef T value_type;
00071   typedef ptrdiff_t difference_type;
00072   typedef T* pointer;
00073   typedef T& reference;
00074 
00075   // default operator= and copy ctors are what we want.
00076 
00077   // dereferencing
00078   T& operator*() { return *ptr; }
00079   T *operator->() { return ptr; }
00080 
00081   const T& operator*() const { return *ptr; }
00082   const T *operator->() const { return ptr; }
00083 
00084   bool operator==(const N_2D_Array_Iterator<T>& rhs) const {
00085     return ptr == rhs.ptr;
00086   }
00087   bool operator!=(const N_2D_Array_Iterator<T>& rhs) const {
00088     return !(*this == rhs);
00089   }
00090 
00091   // pointer arithmetic
00092   N_2D_Array_Iterator<T>& operator++() {    // prefix
00093     ++ptr;
00094     if (fromSubarray && ++offset == width) {
00095       ptr = ptr - width + stride;
00096       offset = 0;
00097     }
00098     return *this;
00099   }
00100   N_2D_Array_Iterator<T> operator++(int) {  // postfix
00101     N_2D_Array_Iterator<T> tmp = *this;
00102     ++*this;
00103     return tmp;
00104   }
00105 
00106   N_2D_Array_Iterator<T>& operator--() {    // prefix
00107     --ptr;
00108     if (fromSubarray && --offset == -1) {
00109       ptr = ptr + width - stride;
00110       offset = 0;
00111     }
00112     return *this;
00113   }
00114   N_2D_Array_Iterator<T> operator--(int) {  // postfix
00115     N_2D_Array_Iterator<T> tmp = *this;
00116     --*this;
00117     return tmp;
00118   }
00119 };
00120 
00121 template <class T>
00122 class N_2D_Array_const_Iterator {
00123 
00124   const T *ptr;
00125   int offset;
00126   const int width, stride;
00127   const bool fromSubarray;
00128 
00129   friend class N_2D_Array<T>;
00130 
00131   N_2D_Array_const_Iterator(const T *pt, bool sub = false, int w = 0, int s = 0)
00132     : ptr(pt), offset(0), width(w), stride(s), fromSubarray(sub) { }
00133 
00134 public:
00135 
00136   typedef std::bidirectional_iterator_tag iterator_category; // needs STL
00137   typedef T value_type;
00138   typedef ptrdiff_t difference_type;
00139   typedef const T* pointer;
00140   typedef const T& reference;
00141 
00142   // default operator= and copy ctors are what we want.
00143 
00144   // one more constructor for making a const iterator from a non-const one
00145   N_2D_Array_const_Iterator(const N_2D_Array_Iterator<T>& rhs)
00146     : ptr(rhs.ptr), offset(rhs.offset), width(rhs.width), stride(rhs.stride),
00147       fromSubarray(rhs.fromSubarray)
00148   {
00149   }
00150 
00151   // dereferencing
00152   const T& operator*() const { return *ptr; }
00153   const T *operator->() const { return ptr; }
00154 
00155   bool operator==(const N_2D_Array_const_Iterator<T>& rhs) const {
00156     return ptr == rhs.ptr;
00157   }
00158   bool operator!=(const N_2D_Array_const_Iterator<T>& rhs) const {
00159     return !(*this == rhs);
00160   }
00161 
00162   // pointer arithmetic
00163   N_2D_Array_const_Iterator<T>& operator++() {    // prefix
00164     ++ptr;
00165     if (fromSubarray && ++offset == width) {
00166       ptr = ptr - width + stride;
00167       offset = 0;
00168     }
00169     return *this;
00170   }
00171   N_2D_Array_const_Iterator<T> operator++(int) {  // postfix
00172     N_2D_Array_const_Iterator<T> tmp = *this;
00173     ++*this;
00174     return tmp;
00175   }
00176 
00177   N_2D_Array_const_Iterator<T>& operator--() {    // prefix
00178     --ptr;
00179     if (fromSubarray && --offset == -1) {
00180       ptr = ptr + width - stride;
00181       offset = 0;
00182     }
00183     return *this;
00184   }
00185   N_2D_Array_const_Iterator<T> operator--(int) {  // postfix
00186     N_2D_Array_const_Iterator<T> tmp = *this;
00187     --*this;
00188     return tmp;
00189   }
00190 };
00191 
00192 } // namespace claraty
00193 
00194 #endif // N_2D_ARRAY_ITERATOR_H