utils.h

00001  /*****************************************************************************
00002  *   Copyright (C) 2006-2007 by Michael Schulze                               *
00003  *   mike.s@genion.de                                                         *
00004  *                                                                            *
00005  *  The code contained in this file is free software; you can redistribute    *
00006  *  it and/or modify it under the terms of the GNU Lesser General Public      *
00007  *  License as published by the Free Software Foundation; either version      *
00008  *  2.1 of the License, or (at your option) any later version.                *
00009  *                                                                            *
00010  *  This file is distributed in the hope that it will be useful,              *
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00013  *  Lesser General Public License for more details.                           *
00014  *                                                                            *
00015  *  You should have received a copy of the GNU Lesser General Public          *
00016  *  License along with this code; if not, write to the Free Software          *
00017  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *
00018  *                                                                            *
00019  *  iTunes and iPod are trademarks of Apple                                   *
00020  *                                                                            *
00021  *  This product is not supported/written/published by Apple!                 *
00022  *****************************************************************************/
00023 
00024 #ifndef _qtpod_itunesdb_utils_H_
00025 #define _qtpod_itunesdb_utils_H_
00026 
00027 // here you can enable usage of the boost shared_ptr impl if using an older libstdc++
00028 // uncomment the following line to use the boost shared_ptr
00029 // #define QTPOD_USE_BOOST_SHAREDPTR 1
00030 
00031 #ifdef QTPOD_USE_BOOST_SHAREDPTR
00032 
00033 #include <boost/shared_ptr.hpp>
00034 #define QTPOD_SHARED_PTR_IMPL_DEF boost::shared_ptr
00035 
00036 #else
00037 
00038 #include <tr1/memory>
00039 #define QTPOD_SHARED_PTR_IMPL_DEF std::tr1::shared_ptr
00040 
00041 #endif
00042 
00043 #include <vector>
00044 
00045 #define MAC_EPOCH_DELTA 2082844800
00046 
00047 namespace itunesdb {
00048 
00049 namespace utils {
00050 
00051 static const QString NullQString = QString();
00052 
00053 /**
00054  * some stuff to find/filter etc through containers
00055  */
00056 
00057 /**
00058  * Returns the Iterator where predicate(*iter) == TRUE
00059  */
00060 template <class Iter, class TUnaryPredicate>
00061 Iter findFirst( Iter pos, Iter end, const TUnaryPredicate& predicate ) {
00062     for (; pos != end; ++pos) {
00063         if (predicate(*pos)) {
00064             return pos;
00065         }
00066     }
00067     return end;
00068 }
00069 
00070 /**
00071  * Returns the Iterator to the element where the given function returned the biggest result
00072  */
00073 template <class Iter, class TUnaryFunction>
00074 Iter max( Iter pos, Iter end, const TUnaryFunction& fn ) {
00075     Iter currentMax = pos;
00076     for ( ; pos != end; ++pos ) {
00077         if ( fn( *pos ) > fn ( *currentMax ) ) {
00078             currentMax = pos;
00079         }
00080     }
00081     return currentMax;
00082 }
00083 
00084 
00085 /**
00086  * A marker predicate for unfiltered Iterators
00087  */
00088 struct TRUEPredicate {};
00089 
00090 /*
00091  * Internal functions for filtered Iterators
00092  */
00093 template < typename IterType, typename Iter, typename TUnaryPredicate, typename TDereferenceFun >
00094 struct RangeIteratorFunctions {
00095     TUnaryPredicate pred;
00096     TDereferenceFun deref;
00097 
00098     RangeIteratorFunctions( const TUnaryPredicate& p, const TDereferenceFun& d ) :
00099         pred( p ), deref( d ) {}
00100 
00101     Iter successor( const Iter& current, const Iter& end ) const {
00102         Iter result = current;
00103         while ( ++result != end && !pred( deref( result ) ) );
00104         return result;
00105     }
00106 
00107     bool isValid( const Iter& i ) const { return pred( deref( i ) ); }
00108 
00109     unsigned int remaining( const Iter& next, const Iter& end ) {
00110         Iter i = next;
00111         unsigned int result = 0;
00112         while ( i != end ) {
00113             result++;
00114             i = successor( i, end );
00115         }
00116         return result;
00117     }
00118 };
00119 
00120 /*
00121  * Internal functions for unfiltered Iterators
00122  */
00123 template < typename IterType, typename Iter, typename TDereferenceFun >
00124 struct RangeIteratorFunctions<IterType, Iter, TRUEPredicate, TDereferenceFun> {
00125     RangeIteratorFunctions( const TRUEPredicate&, const TDereferenceFun& ) {}
00126 
00127     Iter successor( const Iter& current, const Iter& ) const {
00128         Iter result = current;
00129         return ++result;
00130     }
00131 
00132     bool isValid( const Iter& ) const { return true; }
00133 
00134     unsigned int remaining( const Iter& next, const Iter& end ) {
00135         return end - next;
00136     }
00137 };
00138 
00139 /**
00140  * Default dereferencing functor just dereferencing iterators
00141  */
00142 template <typename PType, typename Iter> struct DefaultDeref {
00143 
00144     /**
00145      * Returns the dereferenced Iter
00146      * @param iter the Iter to dereference
00147      * @return the dereferenced Iter
00148      */
00149     const PType operator()( const Iter& iter ) const {
00150         return *iter;
00151     }
00152 };
00153 
00154 /**
00155  * @brief An Iterator over a range of elements (in most cases backed by some container).
00156  *
00157  * The RangeIterator can be used to iterate over a collection of elements using its hasNext() and next() methods.
00158  * For example to iterate over all the Tracks of a @c itunesdb::TrackPtrList :
00159  * <pre><code>
00160     itunesdb::TrackPtrList::Iterator trackIter = tlist.iterator();
00161     while( trackIter.hasNext() ) {
00162         itunesdb::Track * track = trackIter.next();
00163         ... some code ...
00164     }
00165  * </code></pre>
00166  * The TUnaryPredicate decides if an element is part of the range and therefore should be taken into account by hasNext()
00167  * and next() or not.
00168  * The Dereference Function dereferences an iterator and returns IterType. That's helpful if you need to create
00169  * an iterator over the keys of a map without being too obvious about your implementation details.
00170  * @see DereferencingRangeIterator for an example dereferencing the keys of a map.
00171  * @author Michael Schulze
00172  */
00173 template <typename IterType, typename Iter, typename TUnaryPredicate = TRUEPredicate, typename TDereferenceFun = DefaultDeref< IterType, Iter > >
00174 class RangeIterator {
00175     Iter m_current; // points to the element returned by next
00176     Iter m_next;    // points to the element to be returned by next()
00177     Iter m_end; // one beyond the last to return
00178 
00179 protected:
00180 
00181     /**
00182      * Dereferencer to dereference an iterator to IterType
00183      */
00184     TDereferenceFun m_dereferenceFun;
00185 
00186     /**
00187      * Internal implementors of the underlying functions
00188      */
00189     RangeIteratorFunctions<IterType, Iter, TUnaryPredicate, TDereferenceFun> m_helper;
00190 
00191     /**
00192      * @brief Sets the range to the given iterators
00193      */
00194     void setRange( Iter pos, Iter end ) {
00195         m_end = end;
00196         m_current = pos;
00197         if ( m_current != m_end && !m_helper.isValid( m_current ) ) {
00198             m_current = m_helper.successor( m_current, m_end );
00199         }
00200         m_next = m_current;
00201     }
00202 
00203     /**
00204      * @brief  Returns the iterator pointing to the element returned by the last next() call
00205      * @return the iterator pointing to the element returned by the last next() call
00206      */
00207     Iter currentPos() {
00208         return m_current;
00209     }
00210 
00211     /**
00212      * @brief Returns true if there are no elements left to be iterated over
00213      * @return true if there are no elements left to be iterated over
00214      */
00215     bool empty() const {
00216         return m_current == m_end;
00217     }
00218 
00219 public:
00220 
00221     /**
00222      * @brief Constructs a new Iterator from start to end with the given predicate.
00223      */
00224     RangeIterator(Iter start, Iter end, const TUnaryPredicate& predicate = TUnaryPredicate(), TDereferenceFun deref = TDereferenceFun() )
00225         : m_dereferenceFun( deref ), m_helper( predicate, deref )
00226     {
00227         setRange( start, end );
00228     }
00229 
00230     /**
00231      * @brief Returns true if there are elements left so calling next() would return the next element rather than causing a segfault
00232      * @return true if there are elements left
00233      */
00234     bool hasNext() const {
00235         return m_next != m_end;
00236     }
00237 
00238     /**
00239      * @brief Returns the next element of the range of elements we iterate over.
00240      *
00241      * This method positions the Iterator at the next element and returns it. The first call to
00242      * this method will return the first element of the range.
00243      * @n If the iterator is filtered only those elements where the given predicate returned true
00244      * are returned.
00245      * @attention Always check if hasNext() returns true before calling next. Calling next() on an iterator already at
00246      * the end of the range will cause a segfault.
00247      * @pre hasNext() returns true
00248      * @post a successive call to current() returns the element returned by this method
00249      */
00250     IterType next() {
00251         m_current = m_next;
00252         m_next = m_helper.successor( m_current, m_end );
00253         return current();
00254     }
00255 
00256     /**
00257      * @brief Returns the element returned by the last next() call
00258      * @return the element returned by the last next() call
00259      */
00260     IterType current() const {
00261         return m_dereferenceFun( m_current );
00262     }
00263 
00264     /**
00265      * @brief Returns the number of elements remaining in this iterator.
00266      *
00267      * ... meaning the number of times the next() method can be called before the hasNext() method willreturn false.
00268      * For filtered iterators this may be a lengthy operation since the iterator needs to apply its filter over all
00269      * elements to determine how many elements are left.
00270      * @return the number of elements left
00271      */
00272     unsigned int remaining() const {
00273         return m_helper.remaining( m_next, m_end );
00274     }
00275 
00276     /**
00277      * @brief Returns the last element this iterator would return.
00278      *
00279      * This method is dangerous and makes no sense. Do not call this for empty iterators so at least check with hasNext() before.
00280      * @return the last element this iterator would return
00281      * @pre it must have been ensured that the iterator is nonempty
00282      */
00283     IterType last() const {
00284         Iter result = m_end;
00285         while( result != m_current && !m_helper.isValid( --result ) );
00286         return m_dereferenceFun( result );
00287     }
00288 
00289 };
00290 
00291 /**
00292  * @brief An unfiltered RangeIterator with a custom dereferencer.
00293  *
00294  * Use this method if you don't want to return just *iter in your next() method. This is useful if you want to iterate
00295  * over the keys of a map where you'd return iter->first in that case.
00296  * The key dereferencer for a std::map with a key type of QString would look something like this:
00297  * <pre><code>
00298     struct KeyDereferencer {
00299         const QString& operator() ( std::map<QString,whatever>::const_iterator& iter ) const {
00300             return (*iter).first;
00301         }
00302     };
00303  * </code></pre>
00304  * A KeyIterator would then look something loke this:
00305  * <pre><code>
00306     typedef itunesdb::utils::DereferencingRangeIterator<QString,std::map<QString,whatever>::const_iterator, KeyDereferencer> KeyIterator;
00307  * </code></pre>
00308  * and its instantiation
00309  * <pre><code>
00310     KeyIterator keyIter( map.begin(), map.end() );
00311  * </code></pre>
00312  * To print out the keys of the map we use the keyIter above like this
00313  * <pre><code>
00314     while( keyIter.hasNext() ) {
00315         printf( "%s\n", keyIter.next().ascii() );
00316     }
00317  * </code></pre>
00318  */
00319 template <typename IterType, typename Iter, typename TDereferenceFun = DefaultDeref<IterType, Iter> >
00320 class DereferencingRangeIterator : public RangeIterator<IterType, Iter, TRUEPredicate, TDereferenceFun> {
00321 public:
00322 
00323     /**
00324      * Creates a DereferencingRangeIterator over the given range.
00325      */
00326     DereferencingRangeIterator( Iter start, Iter end )
00327         : RangeIterator< IterType, Iter, TRUEPredicate, TDereferenceFun >( start, end, TRUEPredicate() )
00328     {
00329     }
00330 };
00331 
00332 
00333 template <class Comparable_T>
00334 class Comparator {
00335 public:
00336     virtual ~Comparator() {}
00337     /**
00338      * Compares the two given comparables and returns a positive, 0 or a negative value
00339      * if the first comparable is greater than, equal to, or less than the second.
00340      * @param c1 the first comparable to compare
00341      * @param c2 the second comparable to compare
00342      * @return a positive, 0 or a negative value if the first comparable is greater than, equal to, or less than the second.
00343      */
00344     virtual int compare( const Comparable_T& c1, const Comparable_T& c2 ) const = 0;
00345 };
00346 
00347 
00348 /**
00349  * A Class implementing a sortable Vector storing pointers to the given Type
00350  */
00351 template <class ElemType>
00352 class SortablePtrVector : protected std::vector<ElemType*> {
00353 
00354     typedef typename std::vector<ElemType*>::iterator PrivateIterator;
00355     typedef typename std::vector<ElemType*>::const_iterator PrivateConstIterator;
00356     typedef std::vector<ElemType*> BaseContainerType;
00357 
00358     unsigned long m_version;
00359 
00360 public:
00361 
00362     /**
00363      * @brief Comparator Type definition
00364      */
00365     typedef Comparator<ElemType> SortableVectorElemComparator;
00366 
00367     /**
00368      * @brief Shared Pointer type managing the pointer to the comparator
00369      */
00370     typedef QTPOD_SHARED_PTR_IMPL_DEF< SortableVectorElemComparator > ComparatorPtr;
00371 
00372      /**
00373      * An Iterator over all elements of this container being aware of changes to the container.
00374      * The Iterator gets invalid if the container got changed outside the control of this iterator.
00375      */
00376     template < typename Container_T, typename Iter_T, typename TUnaryPredicate = TRUEPredicate >
00377     class ContainerVersionAwareIterator : public RangeIterator<ElemType*, Iter_T, TUnaryPredicate > {
00378     protected:
00379 
00380         /**
00381          * @brief The container we iterate over.
00382          *
00383          * We need this to check our version and validity against
00384          */
00385         Container_T& m_container;
00386 
00387         /**
00388          * @brief The version of the container we iterate over.
00389          *
00390          * If this differs from m_container.m_version the iterator gets invalid.
00391          */
00392         unsigned long m_containerversion;
00393 
00394         /**
00395          * @brief The base type of this iterator
00396          */
00397         typedef RangeIterator< ElemType*, Iter_T, TUnaryPredicate > BaseRangeIterator;
00398 
00399         /**
00400          * @brief Creates a new ContainerVersionAwareIterator
00401          *
00402          * The Iterator iterates over all elements in container matching the given predicate.
00403          * The version of the iterator will be checked against the version of the given container
00404          * to check the validity of this Iterator instance.
00405          * @param container the container to iterate over and to check the version against
00406          * @param pred the predicate to match the elements against
00407          */
00408        ContainerVersionAwareIterator( Container_T& container, const TUnaryPredicate& pred = TUnaryPredicate() )
00409             : BaseRangeIterator( container.begin(), container.end(), pred ),
00410               m_container( container ),
00411               m_containerversion( container.m_version ) {}
00412 
00413     public:
00414 
00415         /**
00416          * @brief Returns false if the underlying container got changed outside the control of this iterator, true otherwise.
00417          * @return false if the underlying container got changed outside the control of this iterator.
00418          */
00419         bool isValid() const {
00420             return m_container.m_version == m_containerversion;
00421         }
00422 
00423         /**
00424          * @brief Returns true if there are elements left so the next() may be called to get the next element
00425          * @n This method will always return false if the underlying container got changed and thus this iterator got invalidated.
00426          * @return true if there are elements left so the next() may be called to get the next element
00427          * @overload RangeIterator::hasNext()
00428          */
00429         bool hasNext() const {
00430             return isValid() && BaseRangeIterator::hasNext();
00431         }
00432 
00433     };
00434 
00435    /**
00436      * A non const @c ContainerVersionAwareIterator providing functions to change the underlying container.
00437      */
00438     template < typename TUnaryPredicate = TRUEPredicate >
00439     class FilteredIterator : public ContainerVersionAwareIterator<SortablePtrVector, PrivateIterator, TUnaryPredicate > {
00440         friend class SortablePtrVector;
00441 
00442         typedef ContainerVersionAwareIterator<SortablePtrVector, PrivateIterator, TUnaryPredicate > IteratorBase;
00443 
00444         unsigned long incrementContainerVersion() {
00445             if ( IteratorBase::isValid() ) {
00446                 return IteratorBase::m_containerversion = ++IteratorBase::m_container.m_version;
00447             }
00448             return 0;
00449         }
00450 
00451     public:
00452 
00453         /**
00454          * @brief Creates a new FilteredIterator over all elements in container matching the given predicate.
00455          * @param container the container to iterate over
00456          * @param predicate the predicate to match the elements against
00457          */
00458         FilteredIterator( SortablePtrVector& container, const TUnaryPredicate& predicate = TUnaryPredicate() )
00459             : IteratorBase( container, predicate ) {}
00460 
00461         /**
00462          * Removes the element returned by the last next() call from the container and positions the iterator at the next element.
00463          * @return true if the Iterator is valid and non empty, false otherwise
00464          */
00465         bool remove() {
00466             if ( IteratorBase::empty() || !IteratorBase::isValid() ) {
00467                 return false;
00468             }
00469             incrementContainerVersion();
00470             ElemType * element = IteratorBase::current();
00471             PrivateIterator newpos = IteratorBase::m_container.erase( IteratorBase::currentPos() );
00472             IteratorBase::setRange( newpos, IteratorBase::m_container.end() );
00473             if ( IteratorBase::m_container.m_deleteElements ) {
00474                 delete element;
00475             }
00476             return true;
00477         }
00478 
00479         /**
00480          * Removes the elements from the current position until the end that are part of this RangeIterator.
00481          * For filtered iterators only those elements matching the filter get removed.
00482          * @return true if at least one element got removed
00483          */
00484         bool removeRemaining() {
00485             if ( !IteratorBase::hasNext() ) {
00486                 return false;
00487             }
00488             do {
00489                 IteratorBase::next();
00490                 remove();
00491             } while ( IteratorBase::hasNext() );
00492             return true;
00493         }
00494     };
00495 
00496     /**
00497      * An unfiltered Iterator over all elements of this container.
00498      */
00499     typedef FilteredIterator<> Iterator;
00500 
00501     /**
00502      * A filtered const Iterator over the elements of this container where the given predicate returned true.
00503      * @see @c RangeIterator for more details
00504      */
00505     template < typename TUnaryPredicate = TRUEPredicate >
00506     struct FilteredConstIterator : public ContainerVersionAwareIterator<const SortablePtrVector, PrivateConstIterator, TUnaryPredicate > {
00507         friend class SortablePtrVector;
00508 
00509         /**
00510          * @brief Creates a new FilteredConstIterator over all elements in container matching the given predicate.
00511          * @param container the container to iterator over
00512          * @param predicate the predicate to match the elements against
00513          */
00514         FilteredConstIterator( const SortablePtrVector& container, const TUnaryPredicate& predicate = TUnaryPredicate() )
00515             : ContainerVersionAwareIterator<const SortablePtrVector, PrivateConstIterator, TUnaryPredicate >( container, predicate ) {}
00516     };
00517 
00518     /**
00519      * A const Iterator over all elements of this container.
00520      * @see @c RangeIterator for more details
00521      */
00522     typedef FilteredConstIterator<> ConstIterator;
00523 
00524 private:
00525     bool m_deleteElements;
00526     ComparatorPtr m_comparator;
00527 
00528 public:
00529     /**
00530      * Creates a sortable vector storing pointers to its elements.
00531      * @param deleteElements if true the container will delete elements being removed from this container.
00532      */
00533     SortablePtrVector( bool deleteElements = false )
00534         : BaseContainerType(), m_version( 0 ), m_deleteElements( deleteElements ) {}
00535 
00536     /**
00537      * @brief Creates a sortable vector storing pointers to its elements and fills in the objects returned by the given iterator.
00538      * @param elements the elements to be filled in to the container
00539      * @param deleteElements if true the container will delete elements being removed from this container.
00540      */
00541     template < typename IterT >
00542     SortablePtrVector( IterT elements, bool deleteElements = false )
00543         : BaseContainerType(), m_version( 0 ), m_deleteElements( deleteElements )
00544     {
00545         addAll( elements );
00546     }
00547 
00548     virtual ~SortablePtrVector() {
00549         clear();
00550     }
00551 
00552     /**
00553      * @brief Sets the comparator for this container to by used by sort() and inSort()
00554      * @param comparator the comparator to be set. The pointer is owned by the container and will be deleted if a new comparator is set.
00555      */
00556     void setComparator( SortableVectorElemComparator * comparator ) {
00557         m_comparator = ComparatorPtr( comparator );
00558     }
00559 
00560     /**
00561      * @brief Sets the comparator for this container to by used by sort() and inSort()
00562      * @param comparator the comparator to be set. The comparators lifecycle is managed by the ComparatorPtr.
00563      */
00564     void setComparator( const ComparatorPtr& comparator ) {
00565         m_comparator = comparator;
00566     }
00567 
00568     /**
00569      * @brief Returns the currently used comparator for sorting.
00570      * @return the currently used comparator for sorting.
00571      */
00572     const ComparatorPtr& getComparator() const {
00573         return m_comparator;
00574     }
00575 
00576     /**
00577      * @brief Sorts the containers element using the comparator set by setComparator().
00578      *
00579      * If no comparator has been set the order is kept unchanged.
00580      */
00581     void sort() {
00582         if ( m_comparator ) {
00583             ++m_version;    // invalidate iterators
00584             std::sort( BaseContainerType::begin(), BaseContainerType::end(), SmallerBinaryPredicate( m_comparator ) );
00585         }   // else leave it as it is
00586     }
00587 
00588     /**
00589      * @brief Randomizes the order of the elements.
00590      */
00591     void randomize() {
00592         ++m_version;    // invalidate iterators
00593         std::random_shuffle( BaseContainerType::begin(), BaseContainerType::end() );
00594     }
00595 
00596     struct SmallerBinaryPredicate {
00597         ComparatorPtr m_comparator;
00598         SmallerBinaryPredicate( ComparatorPtr& ptr ) : m_comparator( ptr ) {}
00599         bool operator() ( const ElemType * i1, const ElemType * i2 ) {
00600             return m_comparator->compare( *i1, *i2 ) < 0;
00601         }
00602     };
00603     struct FindFirstNotLessThan {
00604         SmallerBinaryPredicate& m_predicate;
00605         ElemType * m_item;
00606         FindFirstNotLessThan( SmallerBinaryPredicate& pred, ElemType * item )
00607             : m_predicate( pred ), m_item( item ) {}
00608         bool operator() ( const ElemType * i ) {
00609             return m_predicate( m_item, i );
00610         }
00611     };
00612     /**
00613      * @brief Inserts the given element accordingly to the comparator set by setComparator().
00614      *
00615      * If no comparator has been set the element will be appended at the end.
00616      * @param item the element to be inserted
00617      * @return the position/index of the item in this vector.
00618      */
00619     unsigned int inSort( ElemType * item ) {
00620         unsigned int idx = 0;
00621 
00622         ++m_version;
00623 
00624         if ( !m_comparator ) {
00625             idx = BaseContainerType::size();
00626             BaseContainerType::push_back( item );
00627             return idx;
00628         }
00629 
00630         SmallerBinaryPredicate pred( m_comparator );
00631         FindFirstNotLessThan finder( pred, item );
00632 
00633         PrivateIterator pos = std::find_if( BaseContainerType::begin(), BaseContainerType::end(), finder );
00634         if ( pos == BaseContainerType::end() ) {
00635             idx = BaseContainerType::size();
00636             BaseContainerType::push_back( item );
00637         } else {
00638             idx = pos - BaseContainerType::begin();
00639             BaseContainerType::insert( pos, item );
00640         }
00641 
00642         return idx;
00643     }
00644 
00645 
00646     /**
00647      * @brief Adds all elements delivered by the given Iterator.
00648      */
00649     template <typename IterT>
00650         void addAll( IterT elemIter ) {
00651             while ( elemIter.hasNext() ) {
00652                 append( elemIter.next() );
00653             }
00654         }
00655 
00656     /**
00657      * @brief Removes the element at the given position from the container.
00658      *
00659      * If the container was created with deleteElements set to true the element will be deleted.
00660      * @param pos the position of the element to be removed.
00661      * @return true if the given position was valid accordingly to the number of elements.
00662      */
00663     bool remove( unsigned int pos ) {
00664         if ( pos > BaseContainerType::size() -1 ) {
00665             return false;
00666         }
00667 
00668         ++m_version;
00669 
00670         PrivateIterator posIter = BaseContainerType::begin() + pos;
00671         if ( m_deleteElements ) {
00672             delete *posIter;
00673         }
00674         erase( posIter );
00675 
00676         return true;
00677     }
00678 
00679     /**
00680      * @brief Returns the number of elements,
00681      * @return the number of elements,
00682      */
00683     unsigned int count() const { return BaseContainerType::size(); }
00684 
00685     /**
00686      * @brief Returns true if the number of elements is zero meaning the container is empty, false otherwise.
00687      * @return true if the container is empty.
00688      */
00689     bool isEmpty() const { return BaseContainerType::empty(); }
00690 
00691     /**
00692      * @brief Returns a @c SortablePtrVector::Iterator over all elements of this Container
00693      * @return a @c SortablePtrVector::Iterator over all elements of this Container
00694      */
00695     Iterator iterator() { return Iterator ( *this ); }
00696 
00697     /**
00698      * @brief Returns a @c SortablePtrVector::ConstIterator over all elements of this Container
00699      * @return a @c SortablePtrVector::ConstIterator over all elements of this Container
00700      */
00701     ConstIterator iterator() const { return ConstIterator( *this ); }
00702 
00703     /**
00704      * @brief Returns a @c SortablePtrVector::ConstIterator over all elements of this Container
00705      * @return a @c SortablePtrVector::ConstIterator over all elements of this Container
00706      */
00707     ConstIterator const_iterator() const { return ConstIterator( *this ); }
00708 
00709     /**
00710      * @brief Returns a FilteredIterator over those elements matching the given predicate.
00711      * @param pred the predicate used for filtering
00712      * @return a filtered Iterator over the elements of this container.
00713      */
00714     template <typename TUnaryPredicate>
00715     FilteredIterator<TUnaryPredicate> filteredElements( const TUnaryPredicate& pred ) {
00716         return FilteredIterator<TUnaryPredicate>( *this, pred );
00717     }
00718 
00719     /**
00720      * @brief Returns a FilteredConstIterator over those elements matching the given predicate.
00721      * @param pred the predicate used for filtering
00722      * @return a filtered const Iterator over the elements of this container.
00723      */
00724     template <typename TUnaryPredicate>
00725     FilteredConstIterator<TUnaryPredicate> filteredElements( const TUnaryPredicate& pred ) const {
00726         return FilteredConstIterator<TUnaryPredicate>( *this, pred );
00727     }
00728 
00729     /**
00730      * @brief Appends the given element at the end of the container disregarding any comparator.
00731      * @param item the element to be appended.
00732      */
00733     void append( ElemType * item ) { BaseContainerType::push_back( item ); }
00734 
00735     /**
00736      * @brief An operator to access the element at the given position.
00737      * @param pos the position of the element to be returned
00738      * @return a pointer to the element at the given position
00739      */
00740     ElemType * operator[] ( unsigned int pos ) const {
00741         return BaseContainerType::operator[] ( pos );
00742     }
00743 
00744     /**
00745      * @brief An operator to access the element at the given position.
00746      * @param pos the position of the element to be returned
00747      * @return a reference to the pointer at the given position
00748      */
00749     ElemType *& operator[] ( unsigned int pos ) {
00750         return BaseContainerType::operator[] ( pos );
00751     }
00752 
00753     /**
00754      * @brief Returns a pointer to the last element.
00755      * @return a pointer to the last element.
00756      */
00757     ElemType * last() const {
00758         return BaseContainerType::back();
00759     }
00760 
00761     /**
00762      * @brief Removes all elements.
00763      */
00764     void clear() {
00765 #if 0
00766         // FIXME remove iterator testcode before release
00767         iterator().removeRemaining();
00768         printf( "%d number of items left after clear\n" , count() );
00769 #else
00770         if ( m_deleteElements ) {
00771             PrivateIterator iter = BaseContainerType::begin();
00772             for ( ; iter != BaseContainerType::end(); ++iter ) {
00773                 delete *iter;
00774             }
00775         }
00776         BaseContainerType::clear();
00777 #endif
00778     }
00779 };
00780 
00781 
00782 /**
00783  * @brief inherit from this to get a non copyable class
00784  */
00785 class NonCopyAble {
00786 private:
00787     NonCopyAble( const NonCopyAble& ) {}
00788 protected:
00789     NonCopyAble() {}
00790 public:
00791     virtual ~NonCopyAble() {}
00792 };
00793 
00794 
00795 /**
00796  * @brief Seeks the given number of bytes in the given stream
00797  */
00798 template <class Stream_T>
00799 inline void seekRelative( Stream_T& stream, unsigned int numbytes ) {
00800     if ( numbytes > 0 ) {
00801         char * buffer = new char[ numbytes ];
00802         stream.readRawBytes( buffer, numbytes );
00803         delete [] buffer;
00804     }
00805 }
00806 
00807 
00808 } // utils
00809 
00810 } // itunesdb
00811 
00812 #endif

Generated on Wed Nov 28 03:04:38 2007 for libqtpod by  doxygen 1.5.0