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