last update 20 Sep 2009 |
00001 /* 00002 * Copyright (C) 2006 00003 * Peter Doerfler 00004 * 00005 * 00006 * This file is part of the Computer Vision and Robotics Library (CVR-Lib) 00007 * 00008 * The CVR-Lib is free software; you can redistribute it and/or 00009 * modify it under the terms of the BSD License. 00010 * 00011 * All rights reserved. 00012 * 00013 * Redistribution and use in source and binary forms, with or without 00014 * modification, are permitted provided that the following conditions are met: 00015 * 00016 * 1. Redistributions of source code must retain the above copyright notice, 00017 * this list of conditions and the following disclaimer. 00018 * 00019 * 2. Redistributions in binary form must reproduce the above copyright notice, 00020 * this list of conditions and the following disclaimer in the documentation 00021 * and/or other materials provided with the distribution. 00022 * 00023 * 3. Neither the name of the authors nor the names of its contributors may be 00024 * used to endorse or promote products derived from this software without 00025 * specific prior written permission. 00026 * 00027 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00028 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00029 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00030 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00031 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00032 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00033 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00034 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00035 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00036 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00037 * POSSIBILITY OF SUCH DAMAGE. 00038 */ 00039 00040 00041 00042 /** 00043 * \file cvrDebugIterator.h 00044 * Contains a generic implementation of debug iterators (used in debug 00045 * builds) for cvr::containers 00046 * \author Peter Doerfler 00047 * \date 13.08.2006 00048 * 00049 * $Id: cvrDebugIterator.h,v 1.1 2006/08/24 14:56:56 doerfler Exp $ 00050 */ 00051 00052 #ifndef _CVR_DEBUG_ITERATOR_H_ 00053 #define _CVR_DEBUG_ITERATOR_H_ 00054 00055 #include "cvrMetaProgrammingTools.h" 00056 #include <iterator> 00057 00058 namespace cvr { 00059 00060 namespace internal { 00061 00062 00063 // the general class declaration which is not needed 00064 // 00065 // without this trick it is not possible that Container is a friend of 00066 // debugIterator, as it is not clear that Container is indeed a 00067 // class. However, in the specialization below ContainerBase<T> is sure to 00068 // be a class and is exactly the type the generalVector and generalMatrix 00069 // classes have. 00070 template <typename Container, bool constIterator> 00071 class debugIterator {}; 00072 00073 /** 00074 * A generic debugging iterator for classes genericVector and 00075 * genericMatrix. See those classes for usage examples. 00076 * 00077 * This iterator is compatible with those found in the STL and can thus be 00078 * used with all of its functions. Specifically, this iterator is also 00079 * compatible with a simple pointer which is used as a the iterator of the 00080 * above containers in release mode. 00081 * 00082 * Template parameters: 00083 * - \p Container that has the data, e.g. genericVector<T>. It must 00084 * provide \p value_type. 00085 * - \p constIterator: if true a const_iterator is generated, otherwise an 00086 * iterator 00087 */ 00088 template <template <class> class ContainerBase, 00089 typename T, bool constIterator> 00090 class debugIterator<ContainerBase<T>, constIterator> 00091 : public std::iterator< 00092 std::random_access_iterator_tag, 00093 typename if_t<constIterator, 00094 const typename ContainerBase<T>::value_type, 00095 typename ContainerBase<T>::value_type>::type> { 00096 private: 00097 // the actual container type 00098 typedef ContainerBase<T> Container; 00099 00100 // the std::iterator<> type 00101 // could have used T, but probably better style like this 00102 typedef std::iterator< 00103 std::random_access_iterator_tag, 00104 typename if_t<constIterator, 00105 const typename Container::value_type, 00106 typename Container::value_type>::type> base_type; 00107 public: 00108 typedef typename base_type::iterator_category iterator_category; 00109 typedef typename base_type::value_type value_type; 00110 typedef typename base_type::difference_type difference_type; 00111 typedef typename base_type::reference reference; 00112 typedef typename base_type::pointer pointer; 00113 00114 private: 00115 // needed for special ctor that initializes the pointers 00116 friend class ContainerBase<T>; 00117 // needed for construction of a const_iterator from an iterator 00118 friend class debugIterator<Container, !constIterator>; 00119 00120 /** 00121 * Pointer to the current element 00122 */ 00123 pointer ptr_; 00124 00125 /** 00126 * Pointer to the first element of the container 00127 */ 00128 pointer begin_; 00129 00130 /** 00131 * Pointer behind the last element of the container 00132 */ 00133 pointer end_; 00134 00135 /** 00136 * Protected constructor (for internal use only) 00137 * NEVER USE THIS CONSTRUCTOR EXPLICITLY, OR YOUR CODE WILL NOT 00138 * COMPILE IN THE RELEASE VERSION! 00139 * 00140 * This constructor is used in the Container to initialize the internal 00141 * pointers. 00142 * 00143 * @param ptr pointer to the position the iterator will point to 00144 * @param begin pointer to the first element of the Container 00145 * @param end pointer behind the last element of the Container 00146 */ 00147 inline explicit debugIterator(pointer ptr, pointer begin, pointer end); 00148 00149 public: 00150 00151 /** 00152 * Default constructor 00153 */ 00154 inline debugIterator(); 00155 00156 /** 00157 * Copy constructor 00158 */ 00159 inline debugIterator(const debugIterator& other); 00160 00161 /** 00162 * Copy constructor. Construct a debugIterator with \p constIterator == 00163 * true from \p other with \p constIterator == false and with the same 00164 * Container. 00165 */ 00166 template <bool b> 00167 inline debugIterator(const debugIterator< 00168 typename enable_if<Container, 00169 constIterator&&!b>::type, b>& other); 00170 00171 /** 00172 * Advance to next item 00173 */ 00174 inline debugIterator& operator++(); // prefix 00175 00176 /** 00177 * Advance to next item 00178 */ 00179 inline debugIterator operator++(int); // postfix 00180 00181 /** 00182 * Recede to previous item 00183 */ 00184 inline debugIterator& operator--(); // prefix 00185 00186 /** 00187 * Recede to previous item 00188 */ 00189 inline debugIterator operator--(int); // postfix 00190 00191 /** 00192 * Advance (skip) some elements. 00193 * 00194 * Use this operator with care! Note that you can skip the end of 00195 * the Container, and read (or even worse: write!) out of bounds! 00196 */ 00197 inline debugIterator& operator+=(const difference_type& n); 00198 00199 /** 00200 * Recede (skip) some elements. 00201 * 00202 * Use this operator with care! Note that you can skip the beginning of 00203 * the Container, and read (or even worse: write!) out of bounds! 00204 */ 00205 inline debugIterator& operator-=(const difference_type& n); 00206 00207 /** 00208 * Advance (skip) some elements. 00209 * 00210 * Use this operator with care! Note that you can skip the end of 00211 * the Container, and read (or even worse: write!) out of bounds! 00212 */ 00213 inline debugIterator operator+(const difference_type& n); 00214 00215 /** 00216 * Recede (skip) some elements. 00217 * 00218 * Use this operator with care! Note that you can skip the beginning of 00219 * the Container, and read (or even worse: write!) out of bounds! 00220 */ 00221 inline debugIterator operator-(const difference_type& n); 00222 00223 /** 00224 * Get pointed data 00225 */ 00226 inline reference operator*() const; 00227 00228 /** 00229 * Get pointer to data 00230 */ 00231 inline pointer operator->() const; 00232 00233 /** 00234 * Access the elements relative to the debugIterator position 00235 */ 00236 inline reference operator[](const difference_type& n) const; 00237 00238 /** 00239 * Compare if the pointed position of \p other is the same as that of 00240 * this. 00241 */ 00242 template<bool constOther> 00243 inline bool 00244 operator==(const debugIterator<Container, constOther>& other) const; 00245 00246 /** 00247 * Compare if the pointed position of \p other is different from that of 00248 * this. 00249 */ 00250 template<bool constOther> 00251 inline bool 00252 operator!=(const debugIterator<Container, constOther>& other) const; 00253 00254 /** 00255 * Compare if the position to by this is smaller than the position 00256 * pointed to by \p other. 00257 */ 00258 template<bool constOther> 00259 inline bool 00260 operator<(const debugIterator<Container, constOther>& other) const; 00261 00262 /** 00263 * Compare if the position to by this is greater than the position 00264 * pointed to by \p other. 00265 */ 00266 template<bool constOther> 00267 inline bool 00268 operator>(const debugIterator<Container, constOther>& other) const; 00269 00270 /** 00271 * Compare if the position to by this is smaller or equal than the 00272 * position pointed to by \p other. 00273 */ 00274 template<bool constOther> 00275 inline bool 00276 operator<=(const debugIterator<Container, constOther>& other) const; 00277 00278 /** 00279 * Compare if the position to by this is greater or equal than the 00280 * position pointed to by \p other. 00281 */ 00282 template<bool constOther> 00283 inline bool 00284 operator>=(const debugIterator<Container, constOther>& other) const; 00285 00286 /** 00287 * Difference between this and the \p other debugIterator. 00288 */ 00289 template<bool constOther> 00290 inline difference_type 00291 operator-(const debugIterator<Container, constOther>& other) const; 00292 }; 00293 00294 } // namespace internal 00295 00296 } // namespace cvr 00297 00298 #include "cvrDebugIterator_inline.h" 00299 00300 #endif