NVBIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
priority_deque.hpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*\
2 | Copyright (C) 2012-2013 Nathaniel McClatchey |
3 | Released under the Boost Software License Version 1.0, which may be found |
4 | at http://www.boost.org/LICENSE_1_0.txt |
5 \*----------------------------------------------------------------------------*/
6 
17 #ifndef BOOST_CONTAINER_PRIORITY_DEQUE_HPP_
18 #define BOOST_CONTAINER_PRIORITY_DEQUE_HPP_
19 
20 #ifndef __cplusplus
21 #error priority_deque.hpp requires a C++ compiler.
22 #endif
23 
24 // Default comparison (std::less)
25 #include <functional>
26 // Default container (std::vector)
27 #include <vector>
28 // Grab std::move, if available.
29 #if (__cplusplus >= 201103L)
30 #include <utility>
31 #endif
32 // Interval-heap management.
33 #include "interval_heap.hpp"
34 
35 // Choose the best available version of the assert macro.
36 #ifdef BOOST_ASSERT_MSG
37 #define BOOST_CONTAINER_PRIORITY_DEQUE_ASSERT(x,m) BOOST_ASSERT_MSG(x,m)
38 #elif defined assert
39 #define BOOST_CONTAINER_PRIORITY_DEQUE_ASSERT(x,m) assert(x)
40 #else
41 #define BOOST_CONTAINER_PRIORITY_DEQUE_ASSERT(x,m)
42 #endif
43 
44 namespace boost {
45 namespace container {
47 template <typename Type, typename Sequence =std::vector<Type>,
48  typename Compare =::std::less<typename Sequence::value_type> >
50 
52 template <typename Type, typename Sequence, typename Compare>
55 
56 //----------------------------Priority Deque Class-----------------------------|
90 template <typename Type, typename Sequence, typename Compare>
91 class priority_deque {
92 //----------------------------------Public-------------------------------------|
93  public:
94 //---------------------------------Typedefs------------------------------------|
96  typedef Sequence container_type;
97  typedef typename container_type::value_type value_type;
98  typedef Compare value_compare;
100  typedef typename container_type::size_type size_type;
102  typedef typename container_type::const_reference const_reference;
103  typedef typename container_type::reference reference;
104  typedef typename container_type::pointer pointer;
107  typedef typename container_type::const_iterator const_iterator;
110  typedef typename container_type::difference_type difference_type;
111 //-------------------------------Constructors----------------------------------|
113 #if (__cplusplus >= 201103L)
114  explicit priority_deque (const Compare& =Compare(),
115  Sequence&& =Sequence());
117  priority_deque (const Compare&, const Sequence&);
118 #else
119  explicit priority_deque (const Compare& =Compare(),
120  const Sequence& =Sequence());
121 #endif
122 #if (__cplusplus >= 201103L)
124  template <typename InputIterator>
125  priority_deque (InputIterator first, InputIterator last,
126  const Compare& =Compare(),
127  Sequence&& =Sequence());
129  template <typename InputIterator>
130  priority_deque (InputIterator first, InputIterator last,
131  const Compare&, const Sequence&);
132 #else
133  template <typename InputIterator>
134  priority_deque (InputIterator first, InputIterator last,
135  const Compare& =Compare(),
136  const Sequence& =Sequence());
137 #endif
138 //-----------------------------Restricted Access-------------------------------|
140  void push (const value_type&);
141 #if (__cplusplus >= 201103L)
142  void push (value_type&&);
145  template<typename... Args>
146  void emplace (Args&&...);
147 #endif
148 
151  const_reference maximum (void) const;
153  const_reference minimum (void) const;
155  inline const_reference top (void) const { return maximum(); };
159  void pop_maximum (void);
161  void pop_minimum (void);
163  inline void pop (void) { pop_maximum(); };
165 
166 //--------------------------------Deque Size-----------------------------------|
169  inline bool empty (void) const {return sequence_.empty();};
171  inline size_type size (void) const {return sequence_.size(); };
173  inline size_type max_size (void) const {
174  return sequence_.max_size();
175  };
177 
178 //--------------------------Whole-Deque Operations-----------------------------|
180  inline void clear (void) { sequence_.clear(); };
185  template <typename InputIterator>
186  void merge (InputIterator first, InputIterator last);
188  template <typename SourceContainer>
189  inline void merge (const SourceContainer& source) {
190  merge(source.begin(), source.end());
191  }
193 
194 //-------------------------------Random Access---------------------------------|
197  inline const_iterator begin (void) const {return sequence_.begin();};
199  inline const_iterator end (void) const { return sequence_.end(); };
201  void update (const_iterator, const value_type&);
202 #if (__cplusplus >= 201103L)
203  void update (const_iterator, value_type&&);
205 #endif
206  void erase (const_iterator);
209 
210 //---------------------------Boost.Heap Concepts-------------------------------|
211 // size() has constant complexity
212  static const bool constant_time_size = true;
213 // priority deque does not have ordered iterators
214  static const bool has_ordered_iterators = false;
215 // priority deque is efficiently mergable
216  static const bool is_mergable = true;
217 // priority deque does not have a stable heap order
218  static const bool is_stable = false;
219 // priority deque does not have a reserve() member
220  static const bool has_reserve = false;
221 
222 //--------------------------------Protected------------------------------------|
223  protected:
224  inline container_type& sequence (void) { return sequence_; };
225  inline const container_type& sequence (void) const { return sequence_; };
226  inline value_compare& compare (void) { return compare_; };
227  inline const value_compare& compare (void) const { return compare_; };
228 //---------------------------------Private-------------------------------------|
229  private:
230  Sequence sequence_;
231  Compare compare_;
232 };
233 
234 //-------------------------------Constructors----------------------------------|
235 //----------------------------Default Constructor------------------------------|
242 template <typename T, typename S, typename C>
244  : sequence_(seq), compare_(comp)
245 {
246  heap::make_interval_heap(sequence_.begin(), sequence_.end(), compare_);
247 }
248 #if (__cplusplus >= 201103L)
249 template <typename T, typename S, typename C>
251  : sequence_(std::move(seq)), compare_(comp)
252 {
253  heap::make_interval_heap(sequence_.begin(), sequence_.end(), compare_);
254 }
255 #endif
256 
257 //---------------------------Create from Iterators-----------------------------|
266 template <typename T, typename S, typename C>
267 template <typename InputIterator>
268 priority_deque<T, S, C>::priority_deque (InputIterator first,InputIterator last,
269  const C& comp, const S& seq)
270 : sequence_(seq), compare_(comp)
271 {
272  try {
273  sequence_.insert(sequence_.end(), first, last);
274  heap::make_interval_heap(sequence_.begin(), sequence_.end(), compare_);
275  } catch (...) {
276  heap::make_interval_heap(sequence_.begin(), sequence_.end(), compare_);
277  throw;
278  }
279 }
280 #if (__cplusplus >= 201103L)
281 template <typename T, typename S, typename C>
282 template <typename InputIterator>
283 priority_deque<T, S, C>::priority_deque (InputIterator first,InputIterator last,
284  const C& comp, S&& seq)
285 : sequence_(std::move(seq)), compare_(comp)
286 {
287  try {
288  sequence_.insert(sequence_.end(), first, last);
289  heap::make_interval_heap(sequence_.begin(), sequence_.end(), compare_);
290  } catch (...) {
291  heap::make_interval_heap(sequence_.begin(), sequence_.end(), compare_);
292  throw;
293  }
294 }
295 #endif
296 
297 //-----------------------------Restricted Access-------------------------------|
298 //------------------------------Insert / Emplace-------------------------------|
305 template <typename T, typename Sequence, typename Compare>
307  try {
308  sequence_.push_back(value);
309  } catch (...) {
310  heap::push_interval_heap(sequence_.begin(), sequence_.end(), compare_);
311  throw;
312  }
313  heap::push_interval_heap(sequence_.begin(), sequence_.end(), compare_);
314 }
315 #if (__cplusplus >= 201103L)
316 template <typename T, typename Sequence, typename Compare>
317 void priority_deque<T, Sequence, Compare>::push (value_type&& value) {
318  try {
319  sequence_.push_back(std::move(value));
320  } catch (...) {
321  heap::push_interval_heap(sequence_.begin(), sequence_.end(), compare_);
322  throw;
323  }
324  heap::push_interval_heap(sequence_.begin(), sequence_.end(), compare_);
325 }
326 
327 template <typename T, typename Sequence, typename Compare>
328 template<typename... Args>
329 void priority_deque<T, Sequence, Compare>::emplace (Args&&... args) {
330  try {
331  sequence_.emplace_back(std::forward<Args>(args)...);
332  } catch (...) {
333  heap::push_interval_heap(sequence_.begin(), sequence_.end(), compare_);
334  throw;
335  }
336  heap::push_interval_heap(sequence_.begin(), sequence_.end(), compare_);
337 }
338 #endif
339 
340 //---------------------------Observe Maximum/Minimum---------------------------|
347 template <typename T, typename Sequence, typename Compare>
348 inline typename priority_deque<T, Sequence, Compare>::const_reference
350 {
352  "Empty priority deque has no maximal element. Reference undefined.");
353  const_iterator it = sequence_.begin() + 1;
354  return (it == sequence_.end()) ? sequence_.front() : *it;
355 }
362 template <typename T, typename Sequence, typename Compare>
365 {
367  "Empty priority deque has no minimal element. Reference undefined.");
368  return sequence_.front();
369 }
370 //---------------------------Remove Maximum/Minimum----------------------------|
378 template <typename T, typename Sequence, typename Compare>
381  "Empty priority deque has no maximal element. Removal impossible.");
382  heap::pop_interval_heap_min(sequence_.begin(), sequence_.end(), compare_);
383  try {
384  sequence_.pop_back();
385  } catch (...) {
386 // If pop_back has a strong guarantee, this will restore the heap.
387  heap::push_interval_heap(sequence_.begin(), sequence_.end(), compare_);
388  throw;
389  }
390 }
398 template <typename T, typename Sequence, typename Compare>
401  "Empty priority deque has no minimal element. Removal undefined.");
402  heap::pop_interval_heap_max(sequence_.begin(), sequence_.end(), compare_);
403  try {
404  sequence_.pop_back();
405  } catch (...) {
406 // If pop_back has a strong guarantee, this will restore the heap.
407  heap::push_interval_heap(sequence_.begin(), sequence_.end(), compare_);
408  throw;
409  }
410 }
411 
412 //--------------------------Whole-Deque Operations-----------------------------|
413 //-----------------------------------Merge-------------------------------------|
422 template <typename T, typename S, typename C>
423 template <typename InputIterator>
424 void priority_deque<T, S, C>::merge (InputIterator first, InputIterator last) {
425  try {
426  sequence_.insert(sequence_.end(), first, last);
427  heap::make_interval_heap(sequence_.begin(), sequence_.end(), compare_);
428  } catch (...) { // Try to fix the problem.
429  heap::make_interval_heap(sequence_.begin(), sequence_.end(), compare_);
430  throw;
431  }
432 }
433 
434 //----------------------------Swap Specialization------------------------------|
442 template <typename T, typename S, typename C>
444  sequence_.swap(other.sequence_);
445 }
446 
455 template <typename T, typename S, typename C>
456 inline void swap (priority_deque<T, S, C>& deque1,
457  priority_deque<T, S, C>& deque2)
458 {
459  deque1.swap(deque2);
460 }
461 
462 //---------------------------Random-Access Mutators----------------------------|
475 template <typename T, typename S, typename C>
477  const value_type& value)
478 {
479  const difference_type index = random_it - begin();
481  (index < end() - begin()), "Iterator out of bounds; can't set element.");
482 // Providing the strong guarantee would require saving a copy.
483  *(sequence_.begin() + index) = value;
484  heap::update_interval_heap(sequence_.begin(),sequence_.end(),index,compare_);
485 }
486 #if (__cplusplus >= 201103L)
487 template <typename T, typename S, typename C>
488 void priority_deque<T, S, C>::update (const_iterator random_it,
489  value_type&& value)
490 {
491  const difference_type index = random_it - begin();
493  (index < end() - begin()), "Iterator out of bounds; can't set element.");
494 // Providing the strong guarantee would require saving a copy.
495  *(sequence_.begin() + index) = std::move(value);
496  heap::update_interval_heap(sequence_.begin(),sequence_.end(),index,compare_);
497 }
498 #endif
499 
507 template <typename T, typename Sequence, typename Compare>
509  const difference_type index = random_it - begin();
511  (index < end() - begin()), "Iterator out of bounds; can't erase element.");
512  heap::pop_interval_heap(sequence_.begin(), sequence_.end(),index,compare_);
513  try {
514  sequence_.pop_back();
515  } catch (...) {
516 // If pop_back has the strong guarantee, this will re-make the interval heap.
517  heap::push_interval_heap(sequence_.begin(), sequence_.end(), compare_);
518  throw;
519  }
520 }
521 
522 } // Namespace boost::container
523 } // Namespace boost
524 
525 #endif