iterator.h

Go to the documentation of this file.
00001 // $Id: iterator.h 751 2006-03-31 15:43:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 //
00099 // Some template classes for the STL iterators
00100 // (actually there's only the bidrectional one because that's all I want)
00101 
00102 #ifndef INC_ITERATOR
00103 #define INC_ITERATOR
00104 
00105 // We want better memory tracking
00106 // Declare smart memory handling in Debug builds
00107 #define new CAM_DEBUG_NEW
00108 
00109 //#include "function.h"
00110 
00111 //struct input_iterator_tag {};
00112 //struct output_iterator_tag {};
00113 //struct forward_iterator_tag {};
00114 struct BidirectionalIteratorTag {};
00115 //struct random_access_iterator_tag {};
00116 
00117 
00118 //template <class T, class Distance> struct input_iterator {};
00119 //struct output_iterator {};
00120 //template <class T, class Distance> struct forward_iterator {};
00121 template <class T, class Distance> struct BidirectionalIterator {};
00122 //template <class T, class Distance> struct random_access_iterator {};
00123 
00124 /*
00125 template <class T, class Distance> 
00126 inline input_iterator_tag 
00127 iterator_category(const input_iterator<T, Distance>&) {
00128     return input_iterator_tag();
00129 }
00130 
00131 inline output_iterator_tag iterator_category(const output_iterator&) {
00132     return output_iterator_tag();
00133 }
00134 
00135 template <class T, class Distance> 
00136 inline forward_iterator_tag
00137 iterator_category(const forward_iterator<T, Distance>&) {
00138     return forward_iterator_tag();
00139 }
00140 */
00141 template <class T, class Distance> 
00142 inline BidirectionalIteratorTag IteratorCategory(const BidirectionalIterator<T, Distance>&)
00143 {
00144     return BidirectionalIteratorTag();
00145 }
00146 /*
00147 template <class T, class Distance> 
00148 inline random_access_iterator_tag
00149 iterator_category(const random_access_iterator<T, Distance>&) {
00150     return random_access_iterator_tag();
00151 }
00152 
00153 template <class T>
00154 inline random_access_iterator_tag iterator_category(const T*) {
00155     return random_access_iterator_tag();
00156 }
00157 
00158 template <class T, class Distance> 
00159 inline T* value_type(const input_iterator<T, Distance>&) {
00160     return (T*)(0); 
00161 }
00162 
00163 template <class T, class Distance> 
00164 inline T* value_type(const forward_iterator<T, Distance>&) {
00165     return (T*)(0);
00166 }
00167 
00168 template <class T, class Distance> 
00169 inline T* value_type(const bidirectional_iterator<T, Distance>&) {
00170     return (T*)(0);
00171 }
00172 
00173 template <class T, class Distance> 
00174 inline T* value_type(const random_access_iterator<T, Distance>&) {
00175     return (T*)(0);
00176 }
00177 
00178 template <class T>
00179 inline T* value_type(const T*) { return (T*)(0); }
00180 
00181 template <class T, class Distance> 
00182 inline Distance* distance_type(const input_iterator<T, Distance>&) {
00183     return (Distance*)(0);
00184 }
00185 
00186 template <class T, class Distance> 
00187 inline Distance* distance_type(const forward_iterator<T, Distance>&) {
00188     return (Distance*)(0);
00189 }
00190 
00191 template <class T, class Distance> 
00192 inline Distance* 
00193 distance_type(const bidirectional_iterator<T, Distance>&) {
00194     return (Distance*)(0);
00195 }
00196 
00197 template <class T, class Distance> 
00198 inline Distance* 
00199 distance_type(const random_access_iterator<T, Distance>&) {
00200     return (Distance*)(0);
00201 }
00202 
00203 template <class T>
00204 inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }
00205 
00206 template <class Container>
00207 class back_insert_iterator : public output_iterator {
00208 protected:
00209     Container& container;
00210 public:
00211     back_insert_iterator(Container& x) : container(x) {}
00212     back_insert_iterator<Container>&
00213     operator=(const Container::value_type& value) { 
00214     container.push_back(value);
00215     return *this;
00216     }
00217     back_insert_iterator<Container>& operator*() { return *this; }
00218     back_insert_iterator<Container>& operator++() { return *this; }
00219     back_insert_iterator<Container>& operator++(INT32) { return *this; }
00220 };
00221 
00222 template <class Container>
00223 back_insert_iterator<Container> back_inserter(Container& x) {
00224     return back_insert_iterator<Container>(x);
00225 }
00226 
00227 template <class Container>
00228 class front_insert_iterator : public output_iterator {
00229 protected:
00230     Container& container;
00231 public:
00232     front_insert_iterator(Container& x) : container(x) {}
00233     front_insert_iterator<Container>&
00234     operator=(const Container::value_type& value) { 
00235     container.push_front(value);
00236     return *this;
00237     }
00238     front_insert_iterator<Container>& operator*() { return *this; }
00239     front_insert_iterator<Container>& operator++() { return *this; }
00240     front_insert_iterator<Container>& operator++(INT32) { return *this; }
00241 };
00242 
00243 template <class Container>
00244 front_insert_iterator<Container> front_inserter(Container& x) {
00245     return front_insert_iterator<Container>(x);
00246 }
00247 
00248 template <class Container>
00249 class insert_iterator : public output_iterator {
00250 protected:
00251     Container& container;
00252     Container::iterator iter;
00253 public:
00254     insert_iterator(Container& x, Container::iterator i) 
00255     : container(x), iter(i) {}
00256     insert_iterator<Container>&
00257     operator=(const Container::value_type& value) { 
00258     iter = container.insert(iter, value);
00259     ++iter;
00260     return *this;
00261     }
00262     insert_iterator<Container>& operator*() { return *this; }
00263     insert_iterator<Container>& operator++() { return *this; }
00264     insert_iterator<Container>& operator++(INT32) { return *this; }
00265 };
00266 
00267 template <class Container, class Iterator>
00268 insert_iterator<Container> inserter(Container& x, Iterator i) {
00269     return insert_iterator<Container>(x, Container::iterator(i));
00270 }
00271 
00272 template <class BidirectionalIterator, class T, class Reference, 
00273           class Distance> 
00274 // Reference = T& 
00275 // Distance = ptrdiff_t
00276 class reverse_bidirectional_iterator 
00277     : public bidirectional_iterator<T, Distance> {
00278     typedef reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
00279                                            Distance> self;
00280     friend bool operator==(const self& x, const self& y);
00281 protected:
00282     BidirectionalIterator current;
00283 public:
00284     reverse_bidirectional_iterator() {}
00285     reverse_bidirectional_iterator(BidirectionalIterator x) : current(x) {}
00286     BidirectionalIterator base() { return current; }
00287     Reference operator*() const {
00288     BidirectionalIterator tmp = current;
00289     return *--tmp;
00290     }
00291     self& operator++() {
00292     --current;
00293     return *this;
00294     }
00295     self operator++(INT32) {
00296     self tmp = *this;
00297     --current;
00298     return tmp;
00299     }
00300     self& operator--() {
00301     ++current;
00302     return *this;
00303     }
00304     self operator--(INT32) {
00305     self tmp = *this;
00306     ++current;
00307     return tmp;
00308     }
00309 };
00310 
00311 template <class BidirectionalIterator, class T, class Reference,
00312           class Distance>
00313 inline bool operator==(
00314     const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
00315                                  Distance>& x, 
00316     const reverse_bidirectional_iterator<BidirectionalIterator, T, Reference,
00317                                  Distance>& y) {
00318     return x.current == y.current;
00319 }
00320 
00321 template <class RandomAccessIterator, class T, class Reference,
00322           class Distance> 
00323 // Reference = T&
00324 // Distance = ptrdiff_t
00325 class reverse_iterator : public random_access_iterator<T, Distance> {
00326     typedef reverse_iterator<RandomAccessIterator, T, Reference, Distance>
00327     self;
00328     friend bool operator==(const self& x, const self& y);
00329     friend bool operator<(const self& x, const self& y);
00330     friend Distance operator-(const self& x, const self& y);
00331     friend self operator+(Distance n, const self& x);
00332 protected:
00333     RandomAccessIterator current;
00334 public:
00335     reverse_iterator() {}
00336     reverse_iterator(RandomAccessIterator x) : current(x) {}
00337     RandomAccessIterator base() { return current; }
00338     Reference operator*() const { return *(current - 1); }
00339     self& operator++() {
00340     --current;
00341     return *this;
00342     }
00343     self operator++(INT32) {
00344     self tmp = *this;
00345     --current;
00346     return tmp;
00347     }
00348     self& operator--() {
00349     ++current;
00350     return *this;
00351     }
00352     self operator--(INT32) {
00353     self tmp = *this;
00354     ++current;
00355     return tmp;
00356     }
00357     self operator+(Distance n) const {
00358     return self(current - n);
00359     }
00360     self& operator+=(Distance n) {
00361     current -= n;
00362     return *this;
00363     }
00364     self operator-(Distance n) const {
00365     return self(current + n);
00366     }
00367     self& operator-=(Distance n) {
00368     current += n;
00369     return *this;
00370     }
00371     Reference operator[](Distance n) { return *(*this + n); }
00372 };
00373 
00374 template <class RandomAccessIterator, class T, class Reference, class Distance>
00375 inline bool operator==(const reverse_iterator<RandomAccessIterator, T,
00376                                       Reference, Distance>& x, 
00377                const reverse_iterator<RandomAccessIterator, T,
00378                                       Reference, Distance>& y) {
00379     return x.current == y.current;
00380 }
00381 
00382 template <class RandomAccessIterator, class T, class Reference, class Distance>
00383 inline bool operator<(const reverse_iterator<RandomAccessIterator, T,
00384                                      Reference, Distance>& x, 
00385               const reverse_iterator<RandomAccessIterator, T,
00386                                      Reference, Distance>& y) {
00387     return y.current < x.current;
00388 }
00389 
00390 template <class RandomAccessIterator, class T, class Reference, class Distance>
00391 inline Distance operator-(const reverse_iterator<RandomAccessIterator, T,
00392                                      Reference, Distance>& x, 
00393               const reverse_iterator<RandomAccessIterator, T,
00394                                      Reference, Distance>& y) {
00395     return y.current - x.current;
00396 }
00397 
00398 template <class RandomAccessIterator, class T, class Reference, class Distance>
00399 inline reverse_iterator<RandomAccessIterator, T, Reference, Distance> 
00400 operator+(Distance n,
00401       const reverse_iterator<RandomAccessIterator, T, Reference,
00402                              Distance>& x) {
00403     return reverse_iterator<RandomAccessIterator, T, Reference, Distance>
00404     (x.current - n);
00405 }
00406 
00407 
00408 template <class OutputIterator, class T>
00409 class raw_storage_iterator : public output_iterator {
00410 protected:
00411     OutputIterator iter;
00412 public:
00413     raw_storage_iterator(OutputIterator x) : iter(x) {}
00414     raw_storage_iterator<OutputIterator, T>& operator*() { return *this; }
00415     raw_storage_iterator<OutputIterator, T>& operator=(const T& element) {
00416     construct(iter, element);
00417     return *this;
00418     }        
00419     raw_storage_iterator<OutputIterator, T>& operator++() {
00420     ++iter;
00421     return *this;
00422     }
00423     raw_storage_iterator<OutputIterator, T> operator++(INT32) {
00424     raw_storage_iterator<OutputIterator, T> tmp = *this;
00425     ++iter;
00426     return tmp;
00427     }
00428 };
00429 
00430 
00431 template <class T, class Distance> // Distance == ptrdiff_t
00432 class istream_iterator : public input_iterator<T, Distance> {
00433 friend bool operator==(const istream_iterator<T, Distance>& x,
00434                const istream_iterator<T, Distance>& y);
00435 protected:
00436     istream* stream;
00437     T value;
00438     bool end_marker;
00439     void read() {
00440     end_marker = (*stream) ? true : false;
00441     if (end_marker) *stream >> value;
00442     end_marker = (*stream) ? true : false;
00443     }
00444 public:
00445     istream_iterator() : stream(&cin), end_marker(false) {}
00446     istream_iterator(istream& s) : stream(&s) { read(); }
00447     const T& operator*() const { return value; }
00448     istream_iterator<T, Distance>& operator++() { 
00449     read(); 
00450     return *this;
00451     }
00452     istream_iterator<T, Distance> operator++(INT32)  {
00453     istream_iterator<T, Distance> tmp = *this;
00454     read();
00455     return tmp;
00456     }
00457 };
00458 
00459 template <class T, class Distance>
00460 bool operator==(const istream_iterator<T, Distance>& x,
00461         const istream_iterator<T, Distance>& y) {
00462     return x.stream == y.stream && x.end_marker == y.end_marker ||
00463     x.end_marker == false && y.end_marker == false;
00464 }
00465 
00466 template <class T>
00467 class ostream_iterator : public output_iterator {
00468 protected:
00469     ostream* stream;
00470     char* string;
00471 public:
00472     ostream_iterator(ostream& s) : stream(&s), string(0) {}
00473     ostream_iterator(ostream& s, char* c) : stream(&s), string(c)  {}
00474     ostream_iterator<T>& operator=(const T& value) { 
00475     *stream << value;
00476     if (string) *stream << string;
00477     return *this;
00478     }
00479     ostream_iterator<T>& operator*() { return *this; }
00480     ostream_iterator<T>& operator++() { return *this; } 
00481     ostream_iterator<T>& operator++(INT32) { return *this; } 
00482 };
00483 */
00484 
00485 #endif  // INC_ITERATOR

Generated on Sat Nov 10 03:45:34 2007 for Camelot by  doxygen 1.4.4