any_iterator.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2006-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://stlab.adobe.com/licenses.html) 00005 */ 00006 00007 /*************************************************************************************************/ 00008 00009 #ifndef ADOBE_ANY_ITERATOR_HPP 00010 #define ADOBE_ANY_ITERATOR_HPP 00011 00012 #include <adobe/config.hpp> 00013 00014 #include <boost/concept_check.hpp> 00015 00016 #include <adobe/move.hpp> 00017 #include <adobe/poly.hpp> 00018 00019 /*************************************************************************************************/ 00020 00021 namespace adobe { 00022 00023 /*************************************************************************************************/ 00024 00025 template < typename V, // T models Regular Type 00026 typename R = V&, // R models Reference Type 00027 typename D = std::ptrdiff_t // D models Signed Integer 00028 > 00029 struct poly_iterator_interface : poly_copyable_interface 00030 { 00031 virtual R dereference() const = 0; 00032 virtual void increment() = 0; 00033 virtual bool equals(const poly_iterator_interface &) const = 0; 00034 }; 00035 00036 00037 00038 /*************************************************************************************************/ 00039 00040 template < typename V, // T models Regular Type 00041 typename R = V&, // R models Reference Type 00042 typename D = std::ptrdiff_t // D models Signed Integer 00043 > 00044 struct poly_iterator_instance { 00045 template <typename I> 00046 struct type : optimized_storage_type<I, poly_iterator_interface<V, R, D> >::type 00047 { 00048 typedef typename optimized_storage_type<I, poly_iterator_interface<V, R, D> >::type base_t; 00049 00050 BOOST_CLASS_REQUIRE(I, boost, ForwardIteratorConcept); 00051 00052 type(const I& x) : base_t (x) 00053 { } 00054 00055 type(move_from<type> x) 00056 : base_t(move_from<base_t>(x.source)) 00057 { } 00058 00059 type() : base_t() 00060 { } 00061 00062 R dereference() const 00063 { return *this->get(); } 00064 00065 void increment() 00066 { ++this->get(); } 00067 00068 bool equals(const poly_iterator_interface<V, R, D>& x) const 00069 { 00070 return this->type_info() == x.type_info() && this->get() == *static_cast<const I*>(x.cast()); 00071 } 00072 }; 00073 }; 00074 00075 /*************************************************************************************************/ 00076 00077 template < typename V, // T models Regular Type 00078 typename R = V&, // R models Reference Type 00079 typename D = std::ptrdiff_t // D models Signed Integer 00080 > 00081 struct iter : public poly_base<poly_iterator_interface<V, R, D>, 00082 poly_iterator_instance<V, R, D>::template type>, 00083 public boost::iterator_facade<iter<V, R, D>, 00084 V, std::forward_iterator_tag, R, D 00085 > 00086 { 00087 typedef poly_base<poly_iterator_interface<V, R, D>, 00088 poly_iterator_instance<V, R, D>::template type> base; 00089 00090 template <typename Iter> 00091 explicit iter(const Iter& s) : base(s) 00092 { } 00093 00094 iter(move_from<iter> x) : base(move_from<base>(x.source)) { } 00095 iter& operator=(iter x) { static_cast<base&>(*this) = adobe::move(static_cast<base&>(x)); return *this; } 00096 00097 R dereference() const 00098 { return this->interface_ref().dereference(); } 00099 00100 void increment() 00101 { this->interface_ref().increment(); } 00102 00103 bool equal(const iter& x) const 00104 { return *this == x; } 00105 00106 //disambiguate since iter adaptor and poly both try to provide operator== 00107 friend bool operator==(const iter& x, const iter& y) 00108 { return base(x) == base(y); } 00109 }; 00110 00111 /*************************************************************************************************/ 00112 00113 00114 template < typename V, // T models Regular Type 00115 typename R = V&, // R models Reference Type 00116 typename D = std::ptrdiff_t // D models Signed Integer 00117 > 00118 struct any_bidirectional_iterator_interface : public poly_iterator_interface<V, R, D> 00119 { 00120 virtual void decrement() = 0; 00121 using poly_iterator_interface<V, R, D>::equals; 00122 }; 00123 00124 /*************************************************************************************************/ 00125 00126 template < typename V, // T models Regular Type 00127 typename R = V&, // R models Reference Type 00128 typename D = std::ptrdiff_t // D models Signed Integer 00129 > 00130 struct any_bidirectional_iterator_instance { 00131 template <typename I> 00132 struct type : optimized_storage_type<I, any_bidirectional_iterator_interface<V, R, D> >::type 00133 { 00134 typedef typename optimized_storage_type<I, any_bidirectional_iterator_interface<V, R, D> >::type base_t; 00135 00136 BOOST_CLASS_REQUIRE(I, boost, BidirectionalIteratorConcept); 00137 00138 type(const I& x) 00139 : base_t(x) {} 00140 00141 type(move_from<type> x) 00142 : base_t(move_from<base_t>(x.source)) {} 00143 00144 type() 00145 : base_t() {} 00146 00147 R dereference() const 00148 { return *this->get(); } 00149 00150 void increment() 00151 { ++this->get(); } 00152 00153 void decrement() 00154 { --this->get(); } 00155 00156 bool equals(const poly_iterator_interface<V, R, D>& x) const 00157 { 00158 return this->type_info() == x.type_info() && this->get() 00159 == *static_cast<const I*>(x.cast()); 00160 } 00161 00162 bool equals(const any_bidirectional_iterator_interface<V, R, D>& x) const 00163 { 00164 return this->type_info() == x.type_info() && this->get() 00165 == *static_cast<const I*>(x.cast()); 00166 } 00167 00168 }; 00169 00170 00171 }; 00172 00173 /*************************************************************************************************/ 00174 00175 template < typename V, // T models Regular Type 00176 typename R = V&, // R models Reference Type 00177 typename D = std::ptrdiff_t // D models Signed Integer 00178 > 00179 struct bidirectional_iter : 00180 public poly_base<any_bidirectional_iterator_interface<V, R, D>, 00181 any_bidirectional_iterator_instance<V, R, D>::template type >, 00182 public boost::iterator_facade<bidirectional_iter<V, R, D>, 00183 V, std::bidirectional_iterator_tag, R, D> 00184 00185 { 00186 typedef poly_base<any_bidirectional_iterator_interface<V, R, D>, 00187 any_bidirectional_iterator_instance<V, R, D>::template type> base; 00188 00189 template <typename Iter> 00190 explicit bidirectional_iter(const Iter& s) : base (s) {} 00191 00192 bidirectional_iter(move_from<bidirectional_iter> x) : base(move_from<base>(x.source)) { } 00193 00194 bidirectional_iter& operator=(bidirectional_iter x) { static_cast<base&>(*this) = adobe::move(static_cast<base&>(x)); return *this; } 00195 00196 R dereference() const 00197 { return this->interface_ref().dereference(); } 00198 00199 void increment() 00200 { this->interface_ref().increment(); } 00201 00202 void decrement() 00203 { this->interface_ref().decrement(); } 00204 00205 bool equal(const bidirectional_iter& x) const 00206 { return *this == x; } 00207 00208 //disambiguate since iter adaptor and poly both try to provide operator== 00209 friend bool operator==(const bidirectional_iter& x, const bidirectional_iter& y) 00210 { return x.interface_ref().equals(y.interface_ref()); } 00211 }; 00212 00213 /*************************************************************************************************/ 00214 00215 template < typename V, // T models Regular Type 00216 typename R = V&, // R models Reference Type 00217 typename D = std::ptrdiff_t // D models Signed Integer 00218 > 00219 struct any_random_access_iterator_interface : public any_bidirectional_iterator_interface<V, R, D> 00220 { 00221 virtual void advance(D) = 0; 00222 virtual D distance_to(const any_random_access_iterator_interface& x) const = 0; 00223 using any_bidirectional_iterator_interface<V, R, D>::equals; 00224 }; 00225 00226 /*************************************************************************************************/ 00227 00228 template < typename V, // T models Regular Type 00229 typename R = V&, // R models Reference Type 00230 typename D = std::ptrdiff_t // D models Signed Integer 00231 > 00232 struct any_random_access_iterator_instance { 00233 template <typename I> // I models Random Access Iterator 00234 struct type : optimized_storage_type<I, any_random_access_iterator_interface<V, R, D> >::type 00235 { 00236 typedef typename optimized_storage_type<I, any_random_access_iterator_interface<V, R, D> >::type base_t; 00237 00238 BOOST_CLASS_REQUIRE(I, boost, RandomAccessIteratorConcept); 00239 00240 type(const I& x) 00241 : base_t(x) {} 00242 00243 type(move_from<type> x) 00244 : base_t(move_from<base_t>(x.source)) {} 00245 00246 type() 00247 : base_t() {} 00248 00249 R dereference() const 00250 { return *this->get(); } 00251 00252 void increment() 00253 { ++this->get(); } 00254 00255 void decrement() 00256 { --this->get(); } 00257 00258 void advance(D d) 00259 { std::advance(this->get(), d); } 00260 00261 D distance_to(const any_random_access_iterator_interface<V, R, D>& x) const 00262 { 00263 return std::distance(this->get(), *static_cast<const I*>(x.cast())); 00264 } 00265 00266 bool equals(const poly_iterator_interface<V, R, D>& x) const 00267 { 00268 return this->type_info() == x.type_info() && this->get() 00269 == *static_cast<const I*>(x.cast()); 00270 } 00271 00272 bool equals(const any_bidirectional_iterator_interface<V, R, D>& x) const 00273 { 00274 return this->type_info() == x.type_info() && this->get() 00275 == *static_cast<const I*>(x.cast()); 00276 } 00277 00278 00279 bool equals(const any_random_access_iterator_interface<V, R, D>& x) const 00280 { 00281 return this->type_info() == x.type_info() && this->get() 00282 == *static_cast<const I*>(x.cast()); 00283 } 00284 00285 }; 00286 }; 00287 00288 00289 /*************************************************************************************************/ 00290 00291 template < typename V, // T models Regular Type 00292 typename R = V&, // R models Reference Type 00293 typename D = std::ptrdiff_t // D models Signed Integer 00294 > 00295 struct random_access_iter : 00296 public poly_base<any_random_access_iterator_interface<V, R, D>, 00297 any_random_access_iterator_instance<V, R, D>::template type>, 00298 public boost::iterator_facade<random_access_iter<V, R, D>, 00299 V, std::random_access_iterator_tag, R, D> 00300 { 00301 typedef poly_base<any_random_access_iterator_interface<V, R, D>, 00302 any_random_access_iterator_instance<V, R, D>::template type> base; 00303 00304 template <typename Iter> 00305 explicit random_access_iter(const Iter& s) : base(s) { } 00306 00307 random_access_iter(move_from<random_access_iter> x) : base(move_from<base>(x.source)) { } 00308 00309 random_access_iter& operator=(random_access_iter x) { static_cast<base&>(*this) = adobe::move(static_cast<base&>(x)); return *this; } 00310 00311 R dereference() const 00312 { return this->interface_ref().dereference(); } 00313 00314 void increment() 00315 { this->interface_ref().increment(); } 00316 00317 void decrement() 00318 { this->interface_ref().decrement(); } 00319 00320 void advance(D d) 00321 { this->interface_ref().advance(d); } 00322 00323 D distance_to(const random_access_iter& x) const 00324 { 00325 return this->interface_ref().distance_to(x.interface_ref()); 00326 } 00327 00328 bool equal(const random_access_iter& x) const 00329 { return *this == x; } 00330 00331 //disambiguate since iter adaptor and poly both try to provide operator== 00332 friend bool operator==(const random_access_iter& x, const random_access_iter& y) 00333 { return x.interface_ref().equals(y.interface_ref()); } 00334 }; 00335 00336 00337 /*************************************************************************************************/ 00338 00339 } //namespace adobe 00340 00341 /*************************************************************************************************/ 00342 00343 #endif |