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