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

Generated on Wed Dec 19 00:15:19 2007 for libqtpod by  doxygen 1.5.0