PureMVC PureMVC

include/PureMVC/Patterns/Iterator/Iterator.hpp

Go to the documentation of this file.
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__ */