OpenWalnut 1.3.1
|
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