Embedded Template Library 1.0
Loading...
Searching...
No Matches
priority_queue.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2015 John Wellbelove, rlindeman
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_PRIORITY_QUEUE_INCLUDED
32#define ETL_PRIORITY_QUEUE_INCLUDED
33
34#include "platform.h"
35#include "algorithm.h"
36#include "deque.h"
37#include "error_handler.h"
38#include "exception.h"
39#include "functional.h"
40#include "iterator.h"
41#include "parameter_type.h"
42#include "static_assert.h"
43#include "type_traits.h"
44#include "utility.h"
45#include "vector.h"
46
47#include <stddef.h>
48
49//*****************************************************************************
54//*****************************************************************************
55
56namespace etl
57{
58 //***************************************************************************
61 //***************************************************************************
62 class priority_queue_exception : public exception
63 {
64 public:
65
66 priority_queue_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
67 : exception(reason_, file_name_, line_number_)
68 {
69 }
70 };
71
72 //***************************************************************************
75 //***************************************************************************
76 class priority_queue_full : public etl::priority_queue_exception
77 {
78 public:
79
80 priority_queue_full(string_type file_name_, numeric_type line_number_)
81 : priority_queue_exception(ETL_ERROR_TEXT("priority_queue:full", ETL_PRIORITY_QUEUE_FILE_ID"A"), file_name_, line_number_)
82 {
83 }
84 };
85
86 //***************************************************************************
89 //***************************************************************************
90 class priority_queue_iterator : public etl::priority_queue_exception
91 {
92 public:
93
94 priority_queue_iterator(string_type file_name_, numeric_type line_number_)
95 : priority_queue_exception(ETL_ERROR_TEXT("priority_queue:iterator", ETL_PRIORITY_QUEUE_FILE_ID"B"), file_name_, line_number_)
96 {
97 }
98 };
99
100 //***************************************************************************
103 //***************************************************************************
104 class priority_queue_empty : public etl::priority_queue_exception
105 {
106 public:
107
108 priority_queue_empty(string_type file_name_, numeric_type line_number_)
109 : priority_queue_exception(ETL_ERROR_TEXT("priority_queue:empty", ETL_PRIORITY_QUEUE_FILE_ID"C"), file_name_, line_number_)
110 {
111 }
112 };
113
114 //***************************************************************************
117 //***************************************************************************
118 template <typename TContainer>
120 {
121 ETL_STATIC_ASSERT(sizeof(TContainer) == 0, "Unsupported container type for etl::ipriority_queue");
122 };
123
124 template <typename T, const size_t N>
126 {
127 typedef etl::ivector<T> type;
128 };
129
130 template <typename T, const size_t N>
132 {
133 typedef etl::ideque<T> type;
134 };
135
136 //***************************************************************************
150 //***************************************************************************
151 template <typename T, typename TContainerBase = etl::ivector<T>, typename TCompare = etl::less<T> >
153 {
154 public:
155
156 typedef T value_type;
157 typedef TCompare compare_type;
158 typedef TContainerBase container_base_type;
159 typedef T& reference;
160 typedef const T& const_reference;
161#if ETL_USING_CPP11
162 typedef T&& rvalue_reference;
163#endif
164 typedef typename TContainerBase::size_type size_type;
165 typedef typename TContainerBase::difference_type difference_type;
166
167 //*************************************************************************
172 //*************************************************************************
174 {
175 ETL_ASSERT_CHECK_EXTRA(!empty(), ETL_ERROR(priority_queue_empty));
176 return container.front();
177 }
178
179 //*************************************************************************
184 //*************************************************************************
186 {
187 ETL_ASSERT_CHECK_EXTRA(!empty(), ETL_ERROR(priority_queue_empty));
188 return container.front();
189 }
190
191 //*************************************************************************
196 //*************************************************************************
198 {
200
201 // Put element at end
202 container.push_back(value);
203 // Make elements in container into heap
204 etl::push_heap(container.begin(), container.end(), compare);
205 }
206
207#if ETL_USING_CPP11
208 //*************************************************************************
213 //*************************************************************************
214 void push(rvalue_reference value)
215 {
217
218 // Put element at end
219 container.push_back(etl::move(value));
220 // Make elements in container into heap
221 etl::push_heap(container.begin(), container.end(), compare);
222 }
223#endif
224
225#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_PRIORITY_QUEUE_FORCE_CPP03_IMPLEMENTATION)
226 //*************************************************************************
231 //*************************************************************************
232 template <typename... Args>
233 void emplace(Args&&... args)
234 {
236
237 // Put element at end
238 container.emplace_back(etl::forward<Args>(args)...);
239 // Make elements in container into heap
240 etl::push_heap(container.begin(), container.end(), compare);
241 }
242#else
243 //*************************************************************************
248 //*************************************************************************
249 void emplace()
250 {
252
253 // Put element at end
254 container.emplace_back();
255 // Make elements in container into heap
256 etl::push_heap(container.begin(), container.end(), compare);
257 }
258
259 //*************************************************************************
264 //*************************************************************************
265 template <typename T1>
266 void emplace(const T1& value1)
267 {
269
270 // Put element at end
271 container.emplace_back(value1);
272 // Make elements in container into heap
273 etl::push_heap(container.begin(), container.end(), compare);
274 }
275
276 //*************************************************************************
281 //*************************************************************************
282 template <typename T1, typename T2>
283 void emplace(const T1& value1, const T2& value2)
284 {
286
287 // Put element at end
288 container.emplace_back(value1, value2);
289 // Make elements in container into heap
290 etl::push_heap(container.begin(), container.end(), compare);
291 }
292
293 //*************************************************************************
298 //*************************************************************************
299 template <typename T1, typename T2, typename T3>
300 void emplace(const T1& value1, const T2& value2, const T3& value3)
301 {
303
304 // Put element at end
305 container.emplace_back(value1, value2, value3);
306 // Make elements in container into heap
307 etl::push_heap(container.begin(), container.end(), compare);
308 }
309
310 //*************************************************************************
315 //*************************************************************************
316 template <typename T1, typename T2, typename T3, typename T4>
317 void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
318 {
320
321 // Put element at end
322 container.emplace_back(value1, value2, value3, value4);
323 // Make elements in container into heap
324 etl::push_heap(container.begin(), container.end(), compare);
325 }
326#endif
327
328 //*************************************************************************
336 //*************************************************************************
337 template <typename TIterator>
338 void assign(TIterator first, TIterator last)
339 {
340#if ETL_IS_DEBUG_BUILD
341 difference_type d = etl::distance(first, last);
342 ETL_ASSERT(d >= 0, ETL_ERROR(etl::priority_queue_iterator));
343 ETL_ASSERT(static_cast<size_t>(d) <= max_size(), ETL_ERROR(etl::priority_queue_full));
344#endif
345
346 clear();
347 container.assign(first, last);
348 etl::make_heap(container.begin(), container.end(), compare);
349 }
350
351 //*************************************************************************
356 //*************************************************************************
357 void pop()
358 {
359 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(priority_queue_empty));
360 // Move largest element to end
361 etl::pop_heap(container.begin(), container.end(), compare);
362 // Actually remove largest element at end
363 container.pop_back();
364 }
365
366 //*************************************************************************
369 //*************************************************************************
370 void pop_into(reference destination)
371 {
372 destination = ETL_MOVE(top());
373 pop();
374 }
375
376 //*************************************************************************
378 //*************************************************************************
380 {
381 return container.size();
382 }
383
384 //*************************************************************************
386 //*************************************************************************
388 {
389 return container.max_size();
390 }
391
392 //*************************************************************************
395 //*************************************************************************
396 bool empty() const
397 {
398 return container.empty();
399 }
400
401 //*************************************************************************
405 //*************************************************************************
406 bool full() const
407 {
408 return container.size() == container.max_size();
409 }
410
411 //*************************************************************************
414 //*************************************************************************
416 {
417 return container.max_size() - container.size();
418 }
419
420 //*************************************************************************
422 //*************************************************************************
423 void clear()
424 {
425 container.clear();
426 }
427
428 //*************************************************************************
430 //*************************************************************************
432 {
433 if (&rhs != this)
434 {
435 clone(rhs);
436 }
437
438 return *this;
439 }
440
441#if ETL_USING_CPP11
442 //*************************************************************************
444 //*************************************************************************
446 {
447 if (&rhs != this)
448 {
449 clear();
450 move(etl::move(rhs));
451 }
452
453 return *this;
454 }
455#endif
456
457 //*************************************************************************
459 //*************************************************************************
460#if defined(ETL_POLYMORPHIC_PRIORITY_QUEUE) || defined(ETL_POLYMORPHIC_CONTAINERS)
461
462 public:
463
464 virtual ~ipriority_queue() {}
465#else
466
467 protected:
468
470#endif
471
472 protected:
473
474 //*************************************************************************
476 //*************************************************************************
477 void clone(const ipriority_queue& other)
478 {
480 assign(other.container.cbegin(), other.container.cend());
482 }
483
484#if ETL_USING_CPP11
485 //*************************************************************************
487 //*************************************************************************
488 void move(ipriority_queue&& other)
489 {
490 while (!other.empty())
491 {
492 push(etl::move(other.top()));
493 other.pop();
494 }
495 }
496#endif
497
498 //*************************************************************************
500 //*************************************************************************
501 ipriority_queue(TContainerBase& container_)
502 : container(container_)
503 {
504 }
505
506 private:
507
508 // Disable copy construction.
510
512 TContainerBase& container;
513
514 TCompare compare;
515 };
516
517 //***************************************************************************
523 //***************************************************************************
524 template <typename T, const size_t SIZE, typename TContainer = etl::vector<T, SIZE>,
525 typename TCompare = etl::less<typename TContainer::value_type> >
526 class priority_queue : public etl::ipriority_queue<T, typename etl::priority_queue_container_interface<TContainer>::type, TCompare>
527 {
528 private:
529
531
532 public:
533
534 typedef typename TContainer::size_type size_type;
535 typedef TContainer container_type;
536
537 static ETL_CONSTANT size_type MAX_SIZE = size_type(SIZE);
538
539 //*************************************************************************
541 //*************************************************************************
543 : base_t(container)
544 {
545 }
546
547 //*************************************************************************
549 //*************************************************************************
551 : base_t(container)
552 {
553 base_t::clone(rhs);
554 }
555
556#if ETL_USING_CPP11
557 //*************************************************************************
559 //*************************************************************************
561 : base_t(container)
562 {
563 base_t::move(etl::move(rhs));
564 }
565#endif
566
567 //*************************************************************************
572 //*************************************************************************
573 template <typename TIterator>
574 priority_queue(TIterator first, TIterator last)
575 : base_t(container)
576 {
577 base_t::assign(first, last);
578 }
579
580 //*************************************************************************
582 //*************************************************************************
584 {
585 base_t::clear();
586 }
587
588 //*************************************************************************
590 //*************************************************************************
592 {
593 if (&rhs != this)
594 {
595 base_t::clone(rhs);
596 }
597
598 return *this;
599 }
600
601#if ETL_USING_CPP11
602 //*************************************************************************
604 //*************************************************************************
606 {
607 if (&rhs != this)
608 {
609 base_t::clear();
610 base_t::move(etl::move(rhs));
611 }
612
613 return *this;
614 }
615#endif
616
617 private:
618
619 TContainer container;
620 };
621
622 template <typename T, const size_t SIZE, typename TContainer, typename TCompare>
623 ETL_CONSTANT typename priority_queue<T, SIZE, TContainer, TCompare>::size_type priority_queue<T, SIZE, TContainer, TCompare>::MAX_SIZE;
624} // namespace etl
625
626#endif
Definition vector.h:65
Definition priority_queue.h:527
~priority_queue()
Destructor.
Definition priority_queue.h:583
priority_queue(const priority_queue &rhs)
Copy constructor.
Definition priority_queue.h:550
priority_queue & operator=(const priority_queue &rhs)
Assignment operator.
Definition priority_queue.h:591
priority_queue()
Default constructor.
Definition priority_queue.h:542
priority_queue(TIterator first, TIterator last)
Definition priority_queue.h:574
Make this a clone of the supplied priority queue.
Definition deque.h:2365
Definition deque.h:222
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
reference top()
Definition priority_queue.h:173
ipriority_queue(TContainerBase &container_)
The constructor that is called from derived classes.
Definition priority_queue.h:501
ipriority_queue & operator=(const ipriority_queue &rhs)
Assignment operator.
Definition priority_queue.h:431
TContainerBase::size_type size_type
The type used for determining the size of the queue.
Definition priority_queue.h:164
TCompare compare_type
The comparison type.
Definition priority_queue.h:157
void emplace()
Definition priority_queue.h:249
TContainerBase container_base_type
The non-sized container base type.
Definition priority_queue.h:158
const_reference top() const
Definition priority_queue.h:185
T & reference
A reference to the type used in the queue.
Definition priority_queue.h:159
const T & const_reference
A const reference to the type used in the queue.
Definition priority_queue.h:160
bool full() const
Definition priority_queue.h:406
void push(const_reference value)
Definition priority_queue.h:197
~ipriority_queue()
Destructor.
Definition priority_queue.h:469
void pop_into(reference destination)
Definition priority_queue.h:370
size_type max_size() const
Returns the maximum number of items that can be queued.
Definition priority_queue.h:387
void clear()
Clears the queue to the empty state.
Definition priority_queue.h:423
T value_type
The type stored in the queue.
Definition priority_queue.h:156
void emplace(const T1 &value1, const T2 &value2)
Definition priority_queue.h:283
void emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition priority_queue.h:317
void emplace(const T1 &value1)
Definition priority_queue.h:266
size_type available() const
Definition priority_queue.h:415
void pop()
Definition priority_queue.h:357
size_type size() const
Returns the current number of items in the priority queue.
Definition priority_queue.h:379
bool empty() const
Definition priority_queue.h:396
void assign(TIterator first, TIterator last)
Definition priority_queue.h:338
void emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition priority_queue.h:300
This is the base for all priority queues that contain a particular type.
Definition priority_queue.h:153
Definition priority_queue.h:105
Definition priority_queue.h:63
Definition priority_queue.h:77
Definition priority_queue.h:91
Definition vector.h:1830
Definition absolute.h:40
Definition compare.h:51
Definition priority_queue.h:120