Image Component Library (ICL)
|
00001 /******************************************************************** 00002 ** Image Component Library (ICL) ** 00003 ** ** 00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** 00005 ** Neuroinformatics Group ** 00006 ** Website: www.iclcv.org and ** 00007 ** http://opensource.cit-ec.de/projects/icl ** 00008 ** ** 00009 ** File : ICLMath/src/ICLMath/MatrixSubRectIterator.h ** 00010 ** Module : ICLMath ** 00011 ** Authors: Christof Elbrechter ** 00012 ** ** 00013 ** ** 00014 ** GNU LESSER GENERAL PUBLIC LICENSE ** 00015 ** This file may be used under the terms of the GNU Lesser General ** 00016 ** Public License version 3.0 as published by the ** 00017 ** ** 00018 ** Free Software Foundation and appearing in the file LICENSE.LGPL ** 00019 ** included in the packaging of this file. Please review the ** 00020 ** following information to ensure the license requirements will ** 00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** 00022 ** ** 00023 ** The development of this software was supported by the ** 00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** 00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** 00026 ** Forschungsgemeinschaft (DFG) in the context of the German ** 00027 ** Excellence Initiative. ** 00028 ** ** 00029 ********************************************************************/ 00030 00031 #pragma once 00032 00033 #include <ICLUtils/CompatMacros.h> 00034 #include <iterator> 00035 00036 namespace icl{ 00037 namespace math{ 00039 00069 template <typename Type> 00070 class MatrixSubRectIterator : public std::iterator<std::forward_iterator_tag, Type>{ 00071 protected: 00072 inline void init () { 00073 m_lineStep = m_matrixWidth - m_subRectWidth + 1; 00074 m_dataEnd = m_dataCurr; 00075 if (m_subRectWidth > 0){ 00076 m_dataEnd += m_subRectWidth + (m_subRectHeight-1) * m_matrixWidth; 00077 } 00078 m_currLineEnd = m_dataCurr + m_subRectWidth - 1; 00079 } 00080 00081 public: 00082 00083 static inline const MatrixSubRectIterator<Type> create_end_iterator(const Type *dataOrigin, int matrixWidth, int subRectX, 00084 int subRectY, int subRectWidth, int subRectHeight){ 00085 MatrixSubRectIterator<Type> i(const_cast<Type*>(dataOrigin),matrixWidth,subRectX, subRectY, subRectWidth,subRectHeight); 00086 i.m_dataCurr = i.m_dataEnd - subRectWidth + matrixWidth; 00087 i.m_currLineEnd = i.m_dataCurr + subRectWidth; 00088 return i; 00089 } 00090 00092 00093 inline MatrixSubRectIterator(): 00094 m_matrixWidth(0),m_subRectWidth(0),m_subRectHeight(0), 00095 m_dataOrigin(0), m_dataCurr(0) {init();} 00096 00105 inline MatrixSubRectIterator(Type *ptData,int matrixWidth,int subRectX, int subRectY, int subRectWidth, int subRectHeight): 00106 m_matrixWidth(matrixWidth),m_subRectWidth(subRectWidth),m_subRectHeight(subRectHeight), 00107 m_dataOrigin(ptData),m_dataCurr(ptData+subRectX+subRectY*matrixWidth) {init();} 00108 00109 inline MatrixSubRectIterator &operator=(const MatrixSubRectIterator &other){ 00110 m_matrixWidth = other.m_matrixWidth; 00111 m_subRectWidth = other.m_subRectWidth; 00112 m_subRectHeight = other.m_subRectHeight; 00113 m_lineStep = other.m_lineStep; 00114 m_dataOrigin = other.m_dataOrigin; 00115 m_dataCurr = other.m_dataCurr; 00116 m_dataEnd = other.m_dataEnd; 00117 m_currLineEnd = other.m_currLineEnd; 00118 return *this; 00119 } 00120 00121 inline const MatrixSubRectIterator& operator=(const MatrixSubRectIterator &other) const{ 00122 return (*const_cast<MatrixSubRectIterator*>(this)) = other; 00123 } 00124 00126 00129 inline const Type &operator*() const { return *m_dataCurr; } 00130 00132 00135 inline Type &operator*(){ return *m_dataCurr; } 00136 00138 00164 inline MatrixSubRectIterator& operator++(){ 00165 if ( ICL_UNLIKELY(m_dataCurr == m_currLineEnd) ){ 00166 m_dataCurr += m_lineStep; 00167 m_currLineEnd += m_matrixWidth; 00168 }else{ 00169 m_dataCurr++; 00170 } 00171 return *this; 00172 } 00173 00175 inline const MatrixSubRectIterator& operator++() const{ 00176 return ++(*const_cast<MatrixSubRectIterator*>(this)); 00177 } 00178 00184 inline MatrixSubRectIterator operator++(int){ 00185 MatrixSubRectIterator current (*this); 00186 ++(*this); // call prefix operator 00187 return current; // return previous 00188 } 00189 00191 inline const MatrixSubRectIterator operator++(int) const{ 00192 return (*const_cast<MatrixSubRectIterator*>(this))++; 00193 } 00194 00195 00197 00201 inline bool inSubRect() const{ 00202 return m_dataCurr < m_dataEnd; 00203 } 00204 00205 00206 00208 inline bool operator!=(const MatrixSubRectIterator<Type> &it) const{ 00209 return m_dataCurr != it.m_dataCurr; 00210 } 00212 inline bool operator==(const MatrixSubRectIterator<Type> &it) const{ 00213 return m_dataCurr == it.m_dataCurr; 00214 } 00216 inline bool operator<(const MatrixSubRectIterator<Type> &it) const{ 00217 return m_dataCurr < it.m_dataCurr; 00218 } 00220 inline bool operator>(const MatrixSubRectIterator<Type> &it) const{ 00221 return m_dataCurr > it.m_dataCurr; 00222 } 00224 inline bool operator<=(const MatrixSubRectIterator<Type> &it) const{ 00225 return m_dataCurr <= it.m_dataCurr; 00226 } 00228 inline bool operator>=(const MatrixSubRectIterator<Type> &it) const{ 00229 return m_dataCurr >= it.m_dataCurr; 00230 } 00231 00232 00234 00236 inline int getSubRectWidth() const{ 00237 return m_subRectWidth; 00238 } 00239 00240 inline int getSubRectHeight() const{ 00241 return m_subRectHeight; 00242 } 00243 00245 00249 inline void incRow(int numLines=1) const { 00250 m_dataCurr += numLines * m_matrixWidth; 00251 m_currLineEnd += numLines * m_matrixWidth; 00252 } 00253 00255 00256 inline int x(){ 00257 return (m_dataCurr-m_dataOrigin) % m_matrixWidth; 00258 } 00259 00261 00262 inline int y(){ 00263 return (m_dataCurr-m_dataOrigin) / m_matrixWidth; 00264 } 00265 00266 protected: 00268 int m_matrixWidth; 00269 00271 int m_subRectWidth, m_subRectHeight; 00272 00274 int m_lineStep; 00275 00277 Type *m_dataOrigin; 00278 00280 mutable Type *m_dataCurr; 00281 00283 Type *m_dataEnd; 00284 00286 mutable Type *m_currLineEnd; 00287 00288 }; 00289 } // namespace math 00290 }