OpenWalnut  1.3.1
WSharedSequenceContainer.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WSHAREDSEQUENCECONTAINER_H
26 #define WSHAREDSEQUENCECONTAINER_H
27 
28 #include <algorithm>
29 
30 #include <boost/thread.hpp>
31 
32 #include "WSharedObject.h"
33 
34 /**
35  * This class provides a common interface for thread-safe access to sequence containers (list, vector, dequeue ).
36  * \param S the sequence container to use. Everything is allowed here which provides push_back and pop_back as well as size functionality.
37  */
38 template < typename S >
40 {
41 public:
42  // Some helpful typedefs
43 
44  /**
45  * A typedef for the correct const iterator useful to traverse this sequence container.
46  */
47  typedef typename S::const_iterator ConstIterator;
48 
49  /**
50  * A typedef for the correct iterator to traverse this sequence container.
51  */
52  typedef typename S::iterator Iterator;
53 
54  /**
55  * The type of the elements
56  */
57  typedef typename S::value_type value_type;
58 
59  /**
60  * Default constructor.
61  */
63 
64  /**
65  * Destructor.
66  */
67  virtual ~WSharedSequenceContainer();
68 
69  //////////////////////////////////////////////////////////////////////////////////////////
70  // These methods implement common methods of all sequence containers. The list is not
71  // complete but should be enough for now.
72  // \NOTE: all methods using or returning iterators are NOT implemented here. Use the access
73  // Object (getAccessObject) to iterate.
74  //////////////////////////////////////////////////////////////////////////////////////////
75 
76  /**
77  * Adds a new element at the end of the container.
78  *
79  * \param x the new element.
80  */
81  void push_back( const typename S::value_type& x );
82 
83  /**
84  * Adds a new element at the beginning of the container.
85  *
86  * \param x the new element.
87  */
88  void push_front( const typename S::value_type& x );
89 
90  /**
91  * Removes an element from the end.
92  */
93  void pop_back();
94 
95  /**
96  * Clears the container.
97  */
98  void clear();
99 
100  /**
101  * The size of the container.
102  *
103  * \return the size.
104  *
105  * \note: be aware that the size can change at every moment after getting the size, since the read lock got freed. Better use
106  * access objects to lock the container and use size() on the container directly.
107  */
108  size_t size() const;
109 
110  /**
111  * Get item at position n. Uses the [] operator of the underlying container. Please do not use this for iteration as it locks every access.
112  * Use iterators and read/write tickets for fast iteration.
113  *
114  * \param n the item index
115  *
116  * \return reference to element at the specified position
117  */
118  typename S::value_type& operator[]( size_t n );
119 
120  /**
121  * Get item at position n. Uses the [] operator of the underlying container. Please do not use this for iteration as it locks every access.
122  * Use iterators and read/write tickets for fast iteration.
123  *
124  * \param n the item index
125  *
126  * \return reference to element at the specified position
127  */
128  const typename S::value_type& operator[]( size_t n ) const;
129 
130  /**
131  * 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.
132  * Use iterators and read/write tickets for fast iteration.
133  *
134  * \param n the item index
135  *
136  * \return reference to element at the specified position
137  */
138  typename S::value_type& at( size_t n );
139 
140  /**
141  * 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.
142  * Use iterators and read/write tickets for fast iteration.
143  *
144  * \param n the item index
145  *
146  * \return reference to element at the specified position
147  */
148  const typename S::value_type& at( size_t n ) const;
149 
150  /**
151  * Searches and removes the specified element. If it is not found, nothing happens. It mainly is a comfortable forwarder for std::remove and
152  * S::erase.
153  *
154  * \param element the element to remove
155  */
156  void remove( const typename S::value_type& element );
157 
158  /**
159  * Erase the element at the specified position. Read your STL reference for more details.
160  *
161  * \param position where to erase
162  *
163  * \return A random access iterator pointing to the new location of the element that followed the last element erased by the function call.
164  */
166 
167  /**
168  * Erase the specified range of elements. Read your STL reference for more details.
169  *
170  * \param first Iterators specifying a range within the vector to be removed: [first,last).
171  * \param last Iterators specifying a range within the vector to be removed: [first,last).
172  *
173  * \return A random access iterator pointing to the new location of the element that followed the last element erased by the function call.
174  */
177 
178  /**
179  * Replaces the specified old value by a new one. If the old one does not exist, nothing happens. This is a comfortable forwarder for
180  * std::replace.
181  *
182  * \param oldValue the old value to replace
183  * \param newValue the new value
184  */
185  void replace( const typename S::value_type& oldValue, const typename S::value_type& newValue );
186 
187  /**
188  * Counts the number of occurrences of the specified value inside the container. This is a comfortable forwarder for std::count.
189  *
190  * \param value the value to count
191  *
192  * \return the number of items found.
193  */
194  size_t count( const value_type& value );
195 
196  /**
197  * Resorts the container using the specified comparator from its begin to its end.
198  *
199  * \tparam Comparator the comparator type. Usually a boost::function or class providing the operator().
200  *
201  * \param comp the comparator
202  */
203  template < typename Comparator >
204  void sort( Comparator comp );
205 
206  /**
207  * Resorts the container using the specified comparator between [first,last) in ascending order.
208  *
209  * \param first the first element
210  * \param last the last element
211  * \param comp the comparator
212  */
213  template < typename Comparator >
214  void sort( typename WSharedSequenceContainer< S >::Iterator first, typename WSharedSequenceContainer< S >::Iterator last, Comparator comp );
215 
216  /**
217  * Searches the specified value in the range [first,last).
218  *
219  * \param first the first element
220  * \param last the last element
221  * \param value the value to search.
222  *
223  * \return the iterator pointing to the found element.
224  */
227  const typename S::value_type& value );
228 
229  /**
230  * Searches the specified value in the range [begin,end).
231  *
232  * \param value the value to search.
233  *
234  * \return the iterator pointing to the found element.
235  */
236  typename WSharedSequenceContainer< S >::ConstIterator find( const typename S::value_type& value );
237 
238 protected:
239 private:
240 };
241 
242 template < typename S >
244  WSharedObject< S >()
245 {
246  // init members
247 }
248 
249 template < typename S >
251 {
252  // clean up
253 }
254 
255 template < typename S >
256 void WSharedSequenceContainer< S >::push_back( const typename S::value_type& x )
257 {
258  // Lock, if "a" looses focus -> look is freed
260  a->get().push_back( x );
261 }
262 
263 template < typename S >
264 void WSharedSequenceContainer< S >::push_front( const typename S::value_type& x )
265 {
266  // Lock, if "a" looses focus -> look is freed
268  a->get().insert( a->get().begin(), x );
269 }
270 
271 template < typename S >
273 {
274  // Lock, if "a" looses focus -> look is freed
276  a->get().pop_back();
277 }
278 
279 template < typename S >
281 {
282  // Lock, if "a" looses focus -> look is freed
284  a->get().clear();
285 }
286 
287 template < typename S >
289 {
290  // Lock, if "a" looses focus -> look is freed
292  size_t size = a->get().size();
293  return size;
294 }
295 
296 template < typename S >
297 typename S::value_type& WSharedSequenceContainer< S >::operator[]( size_t n )
298 {
300  return const_cast< S& >( a->get() ).operator[]( n ); // read tickets return the handled object const. This is bad here although in most cases
301  // it is useful and needed.
302 }
303 
304 template < typename S >
305 const typename S::value_type& WSharedSequenceContainer< S >::operator[]( size_t n ) const
306 {
308  return a->get().operator[]( n );
309 }
310 
311 template < typename S >
312 typename S::value_type& WSharedSequenceContainer< S >::at( size_t n )
313 {
315  return const_cast< S& >( a->get() ).at( n ); // read tickets return the handled object const. This is bad here although in most cases it
316  // is useful and needed.
317 }
318 
319 template < typename S >
320 const typename S::value_type& WSharedSequenceContainer< S >::at( size_t n ) const
321 {
323  return a->get().at( n );
324 }
325 
326 template < typename S >
327 void WSharedSequenceContainer< S >::remove( const typename S::value_type& element )
328 {
329  // Lock, if "a" looses focus -> look is freed
331  a->get().erase( std::remove( a->get().begin(), a->get().end(), element ), a->get().end() );
332 }
333 
334 template < typename S >
336 {
337  // Lock, if "a" looses focus -> look is freed
339  return a->get().erase( position );
340 }
341 
342 template < typename S >
346 {
347  // Lock, if "a" looses focus -> look is freed
349  return a->get().erase( first, last );
350 }
351 
352 template < typename S >
353 void WSharedSequenceContainer< S >::replace( const typename S::value_type& oldValue, const typename S::value_type& newValue )
354 {
356  std::replace( a->get().begin(), a->get().end(), oldValue, newValue );
357 }
358 
359 template < typename S >
361 {
363  return std::count( a->get().begin(), a->get().end(), value );
364 }
365 
366 template < typename S >
367 template < typename Comparator >
368 void WSharedSequenceContainer< S >::sort( Comparator comp )
369 {
371  return std::sort( a->get().begin(), a->get().end(), comp );
372 }
373 
374 template < typename S >
375 template < typename Comparator >
378  Comparator comp )
379 {
380  return std::sort( first, last, comp );
381 }
382 
383 template < typename S >
387  const typename S::value_type& value )
388 {
389  return std::find( first, last, value );
390 }
391 
392 template < typename S >
394 {
396  return std::find( a->get().begin(), a->get().end(), value );
397 }
398 
399 #endif // WSHAREDSEQUENCECONTAINER_H
400