00001 /*---------------------------------------------------------------------+ 00002 | Library QgarLib, graphics analysis and recognition | 00003 | Copyright (C) 2002 Qgar Project, LORIA | 00004 | | 00005 | This library is free software; you can redistribute it and/or | 00006 | modify it under the terms of the GNU Lesser General Public | 00007 | License version 2.1, as published by the Free Software Foundation. | 00008 | | 00009 | This library is distributed in the hope that it will be useful, | 00010 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00011 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 00012 | See the GNU Lesser General Public License for more details. | 00013 | | 00014 | The GNU Lesser General Public License is included in the file | 00015 | LICENSE.LGPL, in the root directory of the Qgar packaging. See | 00016 | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. | 00017 | To receive a paper copy, write to the Free Software Foundation, | 00018 | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | 00019 | | 00020 | Contact Project Qgar for any information: | 00021 | LORIA - équipe Qgar | 00022 | B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France | 00023 | email: qgar-contact@loria.fr | 00024 | http://www.qgar.org/ | 00025 *---------------------------------------------------------------------*/ 00026 00027 00028 #ifndef __ARRAY_H_INCLUDED__ 00029 #define __ARRAY_H_INCLUDED__ 00030 00031 00032 /** 00033 * @file array.H 00034 * @brief Definitions of global utilities for arrays. 00035 * 00036 * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Gérald Masini">Gérald Masini</a> 00037 * @date December 06 2004 17:28 00038 * @since Qgar 2.2 00039 */ 00040 00041 00042 // For RCS/CVS use: Do not delete 00043 /* $Id: array.H,v 1.5 2005/10/14 17:05:48 masini Exp $ */ 00044 00045 00046 00047 // STL 00048 #include <cstdlib> 00049 #include <sstream> 00050 #include <string> 00051 00052 00053 00054 namespace qgar 00055 { 00056 00057 // ------------------------------------------------------------------- 00058 // I N D E X E S 00059 // ------------------------------------------------------------------- 00060 00061 00062 /** @name Global functions about array indexes */ 00063 // ==================================== 00064 //@{ 00065 00066 /** 00067 * @ingroup GLOB_ARRAY 00068 * 00069 * @brief Return the index of the minimum element of an array. 00070 * 00071 * @param anArray an array 00072 * @param aSize size of the array 00073 * 00074 * @warning 00075 * - Operator '<' must be defined for objects of type <b>T</b> 00076 * - The behavior of the function is undefined in case of wrong size 00077 */ 00078 template <class T> 00079 inline int 00080 qgMinElement(const T* const anArray, int aSize) 00081 { 00082 return qgMinElement(anArray, 0, aSize - 1); 00083 } 00084 00085 00086 /** 00087 * @ingroup GLOB_ARRAY 00088 * 00089 * @brief Return the index of the minimum element 00090 * of a subrange of an array. 00091 * 00092 * The subrange is defined as <b>[aFirstIdx, aLastIdx]</b>. 00093 * 00094 * @param anArray an array 00095 * @param aFirstIdx lower index of the elements to be examined 00096 * @param aLastIdx upper index of the elements to be examined 00097 * 00098 * @warning 00099 * - Operator '<' must be defined on objects of type <b>T</b> 00100 * - The behavior of the function is undefined in case of 00101 * wrong range <b>[aFirstIdx, aLastIdx]</b> 00102 */ 00103 template <class T> 00104 int 00105 qgMinElement(const T* const anArray, int aFirstIdx, int aLastIdx) 00106 { 00107 T min = anArray[aFirstIdx]; 00108 int idxMin = aFirstIdx; 00109 00110 for (int idx = aFirstIdx + 1 ; idx <= aLastIdx ; ++idx) 00111 { 00112 if (anArray[idx] < min) 00113 { 00114 min = anArray[idx]; 00115 idxMin = idx; 00116 } 00117 } 00118 00119 return idxMin; 00120 } 00121 00122 00123 /** 00124 * @ingroup GLOB_ARRAY 00125 * 00126 * @brief Return the index of the maximum element of an array. 00127 * 00128 * @param anArray an array 00129 * @param aSize size of the array 00130 * 00131 * @warning 00132 * - Operator '>' must be defined for objects of type <b>T</b> 00133 * - The behavior of the function is undefined in case of wrong size 00134 */ 00135 template <class T> 00136 int 00137 qgMaxElement(const T* const anArray, int aSize) 00138 { 00139 return qgMaxElement(anArray, 0, aSize - 1); 00140 } 00141 00142 /** 00143 * @ingroup GLOB_ARRAY 00144 * 00145 * @brief Return the index of the maximum element 00146 * of a subrange of an array. 00147 * 00148 * The subrange is defined as <b>[aFirstIdx, aLastIdx]</b>. 00149 * 00150 * @param anArray an array 00151 * @param aFirstIdx lower index of the elements to be examined 00152 * @param aLastIdx upper index of the elements to be examined 00153 * 00154 * @warning 00155 * - Operator '<' must be defined for objects of type <b>T</b> 00156 * - The behavior of the function is undefined in case of 00157 * wrong range <b>[aFirstIdx, aLastIdx]</b> 00158 */ 00159 template <class T> 00160 int 00161 qgMaxElement(const T* const anArray, int aFirstIdx, int aLastIdx) 00162 { 00163 T max = anArray[aFirstIdx]; 00164 int idxMax = aFirstIdx; 00165 00166 for (int idx = aFirstIdx + 1 ; idx <= aLastIdx ; ++idx) 00167 { 00168 if (anArray[idx] > max) 00169 { 00170 max = anArray[idx]; 00171 idxMax = idx; 00172 } 00173 } 00174 00175 return idxMax; 00176 } 00177 00178 00179 /** 00180 * @ingroup GLOB_ARRAY 00181 * 00182 * @brief Return the index of a value in an array. 00183 * 00184 * Return <b>-1</b> if the value is not found in the array. 00185 * 00186 * @param anArray an array 00187 * @param aSize size of the array 00188 * @param aValue a value to be searched in the array 00189 * 00190 * @warning 00191 * - Operator '=' must be defined for objects of type <b>T</b> 00192 * - The behavior of the function is undefined in case of wrong size 00193 */ 00194 template <class T> 00195 int 00196 qgFind(const T* const anArray, int aSize, T aValue) 00197 { 00198 return qgFind(anArray, 0, aSize - 1, aValue); 00199 } 00200 00201 /** 00202 * @ingroup GLOB_ARRAY 00203 * 00204 * @brief Return the index of a value in a subrange of an array. 00205 * 00206 * The subrange is defined as <b>[aFirstIdx, aLastIdx]</b>. 00207 * The function returns <b>-1</b> if the value is not found. 00208 * 00209 * @param anArray an array 00210 * @param aFirstIdx lower index of the elements to be examined 00211 * @param aLastIdx upper index of the elements to be examined 00212 * @param aValue a value to be searched in the array 00213 * 00214 * @warning 00215 * - Operator '=' must be defined for objects of type <b>T</b> 00216 * - The behavior of the function is undefined in case of 00217 * wrong range <b>[aFirstIdx, aLastIdx]</b> 00218 */ 00219 template <class T> 00220 int 00221 qgFind(const T* const anArray, int aFirstIdx, int aLastIdx, T aValue) 00222 { 00223 int found = -1; 00224 00225 for (int idx = aFirstIdx ; idx <= aLastIdx ; ++idx) 00226 { 00227 if (anArray[idx] = aValue) 00228 { 00229 found = idx; 00230 } 00231 } 00232 00233 return found; 00234 } 00235 00236 //@} 00237 00238 00239 // ------------------------------------------------------------------- 00240 // I N I T I A L I Z A T I O N S 00241 // ------------------------------------------------------------------- 00242 00243 00244 /** @name Global functions for array initialization */ 00245 // ========================================= 00246 //@{ 00247 00248 /** 00249 * @ingroup GLOB_ARRAY 00250 * 00251 * @brief Set all elements of an array to a value. 00252 * 00253 * @param anArray an array 00254 * @param aSize size of the array 00255 * @param aValue value to assign to each element of the array 00256 * 00257 * @warning The behavior of the function is undefined 00258 * in case of wrong size. 00259 */ 00260 template <class T> 00261 inline void 00262 qgFill(T* anArray, int aSize, T aValue) 00263 { 00264 qgFill(anArray, 0, aSize - 1, aValue); 00265 } 00266 00267 00268 /** 00269 * @ingroup GLOB_ARRAY 00270 * 00271 * @brief Set each element of a subrange of an array. 00272 * 00273 * The subrange is defined as <b>[aFirstIdx, aLastIdx]</b>. 00274 * 00275 * @param anArray an array 00276 * @param aFirstIdx lower index of the elements to be set 00277 * @param aLastIdx upper index of the elements to be set 00278 * @param aValue value to set 00279 * 00280 * @warning 00281 * The behavior of the function is undefined in case of 00282 * wrong range <b>[aFirstIdx, aLastIdx]</b>. 00283 */ 00284 template <class T> 00285 void 00286 qgFill(T* anArray, int aFirstIdx, int aLastIdx, T aValue) 00287 { 00288 T* pArray = anArray; 00289 00290 for (int iCnt = aFirstIdx; iCnt <= aLastIdx; ++iCnt) 00291 { 00292 *pArray = aValue; 00293 ++pArray; 00294 } 00295 } 00296 00297 00298 /** 00299 * @ingroup GLOB_ARRAY 00300 * 00301 * @brief Set all bytes of an array to <b>0</b>. 00302 * 00303 * The operation is performed using a low level <b>memset</b>. 00304 * 00305 * @param anArray array to be set 00306 * @param aSize size of the array 00307 * 00308 * @warning 00309 * The behavior of the function is undefined in case of wrong size. 00310 */ 00311 template<class T> 00312 inline void 00313 qgMemSet(T* anArray, int aSize) 00314 { 00315 memset(anArray, 0, aSize * sizeof(T)); 00316 } 00317 00318 00319 /** 00320 * @ingroup GLOB_ARRAY 00321 * 00322 * @brief Set all bytes of an array to <b>0</b>. 00323 * 00324 * The subrange is defined as <b>[aFirstIdx, aLastIdx]</b>. 00325 * The operation is performed using a low level <b>memset</b>. 00326 * 00327 * @param anArray array to be set 00328 * @param aFirstIdx lower index of the elements to be set 00329 * @param aLastIdx upper index of the elements to be set 00330 * 00331 * @warning 00332 * The behavior of the function is undefined in case 00333 * of wrong range <b>[aFirstIdx, aLastIdx]</b>. 00334 */ 00335 template<class T> 00336 inline void 00337 qgMemSet(T* anArray, int aFirstIdx, int aLastIdx) 00338 { 00339 memset(anArray + aFirstIdx, 0, (aLastIdx - aFirstIdx + 1) * sizeof(T)); 00340 } 00341 00342 //@} 00343 00344 00345 // ------------------------------------------------------------------- 00346 // M A P P I N G F U N C T I O N S 00347 // ------------------------------------------------------------------- 00348 00349 00350 /** @name Global mapping functions on arrays */ 00351 // ================================== 00352 //@{ 00353 00354 /** 00355 * @ingroup GLOB_ARRAY 00356 * 00357 * @brief Apply a function to pairs of elements from two arrays. 00358 * 00359 * - Both arrays must have the same size. 00360 * - The two arguments and the result of the function must have 00361 * the same type as the elements of the arrays. 00362 * - For each index in the range determined by the given size, 00363 * the function is applied to the elements at current index 00364 * <b>i</b> in both arrays: <b>anOperation(aSource[i], aDest[i])</b>. 00365 * The value returned by the function is then stored at the current 00366 * index in the destination array. 00367 * 00368 * @param aSource source array (not modified) 00369 * @param aDest destination array (modified) 00370 * @param aSize size of the arrays 00371 * @param anOperation operation to apply to the elements of the arrays 00372 * 00373 * @warning 00374 * The behavior of the function is undefined in case of wrong size 00375 * or in case of overlaping arrays. 00376 */ 00377 template <class T> 00378 inline void 00379 qgForEach(T* const aSource, 00380 T* aDest, 00381 int aSize, 00382 T (*anOperation)(const T&, const T&)) 00383 { 00384 qgForEach(aSource, aDest, 0, aSize - 1, anOperation); 00385 } 00386 00387 00388 /** 00389 * @ingroup GLOB_ARRAY 00390 * 00391 * @brief Apply a given function to pairs of elements 00392 * from a subrange of two arrays. 00393 * 00394 * - The two arguments and the result of the function must have 00395 * the same type as the elements of the arrays. 00396 * - For each index in the range <b>[aFirstIdx, aLastIdx]</b>, 00397 * the function is applied to the elements at current index 00398 * <b>i</b> in both arrays: <b>anOperation(aSource[i], aDest[i])</b>. 00399 * The value returned by the function is then stored at the current 00400 * index in the destination array. 00401 * 00402 * @param aSource source array (not modified) 00403 * @param aDest destination array (modified) 00404 * @param aFirstIdx lower index of the elements to be used 00405 * @param aLastIdx upper index of the elements to be used 00406 * @param anOperation operation to apply to the elements of the arrays 00407 * 00408 * @warning 00409 * The behavior of the function is undefined in case of wrong range 00410 * <b>[aFirstIdx, aLastIdx]</b> or in case of overlaping arrays. 00411 */ 00412 template <class T> 00413 void 00414 qgForEach(T* const aSource, 00415 T* aDest, 00416 int aFirstIdx, 00417 int aLastIdx, 00418 T (*anOperation)(const T&, const T&)) 00419 { 00420 T* pSource = aSource + aFirstIdx; 00421 T* pDest = aDest + aFirstIdx; 00422 00423 for (int iCnt = aFirstIdx; iCnt <= aLastIdx; ++iCnt) 00424 { 00425 *pDest = (*anOperation)(*pSource, *pDest); 00426 ++pDest; 00427 ++pSource; 00428 } 00429 } 00430 00431 //@} 00432 00433 00434 // ------------------------------------------------------------------- 00435 00436 } // namespace qgar 00437 00438 00439 #endif /* __ARRAY_H_INCLUDED__ */