PureMVC PureMVC
|
00001 // Iterator.hpp 00002 // PureMVC_C++ 00003 // 00004 // PureMVC Port to C++ by Tang Khai Phuong <phuong.tang@puremvc.org> 00005 // PureMVC - Copyright(c) 2006-2011 Futurescale, Inc., Some rights reserved. 00006 // Your reuse is governed by the Creative Commons Attribution 3.0 License 00007 // 00008 00009 #if !defined(__PUREMVC_PATTERNS_ITERATOR_ITERATOR_HPP__) 00010 #define __PUREMVC_PATTERNS_ITERATOR_ITERATOR_HPP__ 00011 00012 // STL include 00013 #include <functional> 00014 #include <algorithm> 00015 #include <exception> 00016 #include <stdexcept> 00017 // PureMVC include 00018 #if !defined(__PUREMVC_HPP__) 00019 #define __PUREMVC_INCLUDE__ 00020 #include "../PureMVC.hpp" 00021 #endif /* __PUREMVC_HPP__ */ 00022 00023 #include "../../Interfaces/IIterator.hpp" 00024 00025 namespace PureMVC 00026 { 00027 namespace Patterns 00028 { 00029 using Interfaces::IAggregate; 00030 using Interfaces::IIterator; 00031 00035 template<typename _Type, typename _IteratorType> 00036 struct DefaultIteratorConverter : public std::unary_function<_IteratorType, _Type> 00037 { 00044 inline _Type const& operator()(_IteratorType const& iterator) const 00045 { 00046 return *(const _Type*)(&(*iterator)); 00047 } 00048 }; 00049 00053 template<typename _Type, 00054 typename _IteratorType = _Type, 00055 typename _ConverterType = DefaultIteratorConverter<_Type, _IteratorType> > 00056 class Iterator : public virtual IIterator<_Type> 00057 { 00058 protected: 00059 mutable _IteratorType* _begin; 00060 mutable _IteratorType* _end; 00061 mutable _IteratorType* _current; 00062 mutable _ConverterType _converter; 00063 mutable PureMVC::Mutex _mutex; 00064 public: 00068 explicit Iterator(void) 00069 :_begin(NULL) 00070 ,_end(NULL) 00071 ,_current(NULL) 00072 { } 00073 00080 explicit Iterator(_IteratorType const& begin, _IteratorType const& end) 00081 :_begin(new _IteratorType(begin) ) 00082 ,_end(new _IteratorType(end) ) 00083 ,_current(NULL) 00084 { } 00085 00091 explicit Iterator(Iterator const& arg) 00092 :_begin(new _IteratorType(*(arg._begin) ) ) 00093 ,_end(new _IteratorType(*(arg._end) ) ) 00094 ,_current(new _IteratorType(*(arg._current) ) ) 00095 { } 00096 00097 #if defined(PUREMVC_HAS_RVALUE) 00098 00103 explicit Iterator(Iterator&& arg) 00104 :_begin(std::move(arg._begin) ) 00105 ,_end(std::move(arg._end) ) 00106 ,_current(std::move(arg._current) ) 00107 { 00108 arg._begin = NULL; 00109 arg._end = NULL; 00110 arg._current = NULL; 00111 } 00112 #endif 00113 public: 00114 /* 00115 * Gets the current item. 00116 * 00117 * @return The references of current item. 00118 */ 00119 virtual _Type const& getCurrent(void) const 00120 { 00121 PureMVC::ScopedLock _(_mutex); 00122 if (this->_begin == NULL) 00123 throw std::runtime_error("Begin iterator is null."); 00124 if (this->_end == NULL ) 00125 throw std::runtime_error("End iterator is null."); 00126 if (this->_current == NULL) 00127 throw std::out_of_range("Iterator is out of range. Please use moveNext() method."); 00128 if (*this->_current == *_end) 00129 throw std::out_of_range("Iterator is out of range. Please use reset() method."); 00130 return _converter(*this->_current); 00131 } 00132 00133 /* 00134 * Gets the current item base on operator. 00135 * 00136 * @return The references of current item. 00137 */ 00138 virtual _Type const& operator*() const 00139 { 00140 return getCurrent(); 00141 } 00142 00143 /* 00144 * Move to next item. 00145 * 00146 * @return True if it succeeds, false if it fails. 00147 */ 00148 virtual bool moveNext(void) const 00149 { 00150 PureMVC::ScopedLock _(_mutex); 00151 if (this->_begin == NULL) 00152 throw std::runtime_error("Begin iterator is null."); 00153 if (this->_end == NULL ) 00154 throw std::runtime_error("End iterator is null."); 00155 if (this->_current == NULL) 00156 this->_current = new _IteratorType(*_begin); 00157 else if (*this->_current == *_end) 00158 return false; 00159 else 00160 ++(*this->_current); 00161 if (*this->_current == *_end) 00162 return false; 00163 return true; 00164 } 00165 00166 /* 00167 * Reset iterator. 00168 */ 00169 virtual void reset(void) const 00170 { 00171 PureMVC::ScopedLock _(_mutex); 00172 if (this->_current != NULL ) 00173 delete this->_current; 00174 00175 this->_current = NULL; 00176 } 00177 00178 /* 00179 * Setting stl-iterator range. 00180 * 00181 * @param begin The begin point of stl-iterator. 00182 * @param end The end point of stl-iterator. 00183 */ 00184 virtual void operator()(_IteratorType const& begin, _IteratorType const& end) const 00185 { 00186 PureMVC::ScopedLock _(_mutex); 00187 if (this->_begin != NULL ) 00188 delete this->_begin; 00189 if (this->_end != NULL ) 00190 delete this->_end; 00191 if (this->_current != NULL ) 00192 delete this->_current; 00193 00194 this->_current = NULL; 00195 this->_begin = new _IteratorType(begin); 00196 this->_end = new _IteratorType(end); 00197 } 00198 00199 /* 00200 * Assignment operator. 00201 * 00202 * @return The reference of itself. 00203 */ 00204 Iterator& operator=(Iterator const& arg) 00205 { 00206 PureMVC::ScopedLock _(_mutex); 00207 if (this->_begin != NULL ) 00208 delete this->_begin; 00209 if (this->_end != NULL ) 00210 delete this->_end; 00211 if (this->_current != NULL ) 00212 delete this->_current; 00213 00214 this->_current = new _IteratorType(arg._current); 00215 this->_begin = new _IteratorType(arg._begin); 00216 this->_end = new _IteratorType(arg._end); 00217 return *this; 00218 } 00219 00220 #if defined(PUREMVC_HAS_RVALUE) 00221 /* 00222 * Moving operator. 00223 * 00224 * @return this The reference of itself. 00225 */ 00226 Iterator& operator=(Iterator&& arg) 00227 { 00228 PureMVC::ScopedLock _(_mutex); 00229 if (this->_begin != NULL ) 00230 delete this->_begin; 00231 if (this->_end != NULL ) 00232 delete this->_end; 00233 if (this->_current != NULL ) 00234 delete this->_current; 00235 00236 this->_current = std::move(arg._current); 00237 this->_begin = std::move(arg._begin); 00238 this->_end = std::move(arg._end); 00239 arg._current = NULL; 00240 arg._begin = NULL; 00241 arg._end = NULL; 00242 return *this; 00243 } 00244 #endif 00245 00246 public: 00247 virtual ~Iterator(void) 00248 { 00249 if (this->_begin != NULL ) 00250 delete this->_begin; 00251 if (this->_end != NULL ) 00252 delete this->_end; 00253 if (this->_current != NULL ) 00254 delete this->_current; 00255 this->_begin = NULL; 00256 this->_end = NULL; 00257 this->_current = NULL; 00258 } 00259 }; 00260 00264 template<typename _Container, 00265 typename _IteratorType = typename _Container::const_iterator> 00266 struct StdContainerRange 00267 { 00268 /* 00269 * Convert begin range of iterator. 00270 * 00271 * @param iterator The source iterator. 00272 * @return The result iterator. 00273 */ 00274 inline _IteratorType begin(_Container const& iterator) const 00275 { 00276 return iterator.begin(); 00277 } 00278 00279 /* 00280 * Convert begin range of iterator. 00281 * 00282 * @param iterator The source iterator. 00283 * @return The result iterator. 00284 */ 00285 inline _IteratorType end(_Container const& iterator) const 00286 { 00287 return iterator.end(); 00288 } 00289 }; 00290 00294 template<typename _ContainerType, 00295 #if defined(_MSC_VER) && _MSC_VER < 1300 00296 typename _ValueType = _ContainerType::value_type, 00297 typename _IteratorType = _ContainerType::const_iterator, 00298 #else 00299 typename _ValueType = typename _ContainerType::value_type, 00300 typename _IteratorType = typename _ContainerType::const_iterator, 00301 #endif 00302 typename _ConverterType = DefaultIteratorConverter<_ValueType, _IteratorType>, 00303 typename _ContainerRangeType = StdContainerRange<_ContainerType, _IteratorType> > 00304 class StdContainerAggregate : public virtual IAggregate<_ValueType> 00305 { 00306 public: 00307 typedef _ContainerType ContainerType; 00308 typedef _ValueType ValueType; 00309 typedef _IteratorType IteratorType; 00310 typedef _ConverterType ConverterType; 00311 typedef _ContainerRangeType ContainerRangeType; 00312 typedef typename Interfaces::IAggregate<_ValueType> Aggregate; 00313 private: 00314 ContainerType _container; 00315 ContainerRangeType _container_range; 00316 private: 00317 template<typename _Type> 00318 static inline void setNull(_Type const& arg){ } 00319 template<typename _Type> 00320 static inline void setNull(_Type*& arg) { arg = NULL; } 00321 template<typename _Type> 00322 static inline void setNull(_Type const*& arg) { arg = NULL; } 00323 public: 00324 class IteratorImplement : public Patterns::Iterator<ValueType, IteratorType, ConverterType> 00325 { friend class StdContainerAggregate<ContainerType, ValueType, IteratorType, ConverterType, ContainerRangeType>; }; 00326 public: 00327 /* 00328 * Default constructor. 00329 */ 00330 explicit StdContainerAggregate(void) 00331 { } 00332 00333 /* 00334 * Constructor with constant reference to stl-container. 00335 * 00336 * @param container the stl-iterator reference. 00337 */ 00338 explicit StdContainerAggregate(ContainerType const& container) 00339 :_container(container) 00340 { } 00341 00342 /* 00343 * Copy constructor. 00344 * 00345 * @param arg the target argument to be copy from. 00346 */ 00347 explicit StdContainerAggregate(StdContainerAggregate const& arg) 00348 :_container(arg._container) 00349 { } 00350 00351 #if defined(PUREMVC_HAS_RVALUE) 00352 /* 00353 * Move constructor. 00354 * 00355 * @param arg the target argument to be move from. 00356 */ 00357 explicit StdContainerAggregate(StdContainerAggregate&& arg) 00358 :_container(std::move(arg._container)) 00359 { 00360 setNull(arg._container); 00361 } 00362 #endif 00363 public: 00364 /* 00365 * Assignment operator support. 00366 * 00367 * @param arg the target augment to be copy from. 00368 * @return The this reference. 00369 */ 00370 StdContainerAggregate& operator=(StdContainerAggregate const& arg) 00371 { 00372 _container = arg._container; 00373 return *this; 00374 } 00375 00376 #if defined(PUREMVC_HAS_RVALUE) 00377 /* 00378 * Moving operator support. 00379 * 00380 * @param arg the target augment to be copy from. 00381 * @return The this reference. 00382 */ 00383 StdContainerAggregate& operator=(StdContainerAggregate&& arg) 00384 { 00385 _container = std::move(arg._container); 00386 setNull(arg._container); 00387 return *this; 00388 } 00389 #endif 00390 public: 00391 /* 00392 * Get stl-container from aggregate. 00393 * 00394 * @return The stl-container reference. 00395 */ 00396 virtual ContainerType& get(void) 00397 { 00398 return _container; 00399 } 00400 /* 00401 * Get stl-container from aggregate. 00402 * 00403 * @return The stl-container reference. 00404 */ 00405 virtual ContainerType const& get(void) const 00406 { 00407 return _container; 00408 } 00409 public: 00410 /* 00411 * Set iterator to iterator. 00412 * 00413 * @param iterator the stl-iterator. 00414 */ 00415 virtual void setIterator(IIterator<ValueType>& iterator) const 00416 { 00417 typename StdContainerAggregate::IteratorImplement* result; 00418 result = dynamic_cast<typename StdContainerAggregate::IteratorImplement*>(&iterator); 00419 setIterator(*result); 00420 } 00421 00422 /* 00423 * Set iterator to iterator. 00424 * 00425 * @param iterator the stl-iterator. 00426 */ 00427 virtual void setIterator(typename StdContainerAggregate<ContainerType, ValueType, IteratorType, ConverterType, ContainerRangeType>::IteratorImplement& iterator) const 00428 { 00429 iterator(_container_range.begin(_container), _container_range.end(_container)); 00430 } 00431 00432 /* 00433 * Get iterator from this. 00434 * 00435 * @return The auto pointer of iterator. 00436 */ 00437 virtual std::auto_ptr<IIterator<ValueType> > getIterator(void) const 00438 { 00439 std::auto_ptr<IIterator<ValueType> > result(new typename StdContainerAggregate::IteratorImplement()); 00440 setIterator(*result); 00441 return result; 00442 } 00443 00444 /* 00445 * Virtual destructor. 00446 */ 00447 virtual ~StdContainerAggregate() 00448 { } 00449 }; 00450 } 00451 } 00452 00453 #endif /* __PUREMVC_PATTERNS_ITERATOR_ITERATOR_HPP__ */