OpenWalnut  1.5.0dev
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  */
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  * Add the element only if it is not inside the container until now. This is a shortcut to a combined used of find and push_back.
97  *
98  * \param x the element to push back.
99  */
100  void unique_push_back( const typename S::value_type& x );
101 
102  /**
103  * Add the element only if it is not inside the container until now. This is a shortcut to a combined used of find and push_front.
104  *
105  * \param x the element to push front.
106  */
107  void unique_push_front( const typename S::value_type& x );
108 
109  /**
110  * Clears the container.
111  */
112  void clear();
113 
114  /**
115  * The size of the container.
116  *
117  * \return the size.
118  *
119  * \note: be aware that the size can change at every moment after getting the size, since the read lock got freed. Better use
120  * access objects to lock the container and use size() on the container directly.
121  */
122  size_t size() const;
123 
124  /**
125  * Get item at position n. Uses the [] operator of the underlying container. Please do not use this for iteration as it locks every access.
126  * Use iterators and read/write tickets for fast iteration.
127  *
128  * \param n the item index
129  *
130  * \return reference to element at the specified position
131  */
132  typename S::value_type& operator[]( size_t n );
133 
134  /**
135  * Get item at position n. Uses the [] operator of the underlying container. Please do not use this for iteration as it locks every access.
136  * Use iterators and read/write tickets for fast iteration.
137  *
138  * \param n the item index
139  *
140  * \return reference to element at the specified position
141  */
142  const typename S::value_type& operator[]( size_t n ) const;
143 
144  /**
145  * 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.
146  * Use iterators and read/write tickets for fast iteration.
147  *
148  * \param n the item index
149  *
150  * \return reference to element at the specified position
151  */
152  typename S::value_type& at( size_t n );
153 
154  /**
155  * 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.
156  * Use iterators and read/write tickets for fast iteration.
157  *
158  * \param n the item index
159  *
160  * \return reference to element at the specified position
161  */
162  const typename S::value_type& at( size_t n ) const;
163 
164  /**
165  * Searches and removes the specified element. If it is not found, nothing happens. It mainly is a comfortable forwarder for std::remove and
166  * S::erase.
167  *
168  * \param element the element to remove
169  */
170  void remove( const typename S::value_type& element );
171 
172  /**
173  * Erase the element at the specified position. Read your STL reference for more details.
174  *
175  * \param position where to erase
176  *
177  * \return A random access iterator pointing to the new location of the element that followed the last element erased by the function call.
178  */
180 
181  /**
182  * Erase the specified range of elements. Read your STL reference for more details.
183  *
184  * \param first Iterators specifying a range within the vector to be removed: [first,last).
185  * \param last Iterators specifying a range within the vector to be removed: [first,last).
186  *
187  * \return A random access iterator pointing to the new location of the element that followed the last element erased by the function call.
188  */
191 
192  /**
193  * Replaces the specified old value by a new one. If the old one does not exist, nothing happens. This is a comfortable forwarder for
194  * std::replace.
195  *
196  * \param oldValue the old value to replace
197  * \param newValue the new value
198  */
199  void replace( const typename S::value_type& oldValue, const typename S::value_type& newValue );
200 
201  /**
202  * Counts the number of occurrences of the specified value inside the container. This is a comfortable forwarder for std::count.
203  *
204  * \param value the value to count
205  *
206  * \return the number of items found.
207  */
208  size_t count( const value_type& value );
209 
210  /**
211  * Resorts the container using the specified comparator from its begin to its end.
212  *
213  * \tparam Comparator the comparator type. Usually a boost::function or class providing the operator().
214  *
215  * \param comp the comparator
216  */
217  template < typename Comparator >
218  void sort( Comparator comp );
219 
220  /**
221  * Resorts the container using the specified comparator between [first,last) in ascending order.
222  *
223  * \param first the first element
224  * \param last the last element
225  * \param comp the comparator
226  */
227  template < typename Comparator >
228  void sort( typename WSharedSequenceContainer< S >::Iterator first, typename WSharedSequenceContainer< S >::Iterator last, Comparator comp );
229 
230  /**
231  * Resorts the container using the specified comparator from its begin to its end. Uses stable sort algorithm.
232  *
233  * \tparam Comparator the comparator type. Usually a boost::function or class providing the operator().
234  *
235  * \param comp the comparator
236  */
237  template < typename Comparator >
238  void stableSort( Comparator comp );
239 
240  /**
241  * Resorts the container using the specified comparator between [first,last) in ascending order. Uses stable sort algorithm.
242  *
243  * \param first the first element
244  * \param last the last element
245  * \param comp the comparator
246  */
247  template < typename Comparator >
249 
250  /**
251  * Searches the specified value in the range [first,last).
252  *
253  * \param first the first element
254  * \param last the last element
255  * \param value the value to search.
256  *
257  * \return the iterator pointing to the found element.
258  */
261  const typename S::value_type& value );
262 
263  /**
264  * Searches the specified value in the range [begin,end).
265  *
266  * \param value the value to search.
267  *
268  * \return the iterator pointing to the found element.
269  */
270  typename WSharedSequenceContainer< S >::ConstIterator find( const typename S::value_type& value );
271 
272 protected:
273 private:
274 };
275 
276 template < typename S >
278  WSharedObject< S >()
279 {
280  // init members
281 }
282 
283 template < typename S >
285 {
286  // clean up
287 }
288 
289 template < typename S >
290 void WSharedSequenceContainer< S >::push_back( const typename S::value_type& x )
291 {
292  // Lock, if "a" looses focus -> look is freed
294  a->get().push_back( x );
295 }
296 
297 template < typename S >
298 void WSharedSequenceContainer< S >::push_front( const typename S::value_type& x )
299 {
300  // Lock, if "a" looses focus -> look is freed
302  a->get().insert( a->get().begin(), x );
303 }
304 
305 template < typename S >
306 void WSharedSequenceContainer< S >::unique_push_back( const typename S::value_type& x )
307 {
309  WSharedSequenceContainer< S >::Iterator it = std::find( a->get().begin(), a->get().end(), x );
310  if( it == a->get().end() )
311  {
312  // not found -> add
313  a->get().push_back( x );
314  }
315 }
316 
317 template < typename S >
318 void WSharedSequenceContainer< S >::unique_push_front( const typename S::value_type& x )
319 {
321  WSharedSequenceContainer< S >::Iterator it = std::find( a->get().begin(), a->get().end(), x );
322  if( it == a->get().end() )
323  {
324  // not found -> add
325  a->get().insert( a->get().begin(), x );
326  }
327 }
328 
329 template < typename S >
331 {
332  // Lock, if "a" looses focus -> look is freed
334  a->get().pop_back();
335 }
336 
337 template < typename S >
339 {
340  // Lock, if "a" looses focus -> look is freed
342  a->get().clear();
343 }
344 
345 template < typename S >
347 {
348  // Lock, if "a" looses focus -> look is freed
350  size_t size = a->get().size();
351  return size;
352 }
353 
354 template < typename S >
355 typename S::value_type& WSharedSequenceContainer< S >::operator[]( size_t n )
356 {
358  return const_cast< S& >( a->get() ).operator[]( n ); // read tickets return the handled object const. This is bad here although in most cases
359  // it is useful and needed.
360 }
361 
362 template < typename S >
363 const typename S::value_type& WSharedSequenceContainer< S >::operator[]( size_t n ) const
364 {
366  return a->get().operator[]( n );
367 }
368 
369 template < typename S >
370 typename S::value_type& WSharedSequenceContainer< S >::at( size_t n )
371 {
373  return const_cast< S& >( a->get() ).at( n ); // read tickets return the handled object const. This is bad here although in most cases it
374  // is useful and needed.
375 }
376 
377 template < typename S >
378 const typename S::value_type& WSharedSequenceContainer< S >::at( size_t n ) const
379 {
381  return a->get().at( n );
382 }
383 
384 template < typename S >
385 void WSharedSequenceContainer< S >::remove( const typename S::value_type& element )
386 {
387  // Lock, if "a" looses focus -> look is freed
389  a->get().erase( std::remove( a->get().begin(), a->get().end(), element ), a->get().end() );
390 }
391 
392 template < typename S >
394 {
395  // Lock, if "a" looses focus -> look is freed
397  return a->get().erase( position );
398 }
399 
400 template < typename S >
404 {
405  // Lock, if "a" looses focus -> look is freed
407  return a->get().erase( first, last );
408 }
409 
410 template < typename S >
411 void WSharedSequenceContainer< S >::replace( const typename S::value_type& oldValue, const typename S::value_type& newValue )
412 {
414  std::replace( a->get().begin(), a->get().end(), oldValue, newValue );
415 }
416 
417 template < typename S >
419 {
421  return std::count( a->get().begin(), a->get().end(), value );
422 }
423 
424 template < typename S >
425 template < typename Comparator >
426 void WSharedSequenceContainer< S >::sort( Comparator comp )
427 {
429  return std::sort( a->get().begin(), a->get().end(), comp );
430 }
431 
432 template < typename S >
433 template < typename Comparator >
436  Comparator comp )
437 {
438  return std::sort( first, last, comp );
439 }
440 
441 template < typename S >
442 template < typename Comparator >
444 {
446  return std::stable_sort( a->get().begin(), a->get().end(), comp );
447 }
448 
449 template < typename S >
450 template < typename Comparator >
453  Comparator comp )
454 {
455  return std::stable_sort( first, last, comp );
456 }
457 
458 template < typename S >
462  const typename S::value_type& value )
463 {
464  return std::find( first, last, value );
465 }
466 
467 template < typename S >
469 {
471  return std::find( a->get().begin(), a->get().end(), value );
472 }
473 
474 #endif // WSHAREDSEQUENCECONTAINER_H
475 
Wrapper around an object/type for thread safe sharing of objects among multiple threads.
Definition: WSharedObject.h:45
ReadTicket getReadTicket() const
Returns a ticket to get read access to the contained data.
WriteTicket getWriteTicket(bool suppressNotify=false) const
Returns a ticket to get write access to the contained data.
This class provides a common interface for thread-safe access to sequence containers (list,...
WSharedSequenceContainer()
Default constructor.
size_t size() const
The size of the container.
WSharedSequenceContainer< S >::Iterator erase(typename WSharedSequenceContainer< S >::Iterator first, typename WSharedSequenceContainer< S >::Iterator last)
Erase the specified range of elements.
void remove(const typename S::value_type &element)
Searches and removes the specified element.
void unique_push_back(const typename S::value_type &x)
Add the element only if it is not inside the container until now.
const S::value_type & operator[](size_t n) const
Get item at position n.
void sort(typename WSharedSequenceContainer< S >::Iterator first, typename WSharedSequenceContainer< S >::Iterator last, Comparator comp)
Resorts the container using the specified comparator between [first,last) in ascending order.
void pop_back()
Removes an element from the end.
void sort(Comparator comp)
Resorts the container using the specified comparator from its begin to its end.
S::value_type value_type
The type of the elements.
void push_front(const typename S::value_type &x)
Adds a new element at the beginning of the container.
void clear()
Clears the container.
virtual ~WSharedSequenceContainer()
Destructor.
WSharedSequenceContainer< S >::Iterator find(typename WSharedSequenceContainer< S >::Iterator first, typename WSharedSequenceContainer< S >::Iterator last, const typename S::value_type &value)
Searches the specified value in the range [first,last).
void stableSort(Comparator comp)
Resorts the container using the specified comparator from its begin to its end.
void replace(const typename S::value_type &oldValue, const typename S::value_type &newValue)
Replaces the specified old value by a new one.
void push_back(const typename S::value_type &x)
Adds a new element at the end of the container.
const S::value_type & at(size_t n) const
Get item at position n.
size_t count(const value_type &value)
Counts the number of occurrences of the specified value inside the container.
S::value_type & operator[](size_t n)
Get item at position n.
WSharedSequenceContainer< S >::ConstIterator find(const typename S::value_type &value)
Searches the specified value in the range [begin,end).
S::iterator Iterator
A typedef for the correct iterator to traverse this sequence container.
void unique_push_front(const typename S::value_type &x)
Add the element only if it is not inside the container until now.
WSharedSequenceContainer< S >::Iterator erase(typename WSharedSequenceContainer< S >::Iterator position)
Erase the element at the specified position.
S::value_type & at(size_t n)
Get item at position n.
void stableSort(typename WSharedSequenceContainer< S >::Iterator first, typename WSharedSequenceContainer< S >::Iterator last, Comparator comp)
Resorts the container using the specified comparator between [first,last) in ascending order.
S::const_iterator ConstIterator
A typedef for the correct const iterator useful to traverse this sequence container.