WSharedSequenceContainer.h

00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WSHAREDSEQUENCECONTAINER_H
00026 #define WSHAREDSEQUENCECONTAINER_H
00027 
00028 #include <algorithm>
00029 
00030 #include <boost/thread.hpp>
00031 
00032 #include "WSharedObject.h"
00033 
00034 /**
00035  * This class provides a common interface for thread-safe access to sequence containers (list, vector, dequeue ).
00036  * \param S the sequence container to use. Everything is allowed here which provides push_back and pop_back as well as size functionality.
00037  */
00038 template < typename S >
00039 class WSharedSequenceContainer: public WSharedObject< S >
00040 {
00041 public:
00042 
00043     // Some helpful typedefs
00044 
00045     /**
00046      * A typedef for the correct const iterator useful to traverse this sequence container.
00047      */
00048     typedef typename S::const_iterator   ConstIterator;
00049 
00050     /**
00051      * A typedef for the correct iterator to traverse this sequence container.
00052      */
00053     typedef typename S::iterator         Iterator;
00054 
00055     /**
00056      * The type of the elements
00057      */
00058     typedef typename S::value_type value_type;
00059 
00060     /**
00061      * Default constructor.
00062      */
00063     WSharedSequenceContainer();
00064 
00065     /**
00066      * Destructor.
00067      */
00068     virtual ~WSharedSequenceContainer();
00069 
00070     //////////////////////////////////////////////////////////////////////////////////////////
00071     // These methods implement common methods of all sequence containers. The list is not
00072     // complete but should be enough for now.
00073     // \NOTE: all methods using or returning iterators are NOT implemented here. Use the access
00074     // Object (getAccessObject) to iterate.
00075     //////////////////////////////////////////////////////////////////////////////////////////
00076 
00077     /**
00078      * Adds a new element at the end of the container.
00079      *
00080      * \param x the new element.
00081      */
00082     void push_back( const typename S::value_type& x );
00083 
00084     /**
00085      * Adds a new element at the beginning of the container.
00086      *
00087      * \param x the new element.
00088      */
00089     void push_front( const typename S::value_type& x );
00090 
00091     /**
00092      * Removes an element from the end.
00093      */
00094     void pop_back();
00095 
00096     /**
00097      * Clears the container.
00098      */
00099     void clear();
00100 
00101     /**
00102      * The size of the container.
00103      *
00104      * \return the size.
00105      *
00106      * \note: be aware that the size can change at every moment after getting the size, since the read lock got freed. Better use
00107      * access objects to lock the container and use size() on the container directly.
00108      */
00109     size_t size() const;
00110 
00111     /**
00112      * Get item at position n. Uses the [] operator of the underlying container. Please do not use this for iteration as it locks every access.
00113      * Use iterators and read/write tickets for fast iteration.
00114      *
00115      * \param n the item index
00116      *
00117      * \return reference to element at the specified position
00118      */
00119     typename S::value_type& operator[]( size_t n );
00120 
00121     /**
00122      * Get item at position n. Uses the [] operator of the underlying container. Please do not use this for iteration as it locks every access.
00123      * Use iterators and read/write tickets for fast iteration.
00124      *
00125      * \param n the item index
00126      *
00127      * \return reference to element at the specified position
00128      */
00129     const typename S::value_type& operator[]( size_t n ) const;
00130 
00131     /**
00132      * Get item at position n. Uses the at-method of the underlying container. Please do not use this for iteration as it locks every access.
00133      * Use iterators and read/write tickets for fast iteration.
00134      *
00135      * \param n the item index
00136      *
00137      * \return reference to element at the specified position
00138      */
00139     typename S::value_type& at( size_t n );
00140 
00141     /**
00142      * Get item at position n. Uses the at-method of the underlying container. Please do not use this for iteration as it locks every access.
00143      * Use iterators and read/write tickets for fast iteration.
00144      *
00145      * \param n the item index
00146      *
00147      * \return reference to element at the specified position
00148      */
00149     const typename S::value_type& at( size_t n ) const;
00150 
00151     /**
00152      * Searches and removes the specified element. If it is not found, nothing happens. It mainly is a comfortable forwarder for std::remove and
00153      * S::erase.
00154      *
00155      * \param element the element to remove
00156      */
00157     void remove( const typename S::value_type& element );
00158 
00159     /**
00160      * Erase the element at the specified position. Read your STL reference for more details.
00161      *
00162      * \param position where to erase
00163      *
00164      * \return A random access iterator pointing to the new location of the element that followed the last element erased by the function call.
00165      */
00166     typename WSharedSequenceContainer< S >::Iterator erase( typename WSharedSequenceContainer< S >::Iterator position );
00167 
00168     /**
00169      * Erase the specified range of elements. Read your STL reference for more details.
00170      *
00171      * \param first Iterators specifying a range within the vector to be removed: [first,last).
00172      * \param last Iterators specifying a range within the vector to be removed: [first,last).
00173      *
00174      * \return A random access iterator pointing to the new location of the element that followed the last element erased by the function call.
00175      */
00176     typename WSharedSequenceContainer< S >::Iterator erase( typename WSharedSequenceContainer< S >::Iterator first,
00177                                                             typename WSharedSequenceContainer< S >::Iterator last );
00178 
00179     /**
00180      * Replaces the specified old value by a new one. If the old one does not exist, nothing happens. This is a comfortable forwarder for
00181      * std::replace.
00182      *
00183      * \param oldValue the old value to replace
00184      * \param newValue the new value
00185      */
00186     void replace( const typename S::value_type& oldValue, const typename S::value_type& newValue );
00187 
00188     /**
00189      * Counts the number of occurrences of the specified value inside the container. This is a comfortable forwarder for std::count.
00190      *
00191      * \param value the value to count
00192      *
00193      * \return the number of items found.
00194      */
00195     size_t count( const value_type& value );
00196 
00197     /**
00198      * Resorts the container using the specified comparator from its begin to its end.
00199      *
00200      * \tparam Comparator the comparator type. Usually a boost::function or class providing the operator().
00201      *
00202      * \param comp the comparator
00203      */
00204     template < typename Comparator >
00205     void sort( Comparator comp );
00206 
00207     /**
00208      * Resorts the container using the specified comparator between [first,last) in ascending order.
00209      *
00210      * \param first the first element
00211      * \param last the last element
00212      * \param comp the comparator
00213      */
00214     template < typename Comparator >
00215     void sort( typename WSharedSequenceContainer< S >::Iterator first, typename WSharedSequenceContainer< S >::Iterator last, Comparator comp );
00216 
00217     /**
00218      * Searches the specified value in the range [first,last).
00219      *
00220      * \param first the first element
00221      * \param last the last element
00222      * \param value the value to search.
00223      *
00224      * \return the iterator pointing to the found element.
00225      */
00226     typename WSharedSequenceContainer< S >::Iterator find( typename WSharedSequenceContainer< S >::Iterator first,
00227                                                            typename WSharedSequenceContainer< S >::Iterator last,
00228                                                            const typename S::value_type& value );
00229 
00230     /**
00231      * Searches the specified value in the range [begin,end).
00232      *
00233      * \param value the value to search.
00234      *
00235      * \return the iterator pointing to the found element.
00236      */
00237     typename WSharedSequenceContainer< S >::ConstIterator find( const typename S::value_type& value );
00238 
00239 protected:
00240 
00241 private:
00242 };
00243 
00244 template < typename S >
00245 WSharedSequenceContainer< S >::WSharedSequenceContainer():
00246     WSharedObject< S >()
00247 {
00248     // init members
00249 }
00250 
00251 template < typename S >
00252 WSharedSequenceContainer< S >::~WSharedSequenceContainer()
00253 {
00254     // clean up
00255 }
00256 
00257 template < typename S >
00258 void WSharedSequenceContainer< S >::push_back( const typename S::value_type& x )
00259 {
00260     // Lock, if "a" looses focus -> look is freed
00261     typename WSharedObject< S >::WriteTicket a = WSharedObject< S >::getWriteTicket();
00262     a->get().push_back( x );
00263 }
00264 
00265 template < typename S >
00266 void WSharedSequenceContainer< S >::push_front( const typename S::value_type& x )
00267 {
00268     // Lock, if "a" looses focus -> look is freed
00269     typename WSharedObject< S >::WriteTicket a = WSharedObject< S >::getWriteTicket();
00270     a->get().insert( a->get().begin(), x );
00271 }
00272 
00273 template < typename S >
00274 void WSharedSequenceContainer< S >::pop_back()
00275 {
00276     // Lock, if "a" looses focus -> look is freed
00277     typename WSharedObject< S >::WriteTicket a = WSharedObject< S >::getWriteTicket();
00278     a->get().pop_back();
00279 }
00280 
00281 template < typename S >
00282 void WSharedSequenceContainer< S >::clear()
00283 {
00284     // Lock, if "a" looses focus -> look is freed
00285     typename WSharedObject< S >::WriteTicket a = WSharedObject< S >::getWriteTicket();
00286     a->get().clear();
00287 }
00288 
00289 template < typename S >
00290 size_t WSharedSequenceContainer< S >::size() const
00291 {
00292     // Lock, if "a" looses focus -> look is freed
00293     typename WSharedObject< S >::ReadTicket a = WSharedObject< S >::getReadTicket();
00294     size_t size = a->get().size();
00295     return size;
00296 }
00297 
00298 template < typename S >
00299 typename S::value_type& WSharedSequenceContainer< S >::operator[]( size_t n )
00300 {
00301     typename WSharedObject< S >::ReadTicket a = WSharedObject< S >::getReadTicket();
00302     return const_cast< S& >( a->get() ).operator[]( n );    // read tickets return the handled object const. This is bad here although in most cases
00303     // it is useful and needed.
00304 }
00305 
00306 template < typename S >
00307 const typename S::value_type& WSharedSequenceContainer< S >::operator[]( size_t n ) const
00308 {
00309     typename WSharedObject< S >::ReadTicket a = WSharedObject< S >::getReadTicket();
00310     return a->get().operator[]( n );
00311 }
00312 
00313 template < typename S >
00314 typename S::value_type& WSharedSequenceContainer< S >::at( size_t n )
00315 {
00316     typename WSharedObject< S >::ReadTicket a = WSharedObject< S >::getReadTicket();
00317     return const_cast< S& >( a->get() ).at( n );    // read tickets return the handled object const. This is bad here although in most cases it
00318     // is useful and needed.
00319 }
00320 
00321 template < typename S >
00322 const typename S::value_type& WSharedSequenceContainer< S >::at( size_t n ) const
00323 {
00324     typename WSharedObject< S >::ReadTicket a = WSharedObject< S >::getReadTicket();
00325     return a->get().at( n );
00326 }
00327 
00328 template < typename S >
00329 void WSharedSequenceContainer< S >::remove( const typename S::value_type& element )
00330 {
00331     // Lock, if "a" looses focus -> look is freed
00332     typename WSharedObject< S >::WriteTicket a = WSharedObject< S >::getWriteTicket();
00333     a->get().erase( std::remove( a->get().begin(), a->get().end(), element ), a->get().end() );
00334 }
00335 
00336 template < typename S >
00337 typename WSharedSequenceContainer< S >::Iterator WSharedSequenceContainer< S >::erase( typename WSharedSequenceContainer< S >::Iterator position )
00338 {
00339     // Lock, if "a" looses focus -> look is freed
00340     typename WSharedObject< S >::WriteTicket a = WSharedObject< S >::getWriteTicket();
00341     return a->get().erase( position );
00342 }
00343 
00344 template < typename S >
00345 typename WSharedSequenceContainer< S >::Iterator WSharedSequenceContainer< S >::erase(
00346         typename WSharedSequenceContainer< S >::Iterator first,
00347         typename WSharedSequenceContainer< S >::Iterator last )
00348 {
00349     // Lock, if "a" looses focus -> look is freed
00350     typename WSharedObject< S >::WriteTicket a = WSharedObject< S >::getWriteTicket();
00351     return a->get().erase( first, last );
00352 }
00353 
00354 template < typename S >
00355 void WSharedSequenceContainer< S >::replace( const typename S::value_type& oldValue, const typename S::value_type& newValue )
00356 {
00357     typename WSharedObject< S >::WriteTicket a = WSharedObject< S >::getWriteTicket();
00358     std::replace( a->get().begin(), a->get().end(), oldValue, newValue );
00359 }
00360 
00361 template < typename S >
00362 size_t WSharedSequenceContainer< S >::count( const value_type& value )
00363 {
00364     typename WSharedObject< S >::ReadTicket a = WSharedObject< S >::getReadTicket();
00365     return std::count( a->get().begin(), a->get().end(), value );
00366 }
00367 
00368 template < typename S >
00369 template < typename Comparator >
00370 void WSharedSequenceContainer< S >::sort( Comparator comp )
00371 {
00372     typename WSharedObject< S >::WriteTicket a = WSharedObject< S >::getWriteTicket();
00373     return std::sort( a->get().begin(), a->get().end(), comp );
00374 }
00375 
00376 template < typename S >
00377 template < typename Comparator >
00378 void WSharedSequenceContainer< S >::sort( typename WSharedSequenceContainer< S >::Iterator first,
00379                                           typename WSharedSequenceContainer< S >::Iterator last,
00380                                           Comparator comp )
00381 {
00382     return std::sort( first, last, comp );
00383 }
00384 
00385 template < typename S >
00386 typename WSharedSequenceContainer< S >::Iterator WSharedSequenceContainer< S >::find(
00387         typename WSharedSequenceContainer< S >::Iterator first,
00388         typename WSharedSequenceContainer< S >::Iterator last,
00389         const typename S::value_type& value )
00390 {
00391     return std::find( first, last, value );
00392 }
00393 
00394 template < typename S >
00395 typename WSharedSequenceContainer< S >::ConstIterator WSharedSequenceContainer< S >::find( const typename S::value_type& value )
00396 {
00397     typename WSharedObject< S >::ReadTicket a = WSharedObject< S >::getReadTicket();
00398     return std::find( a->get().begin(), a->get().end(), value );
00399 }
00400 
00401 #endif  // WSHAREDSEQUENCECONTAINER_H
00402 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends