yat  0.15.2pre
PriorityQueue.h
1 #ifndef theplu_yat_utility_priority_queue
2 #define theplu_yat_utility_priority_queue
3 
4 // $Id: PriorityQueue.h 3702 2017-10-04 06:41:25Z peter $
5 //
6 // Copyright (C) 2015, 2016, 2017 Peter Johansson
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21 #include "yat_assert.h"
22 
23 #include <boost/thread.hpp>
24 
25 #include <set>
26 #include <utility>
27 
28 namespace theplu {
29 namespace yat {
30 namespace utility {
31 
53  template<typename T, class Compare = std::less<T> >
55  {
56  public:
58  typedef T value_type;
59 
63  typedef typename std::set<T, Compare>::size_type size_type;
64 
68  PriorityQueue(void) {}
69 
73  explicit PriorityQueue(const Compare& comp) : q_(comp) {}
74 
80  PriorityQueue(const PriorityQueue& other) : q_(other.q_) {}
81 
87  void clear(void)
88  {
89  boost::unique_lock<boost::mutex> lock(mutex_);
90  return q_.clear();
91  }
92 
96  bool empty(void) const
97  {
98  boost::unique_lock<boost::mutex> lock(mutex_);
99  return q_.empty();
100  } // lock is released here
101 
102 
110  void pop(T& value)
111  {
112  boost::unique_lock<boost::mutex> lock(mutex_);
113  while (q_.empty())
114  condition_.wait(lock);
115  pop(value, lock);
116  } // lock is released here
117 
118 
122  void push(const T& t)
123  {
124  boost::unique_lock<boost::mutex> lock(mutex_);
125  q_.insert(t);
126  lock.unlock(); // unlock the mutex
127 
128  // Notify others that data is ready after we have unlocked
129  condition_.notify_one();
130  }
131 
132 
133 #ifdef YAT_HAVE_RVALUE
134 
141  void push(T&& t)
142  {
143  boost::unique_lock<boost::mutex> lock(mutex_);
144  q_.insert(std::move(t));
145  lock.unlock(); // unlock the mutex
146 
147  // Notify others that data is ready after we have unlocked
148  condition_.notify_one();
149  }
150 #endif
151 
152 
156  size_type size(void) const
157  {
158  boost::unique_lock<boost::mutex> lock(mutex_);
159  return q_.size();
160  } // lock is released here
161 
162 
167  bool try_pop(T& value)
168  {
169  boost::unique_lock<boost::mutex> lock(mutex_);
170  if (q_.empty())
171  return false;
172  pop(value, lock);
173  return true;
174  } // lock is released here
175 
176 
183  {
184  boost::unique_lock<boost::mutex> lock(mutex_);
185  q_ = lhs.q();
186  return *this;
187  } // lock is released here
188 
189  private:
190  // never access this container directly from another object, use
191  // q() instead
192  std::set<T, Compare> q_;
193  mutable boost::mutex mutex_;
194  boost::condition_variable condition_;
195 
196  void pop(T& value, const boost::unique_lock<boost::mutex>& lock)
197  {
198  // The obvious choice would be to create a temp copy of front,
199  // pop the queue and then return by-value. This is, however,
200  // dangerous because if the copy constructor throws, the queue
201  // has been popped and the element is lost. Instead we choose to
202  // return via passed reference.
203  typename std::set<T, Compare>::iterator it = q_.end();
204  YAT_ASSERT(q_.size());
205  --it;
206  value = *it;
207  q_.erase(it);
208  }
209 
210  // thread safe way to access nderlying data
211  const std::set<T, Compare>& q(void) const
212  {
213  boost::unique_lock<boost::mutex> lock(mutex_);
214  return q_;
215  } // lock is released here
216  };
217 
218 }}}
219 #endif
PriorityQueue(const PriorityQueue &other)
Copy constructor.
Definition: PriorityQueue.h:80
The Department of Theoretical Physics namespace as we define it.
void clear(void)
clear queue
Definition: PriorityQueue.h:87
T value_type
Type of object stored in Queue.
Definition: PriorityQueue.h:58
Multi-thread safe priority queue.
Definition: PriorityQueue.h:54
PriorityQueue(void)
Create a PriorityQueue with no elements.
Definition: PriorityQueue.h:68
size_type size(void) const
Definition: PriorityQueue.h:156
bool try_pop(T &value)
Definition: PriorityQueue.h:167
bool empty(void) const
Definition: PriorityQueue.h:96
PriorityQueue & operator=(const PriorityQueue &lhs)
assignment operator
Definition: PriorityQueue.h:182
std::set< T, Compare >::size_type size_type
Definition: PriorityQueue.h:63
PriorityQueue(const Compare &comp)
Create a PriorityQueue with comp as Compare functor.
Definition: PriorityQueue.h:73
void push(const T &t)
insert an element into container
Definition: PriorityQueue.h:122
void pop(T &value)
access next element is queue
Definition: PriorityQueue.h:110

Generated on Fri Jul 13 2018 02:33:27 for yat by  doxygen 1.8.11