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 // this is too restrictive check; need to make appropriate one 00051 #ifndef NO_ASL_AI_CONCEPT_CHECK 00052 BOOST_CLASS_REQUIRE(I, boost, ForwardIteratorConcept); 00053 #endif 00054 00055 type(const I& x) : base_t (x) 00056 { } 00057 00058 type(move_from<type> x) 00059 : base_t(move_from<base_t>(x.source)) 00060 { } 00061 00062 type() : base_t() 00063 { } 00064 00065 R dereference() const 00066 { return *this->get(); } 00067 00068 void increment() 00069 { ++this->get(); } 00070 00071 bool equals(const poly_iterator_interface<V, R, D>& x) const 00072 { 00073 return this->type_info() == x.type_info() && this->get() == *static_cast<const I*>(x.cast()); 00074 } 00075 }; 00076 }; 00077 00078 /*************************************************************************************************/ 00079 00080 template < typename V, // T models Regular Type 00081 typename R = V&, // R models Reference Type 00082 typename D = std::ptrdiff_t // D models Signed Integer 00083 > 00084 struct iter : public poly_base<poly_iterator_interface<V, R, D>, 00085 poly_iterator_instance<V, R, D>::template type>, 00086 public boost::iterator_facade<iter<V, R, D>, 00087 V, std::forward_iterator_tag, R, D 00088 > 00089 { 00090 typedef poly_base<poly_iterator_interface<V, R, D>, 00091 poly_iterator_instance<V, R, D>::template type> base; 00092 00093 template <typename Iter> 00094 explicit iter(const Iter& s) : base(s) 00095 { } 00096 00097 iter(move_from<iter> x) : base(move_from<base>(x.source)) { } 00098 iter& operator=(iter x) { static_cast<base&>(*this) = adobe::move(static_cast<base&>(x)); return *this; } 00099 00100 R dereference() const 00101 { return this->interface_ref().dereference(); } 00102 00103 void increment() 00104 { this->interface_ref().increment(); } 00105 00106 bool equal(const iter& x) const 00107 { return *this == x; } 00108 00109 //disambiguate since iter adaptor and poly both try to provide operator== 00110 friend bool operator==(const iter& x, const iter& y) 00111 { return base(x) == base(y); } 00112 }; 00113 00114 /*************************************************************************************************/ 00115 00116 00117 template < typename V, // T models Regular Type 00118 typename R = V&, // R models Reference Type 00119 typename D = std::ptrdiff_t // D models Signed Integer 00120 > 00121 struct any_bidirectional_iterator_interface : public poly_iterator_interface<V, R, D> 00122 { 00123 virtual void decrement() = 0; 00124 using poly_iterator_interface<V, R, D>::equals; 00125 }; 00126 00127 /*************************************************************************************************/ 00128 00129 template < typename V, // T models Regular Type 00130 typename R = V&, // R models Reference Type 00131 typename D = std::ptrdiff_t // D models Signed Integer 00132 > 00133 struct any_bidirectional_iterator_instance { 00134 template <typename I> 00135 struct type : optimized_storage_type<I, any_bidirectional_iterator_interface<V, R, D> >::type 00136 { 00137 typedef typename optimized_storage_type<I, any_bidirectional_iterator_interface<V, R, D> >::type base_t; 00138 00139 #ifndef NO_ASL_AI_CONCEPT_CHECK 00140 BOOST_CLASS_REQUIRE(I, boost, BidirectionalIteratorConcept); 00141 #endif 00142 00143 type(const I& x) 00144 : base_t(x) {} 00145 00146 type(move_from<type> x) 00147 : base_t(move_from<base_t>(x.source)) {} 00148 00149 type() 00150 : base_t() {} 00151 00152 R dereference() const 00153 { return *this->get(); } 00154 00155 void increment() 00156 { ++this->get(); } 00157 00158 void decrement() 00159 { --this->get(); } 00160 00161 bool equals(const poly_iterator_interface<V, R, D>& x) const 00162 { 00163 return this->type_info() == x.type_info() && this->get() 00164 == *static_cast<const I*>(x.cast()); 00165 } 00166 00167 bool equals(const any_bidirectional_iterator_interface<V, R, D>& x) const 00168 { 00169 return this->type_info() == x.type_info() && this->get() 00170 == *static_cast<const I*>(x.cast()); 00171 } 00172 00173 }; 00174 00175 00176 }; 00177 00178 /*************************************************************************************************/ 00179 00180 template < typename V, // T models Regular Type 00181 typename R = V&, // R models Reference Type 00182 typename D = std::ptrdiff_t // D models Signed Integer 00183 > 00184 struct bidirectional_iter : 00185 public poly_base<any_bidirectional_iterator_interface<V, R, D>, 00186 any_bidirectional_iterator_instance<V, R, D>::template type >, 00187 public boost::iterator_facade<bidirectional_iter<V, R, D>, 00188 V, std::bidirectional_iterator_tag, R, D> 00189 00190 { 00191 typedef poly_base<any_bidirectional_iterator_interface<V, R, D>, 00192 any_bidirectional_iterator_instance<V, R, D>::template type> base; 00193 00194 template <typename Iter> 00195 explicit bidirectional_iter(const Iter& s) : base (s) {} 00196 00197 bidirectional_iter(move_from<bidirectional_iter> x) : base(move_from<base>(x.source)) { } 00198 00199 bidirectional_iter& operator=(bidirectional_iter x) { static_cast<base&>(*this) = adobe::move(static_cast<base&>(x)); return *this; } 00200 00201 R dereference() const 00202 { return this->interface_ref().dereference(); } 00203 00204 void increment() 00205 { this->interface_ref().increment(); } 00206 00207 void decrement() 00208 { this->interface_ref().decrement(); } 00209 00210 bool equal(const bidirectional_iter& x) const 00211 { return *this == x; } 00212 00213 //disambiguate since iter adaptor and poly both try to provide operator== 00214 friend bool operator==(const bidirectional_iter& x, const bidirectional_iter& y) 00215 { return x.interface_ref().equals(y.interface_ref()); } 00216 }; 00217 00218 /*************************************************************************************************/ 00219 00220 template < typename V, // T models Regular Type 00221 typename R = V&, // R models Reference Type 00222 typename D = std::ptrdiff_t // D models Signed Integer 00223 > 00224 struct any_random_access_iterator_interface : public any_bidirectional_iterator_interface<V, R, D> 00225 { 00226 virtual void advance(D) = 0; 00227 virtual D distance_to(const any_random_access_iterator_interface& x) const = 0; 00228 using any_bidirectional_iterator_interface<V, R, D>::equals; 00229 }; 00230 00231 /*************************************************************************************************/ 00232 00233 template < typename V, // T models Regular Type 00234 typename R = V&, // R models Reference Type 00235 typename D = std::ptrdiff_t // D models Signed Integer 00236 > 00237 struct any_random_access_iterator_instance { 00238 template <typename I> // I models Random Access Iterator 00239 struct type : optimized_storage_type<I, any_random_access_iterator_interface<V, R, D> >::type 00240 { 00241 typedef typename optimized_storage_type<I, any_random_access_iterator_interface<V, R, D> >::type base_t; 00242 00243 #ifndef NO_ASL_AI_CONCEPT_CHECK 00244 BOOST_CLASS_REQUIRE(I, boost, RandomAccessIteratorConcept); 00245 #endif 00246 00247 type(const I& x) 00248 : base_t(x) {} 00249 00250 type(move_from<type> x) 00251 : base_t(move_from<base_t>(x.source)) {} 00252 00253 type() 00254 : base_t() {} 00255 00256 R dereference() const 00257 { return *this->get(); } 00258 00259 void increment() 00260 { ++this->get(); } 00261 00262 void decrement() 00263 { --this->get(); } 00264 00265 void advance(D d) 00266 { std::advance(this->get(), d); } 00267 00268 D distance_to(const any_random_access_iterator_interface<V, R, D>& x) const 00269 { 00270 return std::distance(this->get(), *static_cast<const I*>(x.cast())); 00271 } 00272 00273 bool equals(const poly_iterator_interface<V, R, D>& x) const 00274 { 00275 return this->type_info() == x.type_info() && this->get() 00276 == *static_cast<const I*>(x.cast()); 00277 } 00278 00279 bool equals(const any_bidirectional_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 bool equals(const any_random_access_iterator_interface<V, R, D>& x) const 00287 { 00288 return this->type_info() == x.type_info() && this->get() 00289 == *static_cast<const I*>(x.cast()); 00290 } 00291 00292 }; 00293 }; 00294 00295 00296 /*************************************************************************************************/ 00297 00298 template < typename V, // T models Regular Type 00299 typename R = V&, // R models Reference Type 00300 typename D = std::ptrdiff_t // D models Signed Integer 00301 > 00302 struct random_access_iter : 00303 public poly_base<any_random_access_iterator_interface<V, R, D>, 00304 any_random_access_iterator_instance<V, R, D>::template type>, 00305 public boost::iterator_facade<random_access_iter<V, R, D>, 00306 V, std::random_access_iterator_tag, R, D> 00307 { 00308 typedef poly_base<any_random_access_iterator_interface<V, R, D>, 00309 any_random_access_iterator_instance<V, R, D>::template type> base; 00310 00311 template <typename Iter> 00312 explicit random_access_iter(const Iter& s) : base(s) { } 00313 00314 random_access_iter(move_from<random_access_iter> x) : base(move_from<base>(x.source)) { } 00315 00316 random_access_iter& operator=(random_access_iter x) { static_cast<base&>(*this) = adobe::move(static_cast<base&>(x)); return *this; } 00317 00318 R dereference() const 00319 { return this->interface_ref().dereference(); } 00320 00321 void increment() 00322 { this->interface_ref().increment(); } 00323 00324 void decrement() 00325 { this->interface_ref().decrement(); } 00326 00327 void advance(D d) 00328 { this->interface_ref().advance(d); } 00329 00330 D distance_to(const random_access_iter& x) const 00331 { 00332 return this->interface_ref().distance_to(x.interface_ref()); 00333 } 00334 00335 bool equal(const random_access_iter& x) const 00336 { return *this == x; } 00337 00338 //disambiguate since iter adaptor and poly both try to provide operator== 00339 friend bool operator==(const random_access_iter& x, const random_access_iter& y) 00340 { return x.interface_ref().equals(y.interface_ref()); } 00341 }; 00342 00343 00344 /*************************************************************************************************/ 00345 00346 } //namespace adobe 00347 00348 /*************************************************************************************************/ 00349 00350 #endif |