managed_list.h
Go to the documentation of this file.
1 /*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2008, Willow Garage, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the Willow Garage nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34 
35 #ifndef ACTIONLIB__MANAGED_LIST_H_
36 #define ACTIONLIB__MANAGED_LIST_H_
37 
39 #include <boost/thread.hpp>
40 #include <boost/shared_ptr.hpp>
41 #include <boost/weak_ptr.hpp>
42 
43 #include <list>
44 
45 #include "ros/console.h"
46 
47 namespace actionlib
48 {
49 
55 template<class T>
56 class ManagedList
57 {
58 private:
59  struct TrackedElem
60  {
61  T elem;
62  boost::weak_ptr<void> handle_tracker_;
63  };
64 
65 public:
66  class Handle;
67 
68  class iterator
69  {
70 public:
71  iterator() {}
72  T & operator*() {return it_->elem; }
73  T & operator->() {return it_->elem; }
74  const T & operator*() const {return it_->elem; }
75  const T & operator->() const {return it_->elem; }
76  bool operator==(const iterator & rhs) const {return it_ == rhs.it_; }
77  bool operator!=(const iterator & rhs) const {return !(*this == rhs); }
78  void operator++() {it_++; }
79  Handle createHandle();
80  friend class ManagedList;
81 
82 private:
83  iterator(typename std::list<TrackedElem>::iterator it)
84  : it_(it) {}
85  typename std::list<TrackedElem>::iterator it_;
86  };
87 
88  typedef typename boost::function<void (iterator)> CustomDeleter;
89 
90 private:
91  class ElemDeleter
92  {
93 public:
96  : it_(it), deleter_(deleter), guard_(guard)
97  {}
98 
99  void operator()(void *)
100  {
102  if (!protector.isProtected()) {
103  ROS_ERROR_NAMED("actionlib",
104  "ManagedList: The DestructionGuard associated with this list has already been destructed. You must delete all list handles before deleting the ManagedList");
105  return;
106  }
107 
108  ROS_DEBUG_NAMED("actionlib", "IN DELETER");
109  if (deleter_) {
110  deleter_(it_);
111  }
112  }
113 
114 private:
115  iterator it_;
118  };
119 
120 public:
121  class Handle
122  {
123 public:
127  Handle()
128  : it_(iterator()), handle_tracker_(boost::shared_ptr<void>()), valid_(false) {}
129 
130  Handle & operator=(const Handle & rhs)
131  {
132  if (rhs.valid_) {
133  it_ = rhs.it_;
134  }
135  handle_tracker_ = rhs.handle_tracker_;
136  valid_ = rhs.valid_;
137  return *this;
138  }
139 
140  Handle(const Handle & rhs)
141  {
142  *this = rhs;
143  }
144 
149  void reset()
150  {
151  valid_ = false;
152 #ifndef _MSC_VER
153  // this prevents a crash on MSVC, but I bet the problem is elsewhere.
154  // it puts the lotion in the basket.
156 #endif
158  }
159 
165  T & getElem()
166  {
167  assert(valid_);
168  if (!valid_) {
169  ROS_ERROR_NAMED("actionlib","getElem() should not see invalid handles");
170  }
171  return *it_;
172  }
173 
174  const T & getElem() const
175  {
176  assert(valid_);
177  if (!valid_) {
178  ROS_ERROR_NAMED("actionlib","getElem() should not see invalid handles");
179  }
180  return *it_;
181  }
182 
186  bool operator==(const Handle & rhs) const
187  {
188  assert(valid_);
189  if (!valid_) {
190  ROS_ERROR_NAMED("actionlib", "operator== should not see invalid handles");
191  }
192  assert(rhs.valid_);
193  if (!rhs.valid_) {
194  ROS_ERROR_NAMED("actionlib", "operator== should not see invalid RHS handles");
195  }
196  return it_ == rhs.it_;
197  }
198 
199  friend class ManagedList;
200  // Need this friend declaration so that iterator::createHandle() can
201  // call the private Handle::Handle() declared below.
202  friend class iterator;
203 
204 private:
205  Handle(const boost::shared_ptr<void> & handle_tracker, iterator it)
206  : it_(it), handle_tracker_(handle_tracker), valid_(true)
207  {}
208 
209  iterator it_;
211  bool valid_;
212  };
213 
214  ManagedList() {}
215 
219  Handle add(const T & elem)
220  {
221  return add(elem, boost::bind(&ManagedList<T>::defaultDeleter, this, boost::placeholders::_1) );
222  }
223 
229  Handle add(const T & elem, CustomDeleter custom_deleter,
231  {
232  TrackedElem tracked_t;
233  tracked_t.elem = elem;
234 
235  typename std::list<TrackedElem>::iterator list_it = list_.insert(list_.end(), tracked_t);
236  iterator managed_it = iterator(list_it);
237 
238  ElemDeleter deleter(managed_it, custom_deleter, guard);
239  boost::shared_ptr<void> tracker(nullptr, deleter);
240 
241  list_it->handle_tracker_ = tracker;
242 
243  return Handle(tracker, managed_it);
244  }
245 
249  void erase(iterator it)
250  {
251  list_.erase(it.it_);
252  }
253 
254  iterator end() {return iterator(list_.end()); }
255  iterator begin() {return iterator(list_.begin()); }
256 
257 private:
258  void defaultDeleter(iterator it)
259  {
260  erase(it);
261  }
262  std::list<TrackedElem> list_;
263 };
264 
265 
266 template<class T>
268  if (it_->handle_tracker_.expired()) {
269  ROS_ERROR_NAMED("actionlib", "Tried to create a handle to a list elem with refcount 0");
270  }
271 
272  boost::shared_ptr<void> tracker = it_->handle_tracker_.lock();
273 
274  return Handle(tracker, *this);
275 }
276 
277 } // namespace actionlib
278 
279 #endif // ACTIONLIB__MANAGED_LIST_H_
actionlib::ManagedList::CustomDeleter
boost::function< void(iterator)> CustomDeleter
Definition: managed_list.h:152
actionlib::DestructionGuard::ScopedProtector::isProtected
bool isProtected()
Checks if the ScopedProtector successfully protected the DestructionGuard.
Definition: destruction_guard.h:145
actionlib::ManagedList::add
Handle add(const T &elem)
Add an element to the back of the ManagedList.
Definition: managed_list.h:283
actionlib::DestructionGuard::ScopedProtector
Protects a DestructionGuard until this object goes out of scope.
Definition: destruction_guard.h:128
boost::shared_ptr
actionlib::ManagedList::TrackedElem::handle_tracker_
boost::weak_ptr< void > handle_tracker_
Definition: managed_list.h:158
actionlib::ManagedList::iterator
Definition: managed_list.h:132
actionlib::ManagedList::iterator::it_
std::list< TrackedElem >::iterator it_
Definition: managed_list.h:149
actionlib::ManagedList::Handle
Definition: managed_list.h:185
actionlib::ManagedList::iterator::operator->
T & operator->()
Definition: managed_list.h:137
boost
actionlib::ManagedList::ElemDeleter::deleter_
CustomDeleter deleter_
Definition: managed_list.h:180
actionlib::ManagedList::ElemDeleter::operator()
void operator()(void *)
Definition: managed_list.h:163
ROS_ERROR_NAMED
#define ROS_ERROR_NAMED(name,...)
actionlib::ManagedList::erase
void erase(iterator it)
Removes an element from the ManagedList.
Definition: managed_list.h:313
actionlib::ManagedList::ElemDeleter::guard_
boost::shared_ptr< DestructionGuard > guard_
Definition: managed_list.h:181
actionlib::ManagedList
wrapper around an STL list to help with reference counting Provides handles elements in an STL list....
Definition: managed_list.h:88
actionlib::ManagedList::defaultDeleter
void defaultDeleter(iterator it)
Definition: managed_list.h:322
actionlib::ManagedList::Handle::it_
iterator it_
Definition: managed_list.h:273
actionlib::ManagedList::Handle::valid_
bool valid_
Definition: managed_list.h:275
console.h
actionlib::ManagedList::Handle::handle_tracker_
boost::shared_ptr< void > handle_tracker_
Definition: managed_list.h:274
ROS_DEBUG_NAMED
#define ROS_DEBUG_NAMED(name,...)
actionlib::ManagedList::iterator::ManagedList
friend class ManagedList
Definition: managed_list.h:144
actionlib::ManagedList::ElemDeleter::ElemDeleter
ElemDeleter(iterator it, CustomDeleter deleter, const boost::shared_ptr< DestructionGuard > &guard)
Definition: managed_list.h:158
destruction_guard.h
actionlib::ManagedList::iterator::operator++
void operator++()
Definition: managed_list.h:142
actionlib::ManagedList::ElemDeleter
Definition: managed_list.h:155
actionlib::ManagedList::Handle::iterator
friend class iterator
Definition: managed_list.h:266
actionlib::ManagedList::iterator::operator!=
bool operator!=(const iterator &rhs) const
Definition: managed_list.h:141
actionlib::ManagedList::Handle::operator==
bool operator==(const Handle &rhs) const
Checks if two handles point to the same list elem.
Definition: managed_list.h:250
actionlib::ManagedList::ElemDeleter::it_
iterator it_
Definition: managed_list.h:179
actionlib::ManagedList::begin
iterator begin()
Definition: managed_list.h:319
actionlib::ManagedList::iterator::operator==
bool operator==(const iterator &rhs) const
Definition: managed_list.h:140
actionlib::ManagedList::Handle::Handle
Handle()
Construct an empty handle.
Definition: managed_list.h:191
actionlib::ManagedList::Handle::operator=
Handle & operator=(const Handle &rhs)
Definition: managed_list.h:194
actionlib
Definition: action_definition.h:40
actionlib::ManagedList::TrackedElem::elem
T elem
Definition: managed_list.h:157
actionlib::ManagedList::end
iterator end()
Definition: managed_list.h:318
actionlib::ManagedList::iterator::operator*
T & operator*()
Definition: managed_list.h:136
actionlib::ManagedList::Handle::reset
void reset()
stop tracking the list element with this handle, even though the Handle hasn't gone out of scope
Definition: managed_list.h:213
actionlib::ManagedList::ManagedList
ManagedList()
Definition: managed_list.h:278
actionlib::ManagedList::list_
std::list< TrackedElem > list_
Definition: managed_list.h:326
actionlib::ManagedList::Handle::getElem
T & getElem()
get the list element that this handle points to fails/asserts if this is an empty handle
Definition: managed_list.h:229
actionlib::ManagedList::iterator::createHandle
Handle createHandle()
Creates a refcounted Handle from an iterator.
Definition: managed_list.h:299
actionlib::ManagedList::TrackedElem
Definition: managed_list.h:123
actionlib::ManagedList::iterator::iterator
iterator()
Definition: managed_list.h:135


actionlib
Author(s): Eitan Marder-Eppstein, Vijay Pradeep, Mikael Arguedas
autogenerated on Fri May 19 2023 02:36:55