BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslstl_priorityqueue.h
Go to the documentation of this file.
1/// @file bslstl_priorityqueue.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslstl_priorityqueue.h -*-C++-*-
8#ifndef INCLUDED_BSLSTL_PRIORITYQUEUE
9#define INCLUDED_BSLSTL_PRIORITYQUEUE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslstl_priorityqueue bslstl_priorityqueue
15/// @brief Provide container adapter class template `priority_queue`.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslstl
19/// @{
20/// @addtogroup bslstl_priorityqueue
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslstl_priorityqueue-purpose"> Purpose</a>
25/// * <a href="#bslstl_priorityqueue-classes"> Classes </a>
26/// * <a href="#bslstl_priorityqueue-canonical-header"> Canonical Header </a>
27/// * <a href="#bslstl_priorityqueue-description"> Description </a>
28/// * <a href="#bslstl_priorityqueue-memory-allocation"> Memory Allocation </a>
29/// * <a href="#bslstl_priorityqueue-value-and-container-value_type"> VALUE and CONTAINER::value_type </a>
30/// * <a href="#bslstl_priorityqueue-operations"> Operations </a>
31/// * <a href="#bslstl_priorityqueue-usage"> Usage </a>
32/// * <a href="#bslstl_priorityqueue-example-1-task-scheduler"> Example 1: Task Scheduler </a>
33///
34/// # Purpose {#bslstl_priorityqueue-purpose}
35/// Provide container adapter class template @ref priority_queue .
36///
37/// # Classes {#bslstl_priorityqueue-classes}
38///
39/// - bsl::priority_queue: template of highest-priority-first data structure
40///
41/// # Canonical Header {#bslstl_priorityqueue-canonical-header}
42/// bsl_queue.h
43///
44/// @see bslstl_queue, bslstl_stack
45///
46/// # Description {#bslstl_priorityqueue-description}
47/// This component defines a class template, `bsl::priority_queue`,
48/// holding a container (of a template parameter type, `CONTAINER`, containing
49/// elements of another template parameter type, `VALUE`), and adapting it to
50/// provide highest-priority-first priority queue data structure. The component
51/// takes a third template parameter type, `COMPARATOR`, for customized
52/// priorities comparison between two elements.
53///
54/// An instantiation of @ref priority_queue is an allocator-aware, value-semantic
55/// type whose salient attributes are its size (number of held elements) and the
56/// sorted sequence of values (of held elements). If @ref priority_queue is
57/// instantiated with a value type, that is not itself value-semantic, then it
58/// will not retain all of its value-semantic qualities. A @ref priority_queue
59/// cannot be tested for equality, but its value type must be able to be tested
60/// for comparing less by its comparator type.
61///
62/// The @ref priority_queue implemented here adheres to the C++11 standard when
63/// compiled with a C++11 compiler, and makes the best approximation when
64/// compiled with a C++03 compiler. In particular, for C++03 we emulate move
65/// semantics, but limit forwarding (in `emplace`) to `const` lvalues, and make
66/// no effort to emulate `noexcept` or initializer-lists.
67///
68/// ## Memory Allocation {#bslstl_priorityqueue-memory-allocation}
69///
70///
71/// The type supplied as an `ALLOCATOR` template parameter in some of
72/// @ref priority_queue constructors determines how the held container (of the
73/// (template parameter) type `CONTAINER`) will allocate memory. A
74/// @ref priority_queue supports allocators meeting the requirements of the C++11
75/// standard [17.6.3.5] as long as the held container does. In addition it
76/// supports scoped-allocators derived from the `bslma::Allocator` memory
77/// allocation protocol. Clients intending to use `bslma`-style allocators
78/// should use `bsl::allocator` as the `ALLOCATOR` template parameter,
79/// providing a C++11 standard-compatible adapter for a `bslma::Allocator`
80/// object.
81///
82/// ### VALUE and CONTAINER::value_type {#bslstl_priorityqueue-value-and-container-value_type}
83///
84///
85/// When the `CONTAINER` template parameter is omitted the `VALUE` template
86/// parameter specifies the `value_type` of `bsl::vector`, the default container
87/// type. The `VALUE` template has no other role.
88///
89/// For C++17 and later, the behavior is undefined unless:
90/// @code
91/// true == bsl::is_same<VALUE, typename CONTAINER::value_type>::value
92/// @endcode
93/// Prior to C++17, `CONTAINER::value_type` determines the contained value type
94/// and `VALUE` is simply ignored. The resulting code may work with instances
95/// of `VALUE` (e.g., `VALUE` is convertible to `CONTAINER::value_type`) or not
96/// (compiler errors).
97///
98/// ## Operations {#bslstl_priorityqueue-operations}
99///
100///
101/// The C++11 standard [23.6.4] declares any container type supporting
102/// operations `front`, `push_back`, and @ref pop_back can be used to instantiate
103/// the (template parameter) type `CONTAINER`. Below is a list of public
104/// methods of @ref priority_queue class that are effectively implemented as
105/// calling the corresponding operations in the held container (referenced as
106/// `c`).
107/// @code
108/// +--------------------------------------+--------------------------+
109/// | Public methods in 'priority_queue' | Operation in 'CONTAINER' |
110/// +======================================+==========================+
111/// | void push(const value_type& value); | c.push_back(value); |
112/// | void pop(); | c.pop_back(); |
113/// | void emplace(Args&&... args) | c.emplace_back(...) |
114/// +--------------------------------------+--------------------------+
115/// | bool empty() const; | c.empty(); |
116/// | size_type size() const; | c.size(); |
117/// | const_reference top() const; | c.front(); |
118/// +--------------------------------------+--------------------------+
119/// @endcode
120///
121/// ## Usage {#bslstl_priorityqueue-usage}
122///
123///
124/// In this section we show intended use of this component.
125///
126/// ### Example 1: Task Scheduler {#bslstl_priorityqueue-example-1-task-scheduler}
127///
128///
129/// In this example, we will use the `bsl::priority_queue` class to implement a
130/// task scheduler that schedules a group of tasks based on their designated
131/// priorities.
132///
133/// Suppose we want to write a background process that runs tasks needed by
134/// foreground applications. Each task has a task id, a priority, and a
135/// function pointer that can be invoked by the background process. This
136/// background process has two threads: one thread (receiving thread) receives
137/// requests from other applications, passing required tasks to a task
138/// scheduler; the other thread (processing thread) runs the task scheduler,
139/// executing the tasks one-by-one from higher to lower priorities. To
140/// implement this functionality, we can use `bsl::priority_queue` in the task
141/// scheduler to buffer received, but as yet unprocessed, tasks. The task
142/// scheduler adds newly received tasks into the priority queue in the receiving
143/// thread, and extracts tasks from the priority queue for execution according
144/// to their priorities in the processing thread.
145///
146/// First, we define a `TaskFunction` type:
147/// @code
148/// typedef void (*TaskFunction)(int, int, int);
149/// @endcode
150/// Then, we define a `Task` class, which contains a task id, a `TaskFunction`
151/// object and an associated task priority:
152/// @code
153/// class Task
154/// // This class represents a task that has an integer task id, a task
155/// // function, and an integer priority. The smaller the numerical value
156/// // of a priority, the higher the priority.
157/// {
158/// private:
159/// // DATA
160/// int d_taskId; // task id
161///
162/// TaskFunction d_taskFunction_p; // task function
163///
164/// int d_priority; // priority of the task
165///
166/// public:
167/// // CREATORS
168/// explicit Task(int taskId, TaskFunction taskFunction, int priority);
169/// // Create a 'Task' object having the specified 'taskId', the
170/// // specified 'd_taskFunction_p', and the specified 'priority'.
171///
172/// // ACCESSORS
173/// int getId() const;
174/// // Return the contained task id.
175///
176/// int getPriority() const;
177/// // Return the priority of the task.
178///
179/// TaskFunction getFunction() const;
180/// // Return the contained task function object.
181/// };
182///
183/// // CREATORS
184/// Task::Task(int taskId, TaskFunction taskFunction, int priority)
185/// : d_taskId(taskId)
186/// , d_taskFunction_p(taskFunction)
187/// , d_priority(priority)
188/// {
189/// }
190///
191/// // ACCESSORS
192/// inline
193/// int Task::getId() const
194/// {
195/// return d_taskId;
196/// }
197///
198/// inline
199/// int Task::getPriority() const
200/// {
201/// return d_priority;
202/// }
203///
204/// inline
205/// TaskFunction Task::getFunction() const
206/// {
207/// return d_taskFunction_p;
208/// }
209/// @endcode
210/// Next, we define a functor to compare the priorities of two `Task` objects:
211/// @code
212/// struct TaskComparator {
213/// // This 'struct' defines an ordering on 'Task' objects, allowing them
214/// // to be included in sorted data structures such as
215/// // 'bsl::priority_queue'.
216///
217/// bool operator()(const Task& lhs, const Task& rhs) const
218/// // Return 'true' if the priority of the specified 'lhs' is
219/// // numerically less than that of the specified 'rhs', and 'false'
220/// // otherwise. Note that the smaller the value returned by the
221/// // 'Task::getPriority' method, the higher the priority.
222/// {
223/// return lhs.getPriority() > rhs.getPriority();
224/// }
225/// };
226/// @endcode
227/// Then, we define a `TaskScheduler` class that provides methods to hold and
228/// schedule unprocessed tasks:
229/// @code
230/// class TaskScheduler {
231/// // This class holds and schedules tasks to execute.
232/// @endcode
233/// Here, we define a private data member that is an instantiation of
234/// `bsl::priority_queue`, which uses `Task` for its `VALUE` (template
235/// parameter) type, `bsl::vector<Task>` for its `CONTAINER` (template
236/// parameter) type, and `TaskComparator` for its `COMPARATOR` (template
237/// parameter) type:
238/// @code
239/// // DATA
240/// bsl::priority_queue<Task,
241/// bsl::vector<Task>,
242/// TaskComparator>
243/// d_taskPriorityQueue; // priority queue holding unprocessed tasks
244///
245/// // ...
246///
247/// public:
248/// // CREATORS
249/// explicit TaskScheduler(bslma::Allocator *basicAllocator = 0);
250/// // Create a 'TaskScheduler' object. Optionally specify a
251/// // 'basicAllocator' used to supply memory. If 'basicAllocator' is
252/// // 0, the currently installed default allocator is used.
253///
254/// // MANIPULATORS
255/// void addTask(int taskId, TaskFunction taskFunction, int priority);
256/// // Enqueue the specified 'task' having the specified 'priority'
257/// // onto this scheduler.
258///
259/// void processTasks(int verbose);
260/// // Dequeue the task having the highest priority in this scheduler,
261/// // and call its task function by passing in the specified 'verbose'
262/// // flag.
263/// };
264/// @endcode
265/// Next, we implement the `TaskScheduler` constructor:
266/// @code
267/// TaskScheduler::TaskScheduler(bslma::Allocator *basicAllocator)
268/// : d_taskPriorityQueue(basicAllocator)
269/// {
270/// }
271/// @endcode
272/// Notice that we pass to the contained `d_taskPriorityQueue` object the
273/// `bslma::Allocator` supplied to the `TaskScheduler` at construction.
274///
275/// Then, we implement the `addTask` method, which constructs a `Task` object
276/// and adds it into the priority queue:
277/// @code
278/// void TaskScheduler::addTask(int taskId,
279/// TaskFunction taskFunction,
280/// int priority)
281/// {
282/// // ... (some synchronization)
283///
284/// d_taskPriorityQueue.push(Task(taskId, taskFunction, priority));
285///
286/// // ...
287/// }
288/// @endcode
289/// Next, we implement the `processTasks` method, which extracts tasks from the
290/// priority queue in order of descending priorities, and executes them:
291/// @code
292/// void TaskScheduler::processTasks(int verbose)
293/// {
294/// // ... (some synchronization)
295///
296/// while (!d_taskPriorityQueue.empty()) {
297/// const Task& task = d_taskPriorityQueue.top();
298/// TaskFunction taskFunction = task.getFunction();
299/// if (taskFunction) {
300/// taskFunction(task.getId(), task.getPriority(), verbose);
301/// }
302/// d_taskPriorityQueue.pop();
303/// }
304///
305/// // ...
306/// }
307/// @endcode
308/// Note that the `top` method always returns the `Task` object having the
309/// highest priority in the priority queue.
310///
311/// Then, we define two task functions:
312/// @code
313/// void taskFunction1(int taskId, int priority, int verbose)
314/// {
315/// if (verbose) {
316/// printf("Executing task %d (priority = %d) in 'taskFunction1'.\n",
317/// taskId,
318/// priority);
319/// }
320/// }
321///
322/// void taskFunction2(int taskId, int priority, int verbose)
323/// {
324/// if (verbose) {
325/// printf("Executing task %d (priority = %d) in 'taskFunction2'.\n",
326/// taskId,
327/// priority);
328/// }
329/// }
330/// @endcode
331/// Next, we create a global `TaskScheduler` object:
332/// @code
333/// TaskScheduler taskScheduler;
334/// @endcode
335/// Now, we call the `addTask` method of `taskScheduler` in the receiving
336/// thread:
337/// @code
338/// // (in receiving thread)
339/// // ...
340///
341/// taskScheduler.addTask(1, taskFunction1, 50);
342///
343/// // ...
344///
345/// taskScheduler.addTask(2, taskFunction1, 99);
346///
347/// // ...
348///
349/// taskScheduler.addTask(3, taskFunction2, 4);
350///
351/// // ...
352/// @endcode
353/// Finally, we call the `processTasks` method of `taskScheduler` in the
354/// processing thread:
355/// @code
356/// // (in processing thread)
357/// // ...
358///
359/// taskScheduler.processTasks(veryVerbose);
360///
361/// // ...
362/// @endcode
363/// @}
364/** @} */
365/** @} */
366
367/** @addtogroup bsl
368 * @{
369 */
370/** @addtogroup bslstl
371 * @{
372 */
373/** @addtogroup bslstl_priorityqueue
374 * @{
375 */
376
377#include <bslscm_version.h>
378
379#include <bslstl_iterator.h>
380#include <bslstl_iteratorutil.h>
381#include <bslstl_ranges.h>
382#include <bslstl_vector.h>
383
384#include <bslalg_swaputil.h>
385
386#include <bslma_isstdallocator.h>
387#include <bslma_bslallocator.h>
389
390#include <bslmf_assert.h>
392#include <bslmf_enableif.h>
393#include <bslmf_isconvertible.h>
394#include <bslmf_issame.h>
395#include <bslmf_movableref.h>
397#include <bslmf_usesallocator.h>
398#include <bslmf_util.h> // 'forward(V)'
399
401#include <bsls_keyword.h>
402#include <bsls_libraryfeatures.h>
403#include <bsls_util.h> // 'forward<T>(V)'
404
405#include <algorithm>
406#include <functional>
407
408#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
409# define BSLSTL_PRIORITY_QUEUE_REQUIRES_CONTAINER_COMPATIBLE_RANGE(R, T) \
410 requires ::BloombergLP::bslmf::ContainerCompatibleRange<R, T>
411#else
412# define BSLSTL_PRIORITY_QUEUE_REQUIRES_CONTAINER_COMPATIBLE_RANGE(R, T)
413#endif
414
415#if BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
416// clang-format off
417// Include version that can be compiled with C++03
418// Generated on Mon Jan 13 08:31:39 2025
419// Command line: sim_cpp11_features.pl bslstl_priorityqueue.h
420
421# define COMPILING_BSLSTL_PRIORITYQUEUE_H
423# undef COMPILING_BSLSTL_PRIORITYQUEUE_H
424
425// clang-format on
426#else
427
428namespace bsl {
429
430 // ====================
431 // class priority_queue
432 // ====================
433
434/// This class is a value-semantic class template, adapting a container of
435/// the (template parameter) type `CONTAINER`, that holds elements of the
436/// (template parameter) type `VALUE`, to provide a highest-priority-first
437/// priority queue data structure, where the priorities of elements are
438/// compared by a comparator of the template parameter type, `COMPARATOR`.
439/// The container object held by a @ref priority_queue class object is
440/// referenced as `c` in the following documentation.
441///
442/// See @ref bslstl_priorityqueue
443template <class VALUE,
444 class CONTAINER = vector<VALUE>,
445 class COMPARATOR = std::less<typename CONTAINER::value_type> >
447
448#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_BASELINE_LIBRARY
449 // STATIC CHECK: Type mismatch is UB per C++17
451#endif
452
453 private:
454 // PRIVATE TYPES
455
456 /// This `typedef` is a convenient alias for the utility associated with
457 /// movable references.
458 typedef BloombergLP::bslmf::MovableRefUtil MoveUtil;
459
460 // PRIVATE MANIPULATORS
461
462 /// Push onto the back of the underlying container the elements of the
463 /// specified `[first, last)` range.
464 template <class INPUT_ITER, class SENTINEL>
465 void privatePushRange(INPUT_ITER first, SENTINEL last);
466
467 public:
468 // PUBLIC TYPES
469 typedef CONTAINER container_type;
470 typedef COMPARATOR value_compare;
471 typedef typename CONTAINER::value_type value_type;
472 typedef typename CONTAINER::reference reference;
473 typedef typename CONTAINER::const_reference const_reference;
474 typedef typename CONTAINER::size_type size_type;
475
476 protected:
477 // PROTECTED DATA
478 CONTAINER c; // container for elements in the 'priority_queue'. This
479 // data member exactly matches its definition in the
480 // C++11 standard [23.6.4].
481
482 COMPARATOR comp; // comparator that defines the priority order of elements
483 // in the @ref priority_queue . This data member exactly
484 // matches its definition in the C++11 standard [23.6.4].
485
486 public:
487 // TRAITS
490 BloombergLP::bslma::UsesBslmaAllocator,
491 BloombergLP::bslma::UsesBslmaAllocator<container_type>::value);
492
493 // CREATORS
494
495 /// Create an empty priority queue, adapting a default-constructed
496 /// container of the (template parameter) type `CONTAINER`. Use a
497 /// default-constructed comparator of the (template parameter) type
498 /// `COMPARATOR` to order elements in the priority queue.
500
501 /// Create an empty priority queue, adapting a default-constructed
502 /// container of the (template parameter) type `CONTAINER`, and having
503 /// the specified `comparator` of the (template parameter) type
504 /// `COMPARATOR` to order elements in the priority queue.
505 explicit priority_queue(const COMPARATOR& comparator);
506
507 /// Create a priority queue, adapting the specified `container` of the
508 /// (template parameter) type `CONTAINER`, and having the specified
509 /// `comparator` of the (template parameter) type `COMPARATOR` to order
510 /// elements in the priority queue.
511 priority_queue(const COMPARATOR& comparator, const CONTAINER& container);
512
513 /// Create a priority queue, adapting the specified `container` of the
514 /// (template parameter) type `CONTAINER`, and having the specified
515 /// `comparator` of the (template parameter) type `COMPARATOR` to order
516 /// elements in the priority queue.
517 explicit priority_queue(
518 const COMPARATOR& comparator,
519 BloombergLP::bslmf::MovableRef<CONTAINER> container);
520
521
522 /// Create a priority queue, adapting a default-constructed container of
523 /// the (template parameter) type `CONTAINER`, and inserting into the
524 /// container a sequence of `value_type` elements that starts at the
525 /// specified `first` and ends immediately before the specified `last`.
526 /// Use a default-constructed comparator of the (template parameter)
527 /// type `COMPARATOR` to order elements in the priority queue.
528 template <class INPUT_ITERATOR>
529 priority_queue(INPUT_ITERATOR first, INPUT_ITERATOR last);
530
531 /// Create a priority queue, adapting the specified `container`, having
532 /// the specified `comparator` to order the priorities of elements,
533 /// including those originally existed in `container`, and those
534 /// inserted into the `container` from a sequence of `value_type`
535 /// elements starting at the specified `first`, and ending immediately
536 /// before the specified `last`.
537 template <class INPUT_ITERATOR>
538 priority_queue(INPUT_ITERATOR first,
539 INPUT_ITERATOR last,
540 const COMPARATOR& comparator,
541 const CONTAINER& container);
542
543 /// Create a priority queue, adapting the specified `container`, having
544 /// the specified `comparator` to order elements in the priority queue,
545 /// including those originally existed in `container`, and those
546 /// inserted into the `container` from a sequence of `value_type`
547 /// elements starting at the specified `first`, and ending immediately
548 /// before the specified `last`.
549 template <class INPUT_ITERATOR>
551 INPUT_ITERATOR first,
552 INPUT_ITERATOR last,
553 const COMPARATOR& comparator,
554 BloombergLP::bslmf::MovableRef<CONTAINER> container);
555
556 /// Create a priority queue having the same value as the specified
557 /// `original` object. Use a copy of the comparator from `original` to
558 /// order elements in the priority queue.
559 priority_queue(const priority_queue& original);
560
561 /// Create a priority queue having the same value as the specified
562 /// `original` object. Use a copy of the comparator from `original` to
563 /// order elements in the priority queue.
564 priority_queue(BloombergLP::bslmf::MovableRef<priority_queue> original);
565
566 /// Create an empty priority queue, adapting a default-constructed
567 /// container of the (template parameter) type `CONTAINER` that uses the
568 /// specified `basicAllocator` to supply memory. Use a
569 /// default-constructed object of the (template parameter) type
570 /// `COMPARATOR` to order elements in the priority queue.
571 ///
572 /// \note Note that this constructor is only defined if the underlying container uses
573 /// allocator. Otherwise this constructor is disabled.
574 template <class ALLOCATOR>
575 explicit
576 priority_queue(const ALLOCATOR& basicAllocator,
577 typename enable_if<
579 ALLOCATOR>::type * = 0);
580
581 /// Create an empty priority queue, adapting a default-constructed
582 /// container of the (template parameter) type `CONTAINER` that uses the
583 /// specified `basicAllocator` to supply memory, and the specified
584 /// `comparator` to order elements in the priority queue.
585 ///
586 /// \note Note that this constructor is only defined if the underlying container uses
587 /// allocator. Otherwise this constructor is disabled.
588 template <class ALLOCATOR>
589 priority_queue(const COMPARATOR& comparator,
590 const ALLOCATOR& basicAllocator,
591 typename enable_if<
593 ALLOCATOR>::type * = 0);
594
595 /// Create a priority queue, adapting the specified `container` that
596 /// uses the specified `basicAllocator` to supply memory, and the
597 /// specified `comparator` to order elements in the priority queue.
598 ///
599 /// \note Note that this constructor is only defined if the underlying
600 /// container uses allocator. Otherwise this constructor is disabled.
601 template <class ALLOCATOR>
602 priority_queue(const COMPARATOR& comparator,
603 const CONTAINER& container,
604 const ALLOCATOR& basicAllocator,
605 typename enable_if<
607 ALLOCATOR>::type * = 0);
608
609 /// Create a priority queue, adapting the specified `container` that
610 /// uses the specified `basicAllocator` to supply memory, and the
611 /// specified `comparator` to order elements in the priority queue.
612 ///
613 /// \note Note that this constructor is only defined if the underlying
614 /// container uses allocator. Otherwise this constructor is disabled.
615 template <class ALLOCATOR>
616 priority_queue(const COMPARATOR& comparator,
617 BloombergLP::bslmf::MovableRef<CONTAINER> container,
618 const ALLOCATOR& basicAllocator,
619 typename enable_if<
621 ALLOCATOR>::type * = 0);
622
623 /// Create a priority queue having the same value as the specified
624 /// `original` object and using the specified `basicAllocator` to supply
625 /// memory. Use a copy of the comparator from `original` to order elements in the priority queue.
626 ///
627 /// \note Note that this constructor is only
628 /// defined if the underlying container uses allocator. Otherwise this
629 /// constructor is disabled.
630 template <class ALLOCATOR>
631 priority_queue(const priority_queue& original,
632 const ALLOCATOR& basicAllocator,
633 typename enable_if<
635 ALLOCATOR>::type * = 0);
636
637 /// Create a priority queue having the same value as the specified
638 /// `original` object and using the specified `basicAllocator` to supply
639 /// memory. Use a copy of the comparator from `original` to order elements in the priority queue.
640 ///
641 /// \note Note that this constructor is only
642 /// defined if the underlying container uses allocator. Otherwise this
643 /// constructor is disabled.
644 template <class ALLOCATOR>
646 BloombergLP::bslmf::MovableRef<priority_queue> original,
647 const ALLOCATOR& basicAllocator,
648 typename enable_if<
650 ALLOCATOR>::type * = 0);
651
652 /// Create a priority queue from the elements of the specified `range`.
653 /// Optionally specify a `comparator` used to order elements in the
654 /// priority queue. Optionally supply an `allocator` to supply memory. If
655 /// `allocator` is not supplied and if `CONTAINER` is allocator aware, the currently installed default allocator is used.
656 ///
657 /// \note Note that `range` must
658 /// (minimally) meet the requirements of an input range and the values from
659 /// the range must have a type matching or convertible to (template
660 /// parameter) `VALUE`. Also note that the constructor overloads that take
661 /// allocators are defined only if the underlying `CONTAINTER` is allocator
662 /// aware.
663 template <class t_RANGE>
668 const COMPARATOR& comparator = COMPARATOR());
669 template <class t_RANGE, class t_ALLOCATOR>
673 const COMPARATOR& comparator,
674 const t_ALLOCATOR& allocator,
675 typename enable_if<bsl::uses_allocator<CONTAINER,
676 t_ALLOCATOR>::value,
677 t_ALLOCATOR>::type * = 0);
678 template <class t_RANGE, class t_ALLOCATOR>
682 const t_ALLOCATOR& allocator,
683 typename enable_if<bsl::uses_allocator<CONTAINER,
684 t_ALLOCATOR>::value,
685 t_ALLOCATOR>::type * = 0);
686
687 // MANIPULATORS
688
689 /// Assign to this object the value and comparator of the specified
690 /// `rhs` object and return a reference providing modifiable access to
691 /// this object.
693
694 /// Assign to this object the value and comparator of the specified
695 /// `rhs` object and return a reference providing modifiable access to
696 /// this object. `rhs` is left in a valid but unspecified state.
698 BloombergLP::bslmf::MovableRef<priority_queue> rhs)
700
701 /// Insert the specified `value` into this priority queue. In effect,
702 /// performs `c.push_back(value);`.
703 void push(const value_type& value);
704
705 /// Insert the specified `value` into this priority queue. In effect,
706 /// performs `c.push_back(value);`.
707 void push(BloombergLP::bslmf::MovableRef<value_type> value);
708
709 /// Insert the elements of the specified `range` into this priority queue.
710 ///
711 /// \note Note that `range` must meet the requirements of an input range and the
712 /// values from `range` must have a type matching or convertible to
713 /// (template parameter) `VALUE`.
714 template <class t_RANGE>
717
718#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
719 /// Insert into this priority queue a newly created `value_type` object,
720 /// constructed by forwarding the specified (variable number of) `args`
721 /// to the corresponding constructor of `value_type`. In effect,
722 /// performs `c.emplace_back(FORWARD(Args,args)...);`.
723 template <class... Args>
724 void emplace(Args&&... args);
725#endif
726
727 /// Remove the top element from this @ref priority_queue object that has
728 /// the highest priority. In effect, performs `c.pop_back();`.
729 ///
730 /// \pre The behavior is undefined if there is currently no elements in this
731 /// object.
732 void pop();
733
734 /// Efficiently exchange the value of this object with the value of the
735 /// specified `other` object. In effect, performs
736 /// `using bsl::swap; swap(c, other.c);`.
738 bsl::is_nothrow_swappable<CONTAINER>::value &&
739 bsl::is_nothrow_swappable<COMPARATOR>::value);
740
741 // ACCESSORS
742
743 /// Return `true` if this @ref priority_queue object contains no elements,
744 /// and `false` otherwise. In effect, performs `return c.empty();`.
745 bool empty() const;
746
747 /// Return the number of elements in this @ref priority_queue object. In
748 /// effect, performs `return c.size()`.
749 size_type size() const;
750
751 /// Return a reference providing non-modifiable access to the element
752 /// having the highest priority in this @ref priority_queue object. In effect, performs `return c.front()`.
753 ///
754 /// \pre The behavior is undefined if
755 /// the priority queue is empty.
756 const_reference top() const;
757};
758
759#ifdef BSLS_COMPILERFEATURES_SUPPORT_CTAD
760// CLASS TEMPLATE DEDUCTION GUIDES
761
762/// Deduce the template parameter `VALUE` and `CONTAINER` from the
763/// parameters supplied to the constructor of @ref priority_queue .
764template <
765 class COMPARATOR,
766 class CONTAINER,
767 class = bsl::enable_if_t<!bsl::IsStdAllocator_v<CONTAINER>>
768 >
769priority_queue(COMPARATOR, CONTAINER)
771
772/// Deduce the template parameters `VALUE`, `CONTAINER` and `COMPARATOR`
773/// from the parameters supplied to the constructor of @ref priority_queue .
774/// This deduction guide does not participate unless the supplied allocator
775/// is convertible to the underlying container's `allocator_type`.
776template <
777 class COMPARATOR,
778 class CONTAINER,
779 class ALLOCATOR,
780 class = bsl::enable_if_t<bsl::uses_allocator_v<CONTAINER, ALLOCATOR>>
781 >
782priority_queue(COMPARATOR, CONTAINER, ALLOCATOR)
784
785/// Deduce the template parameter `VALUE` from the `value_type` of the
786/// iterators supplied to the constructor of @ref priority_queue .
787template <
788 class INPUT_ITERATOR,
789 class VALUE =
790 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>
791 >
792priority_queue(INPUT_ITERATOR, INPUT_ITERATOR)
794
795/// Deduce the template parameter `VALUE` from the `value_type` of the
796/// iterators supplied to the constructor of @ref priority_queue . Deduce the
797/// template parameters `CONTAINER` and `COMPARATOR` from the other
798/// parameters passed to the constructor.
799template <
800 class INPUT_ITERATOR,
801 class COMPARATOR,
802 class CONTAINER,
803 class VALUE =
804 typename BloombergLP::bslstl::IteratorUtil::IterVal_t<INPUT_ITERATOR>
805 >
806priority_queue(INPUT_ITERATOR, INPUT_ITERATOR, COMPARATOR, CONTAINER)
808
809#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
810/// Deduce the template parameters `VALUE` and `COMPARATOR` from the parameters
811/// supplied to the constructor of @ref priority_queue .
812template <ranges::input_range t_RANGE,
813 class t_COMPARATOR =
814 std::less<ranges::range_value_t<t_RANGE>>,
815 class t_TYPE = ranges::range_value_t<t_RANGE>,
816 class = enable_if_t<!IsStdAllocator_v<t_COMPARATOR>>>
817priority_queue(from_range_t, t_RANGE&&, t_COMPARATOR = t_COMPARATOR())
818-> priority_queue<t_TYPE, vector<t_TYPE>, t_COMPARATOR>;
819
820/// Deduce the template parameters `VALUE`, `COMPARATOR`, and `ALLOCATOR` from
821/// the parameters supplied to the constructor of @ref priority_queue . This
822/// deduction guide does not participate if the `t_ALLOCATOR` parameter does
823/// not meet the requirements for a standard allocator or the `t_COMPARATOR`
824/// parameter meets the requirements for a standard allocator.
825template <ranges::input_range t_RANGE,
826 class t_COMPARATOR,
827 class t_ALLOCATOR,
828 class t_TYPE = ranges::range_value_t<t_RANGE>>
829requires (!IsStdAllocator_v<t_COMPARATOR> && IsStdAllocator_v<t_ALLOCATOR>)
830priority_queue(from_range_t, t_RANGE&&, t_COMPARATOR, t_ALLOCATOR)
832
833/// Deduce the template parameters `VALUE` and `ALLOCATOR` from the parameters
834/// supplied to the constructor of @ref priority_queue . This deduction guide does
835/// not participate unless the `t_ALLOCATOR` parameter meets the requirements
836/// for a standard allocator.
837template <ranges::input_range t_RANGE,
838 class t_ALLOCATOR,
839 class t_TYPE = ranges::range_value_t<t_RANGE>,
840 class = enable_if_t<IsStdAllocator_v<t_ALLOCATOR>>>
841priority_queue(from_range_t, t_RANGE&&, t_ALLOCATOR)
843#endif
844#endif
845
846// FREE FUNCTIONS
847
848/// Exchange the container and comparator of the specified `a` object with
849/// the container and comparator of the specified `b` object.
850template <class VALUE, class CONTAINER, class COMPARATOR>
854
855// ============================================================================
856// TEMPLATE AND INLINE FUNCTION DEFINITIONS
857// ============================================================================
858
859 // --------------------
860 // class priority_queue
861 // --------------------
862
863// CREATORS
864template <class VALUE, class CONTAINER, class COMPARATOR>
865inline
869
870template <class VALUE, class CONTAINER, class COMPARATOR>
871inline
873 const COMPARATOR& comparator)
874: comp(comparator)
875{
876}
877
878template <class VALUE, class CONTAINER, class COMPARATOR>
879inline
881 const COMPARATOR& comparator,
882 const CONTAINER& container)
883: c(container)
884, comp(comparator)
885{
886 std::make_heap(c.begin(), c.end(), comp);
887}
888
889template <class VALUE, class CONTAINER, class COMPARATOR>
890inline
892 const COMPARATOR& comparator,
893 BloombergLP::bslmf::MovableRef<CONTAINER> container)
894: c(MoveUtil::move(container))
895, comp(comparator)
896{
897 std::make_heap(c.begin(), c.end(), comp);
898}
899
900template <class VALUE, class CONTAINER, class COMPARATOR>
901template <class INPUT_ITERATOR>
902inline
904 INPUT_ITERATOR first,
905 INPUT_ITERATOR last)
906{
907 c.insert(c.end(), first, last);
908 std::make_heap(c.begin(), c.end(), comp);
909}
910
911template <class VALUE, class CONTAINER, class COMPARATOR>
912template <class INPUT_ITERATOR>
913inline
915 INPUT_ITERATOR first,
916 INPUT_ITERATOR last,
917 const COMPARATOR& comparator,
918 const CONTAINER& container)
919: c(container)
920, comp(comparator)
921{
922 c.insert(c.end(), first, last);
923 std::make_heap(c.begin(), c.end(), comp);
924}
925
926template <class VALUE, class CONTAINER, class COMPARATOR>
927template <class INPUT_ITERATOR>
928inline
930 INPUT_ITERATOR first,
931 INPUT_ITERATOR last,
932 const COMPARATOR& comparator,
933 BloombergLP::bslmf::MovableRef<CONTAINER> container)
934: c(MoveUtil::move(container))
935, comp(comparator)
936{
937 c.insert(c.end(), first, last);
938 std::make_heap(c.begin(), c.end(), comp);
939}
940
941template <class VALUE, class CONTAINER, class COMPARATOR>
942inline
944 const priority_queue& original)
945: c(original.c)
946, comp(original.comp)
947{
948}
949
950template <class VALUE, class CONTAINER, class COMPARATOR>
951inline
953 BloombergLP::bslmf::MovableRef<priority_queue> original)
954: c(MoveUtil::move(MoveUtil::access(original).c))
955, comp(MoveUtil::access(original).comp)
956{
957}
958
959template <class VALUE, class CONTAINER, class COMPARATOR>
960template <class ALLOCATOR>
961inline
963 const ALLOCATOR& basicAllocator,
964 typename enable_if<
966 ALLOCATOR>::type *)
967: c(basicAllocator)
968, comp(COMPARATOR())
969{
970}
971
972template <class VALUE, class CONTAINER, class COMPARATOR>
973template <class ALLOCATOR>
974inline
976 const COMPARATOR& comparator,
977 const ALLOCATOR& basicAllocator,
978 typename enable_if<
980 ALLOCATOR>::type *)
981: c(basicAllocator)
982, comp(comparator)
983{
984}
985
986template <class VALUE, class CONTAINER, class COMPARATOR>
987template <class ALLOCATOR>
988inline
990 const COMPARATOR& comparator,
991 const CONTAINER& container,
992 const ALLOCATOR& basicAllocator,
993 typename enable_if<
995 ALLOCATOR>::type *)
996: c(container, basicAllocator)
997, comp(comparator)
998{
999 std::make_heap(c.begin(), c.end(), comp);
1000}
1001
1002template <class VALUE, class CONTAINER, class COMPARATOR>
1003template <class ALLOCATOR>
1004inline
1006 const COMPARATOR& comparator,
1007 BloombergLP::bslmf::MovableRef<CONTAINER> container,
1008 const ALLOCATOR& basicAllocator,
1009 typename enable_if<
1011 ALLOCATOR>::type *)
1012: c(MoveUtil::move(container), basicAllocator)
1013, comp(comparator)
1014{
1015 std::make_heap(c.begin(), c.end(), comp);
1016}
1017
1018template <class VALUE, class CONTAINER, class COMPARATOR>
1019template <class ALLOCATOR>
1020inline
1022 const priority_queue& original,
1023 const ALLOCATOR& basicAllocator,
1024 typename enable_if<
1026 ALLOCATOR>::type *)
1027: c(original.c, basicAllocator)
1028, comp(original.comp)
1029{
1030}
1031
1032template <class VALUE, class CONTAINER, class COMPARATOR>
1033template <class ALLOCATOR>
1034inline
1036 BloombergLP::bslmf::MovableRef<priority_queue> original,
1037 const ALLOCATOR& basicAllocator,
1038 typename enable_if<
1040 ALLOCATOR>::type *)
1041: c(MoveUtil::move(MoveUtil::access(original).c), basicAllocator)
1042, comp(MoveUtil::access(original).comp)
1043{
1044}
1045
1046template <class VALUE, class CONTAINER, class COMPARATOR>
1047template <class t_RANGE>
1049inline
1051 from_range_t ,
1052 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1053 const COMPARATOR& comparator)
1054#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_TO_CONTAINER
1055: c(ranges::to<CONTAINER>(std::forward<t_RANGE>(range)))
1056#else
1057: c(from_range, BSLS_COMPILERFEATURES_FORWARD(t_RANGE, range))
1058#endif
1059, comp(comparator)
1060{
1061 std::make_heap(c.begin(), c.end(), comp);
1062}
1063
1064template <class VALUE, class CONTAINER, class COMPARATOR>
1065template <class t_RANGE, class t_ALLOCATOR>
1067inline
1069 from_range_t ,
1070 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1071 const COMPARATOR& comparator,
1072 const t_ALLOCATOR& allocator,
1073 typename enable_if<bsl::uses_allocator<CONTAINER,
1074 t_ALLOCATOR>::value,
1075 t_ALLOCATOR>::type *)
1076#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_TO_CONTAINER
1077: c(ranges::to<CONTAINER>(std::forward<t_RANGE>(range), allocator))
1078#else
1080#endif
1081, comp(comparator)
1082{
1083 std::make_heap(c.begin(), c.end(), comp);
1084}
1085
1086template <class VALUE, class CONTAINER, class COMPARATOR>
1087template <class t_RANGE, class t_ALLOCATOR>
1089inline
1091 from_range_t ,
1092 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range,
1093 const t_ALLOCATOR& allocator,
1094 typename enable_if<bsl::uses_allocator<CONTAINER,
1095 t_ALLOCATOR>::value,
1096 t_ALLOCATOR>::type *)
1097#ifdef BSLS_LIBRARYFEATURES_HAS_CPP23_RANGES_TO_CONTAINER
1098: c(ranges::to<CONTAINER>(std::forward<t_RANGE>(range), allocator))
1099#else
1101#endif
1102{
1103 std::make_heap(c.begin(), c.end(), comp);
1104}
1105
1106// PRIVATE MANIPULATORS
1107template <class VALUE, class CONTAINER, class COMPARATOR>
1108template <class INPUT_ITER, class SENTINEL>
1109inline
1111 INPUT_ITER first,
1112 SENTINEL last)
1113{
1114 while (first != last) {
1115 c.push_back(*first);
1116 ++first;
1117 }
1118}
1119
1120// MANIPULATORS
1121template <class VALUE, class CONTAINER, class COMPARATOR>
1122inline
1123priority_queue<VALUE, CONTAINER, COMPARATOR>&
1125 const priority_queue& rhs)
1126{
1127 c = rhs.c;
1128 comp = rhs.comp;
1129 return *this;
1130}
1131
1132template <class VALUE, class CONTAINER, class COMPARATOR>
1133inline
1136 BloombergLP::bslmf::MovableRef<priority_queue> rhs)
1138{
1139 c = MoveUtil::move(MoveUtil::access(rhs).c);
1140 comp = MoveUtil::access(rhs).comp;
1141 return *this;
1142}
1143
1144template <class VALUE, class CONTAINER, class COMPARATOR>
1145inline
1147 const value_type& value)
1148{
1149 c.push_back(value);
1150 std::push_heap(c.begin(), c.end(), comp);
1151}
1152
1153template <class VALUE, class CONTAINER, class COMPARATOR>
1154inline
1156 BloombergLP::bslmf::MovableRef<value_type> value)
1157{
1158 c.push_back(MoveUtil::move(value));
1159 std::push_heap(c.begin(), c.end(), comp);
1160}
1161
1162template <class VALUE, class CONTAINER, class COMPARATOR>
1163template <class t_RANGE>
1165void priority_queue<VALUE, CONTAINER, COMPARATOR>::push_range(
1166 BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
1167{
1168#if defined(BSLS_LIBRARYFEATURES_HAS_CPP20_RANGES)
1169 if constexpr (requires{ c.append_range(std::forward<t_RANGE>(range)); }) {
1170 c.append_range(std::forward<t_RANGE>(range));
1171 }
1172 else {
1173 ranges::copy(range, back_inserter(c));
1174 }
1175#else
1176 privatePushRange(bsl::begin(range), bsl::end(range));
1177#endif
1178 std::make_heap(c.begin(), c.end(), comp);
1179}
1180
1181#if !BSLS_COMPILERFEATURES_SIMULATE_CPP11_FEATURES
1182template <class VALUE, class CONTAINER, class COMPARATOR>
1183template <class... Args>
1184inline
1186{
1187 c.emplace_back(BSLS_COMPILERFEATURES_FORWARD(Args,args)...);
1188 std::push_heap(c.begin(), c.end(), comp);
1189}
1190#endif
1191
1192template <class VALUE, class CONTAINER, class COMPARATOR>
1193inline
1195{
1196 std::pop_heap(c.begin(), c.end(), comp);
1197 c.pop_back();
1198}
1199
1200template <class VALUE, class CONTAINER, class COMPARATOR>
1201inline
1204 bsl::is_nothrow_swappable<CONTAINER>::value &&
1205 bsl::is_nothrow_swappable<COMPARATOR>::value)
1206{
1207 BloombergLP::bslalg::SwapUtil::swap(&c, &other.c);
1208 BloombergLP::bslalg::SwapUtil::swap(&comp, &other.comp);
1209}
1210
1211// ACCESSORS
1212template <class VALUE, class CONTAINER, class COMPARATOR>
1213inline
1215{
1216 return c.empty();
1217}
1218
1219template <class VALUE, class CONTAINER, class COMPARATOR>
1220inline
1226
1227template <class VALUE, class CONTAINER, class COMPARATOR>
1228inline
1231{
1232 return c.front();
1233}
1234
1235// FREE FUNCTIONS
1236template <class VALUE, class CONTAINER, class COMPARATOR>
1243
1244} // close namespace bsl
1245
1246#endif // End C++11 code
1247
1248#undef BSLSTL_PRIORITY_QUEUE_REQUIRES_CONTAINER_COMPATIBLE_RANGE
1249
1250#endif
1251
1252// ----------------------------------------------------------------------------
1253// Copyright 2016 Bloomberg Finance L.P.
1254//
1255// Licensed under the Apache License, Version 2.0 (the "License");
1256// you may not use this file except in compliance with the License.
1257// You may obtain a copy of the License at
1258//
1259// http://www.apache.org/licenses/LICENSE-2.0
1260//
1261// Unless required by applicable law or agreed to in writing, software
1262// distributed under the License is distributed on an "AS IS" BASIS,
1263// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1264// See the License for the specific language governing permissions and
1265// limitations under the License.
1266// ----------------------------- END-OF-FILE ----------------------------------
1267
1268/** @} */
1269/** @} */
1270/** @} */
Definition bslma_bslallocator.h:588
Definition bslstl_priorityqueue.h:446
size_type size() const
Definition bslstl_priorityqueue.h:1222
void emplace(Args &&... args)
Definition bslstl_priorityqueue.h:1185
void pop()
Definition bslstl_priorityqueue.h:1194
void swap(priority_queue &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(bsl bool empty() const
Definition bslstl_priorityqueue.h:745
COMPARATOR value_compare
Definition bslstl_priorityqueue.h:470
CONTAINER::reference reference
Definition bslstl_priorityqueue.h:472
COMPARATOR comp
Definition bslstl_priorityqueue.h:482
CONTAINER::size_type size_type
Definition bslstl_priorityqueue.h:474
priority_queue()
Definition bslstl_priorityqueue.h:866
void push_range(BSLS_COMPILERFEATURES_FORWARD_REF(t_RANGE) range)
Definition bslstl_priorityqueue.h:1165
CONTAINER::const_reference const_reference
Definition bslstl_priorityqueue.h:473
BSLMF_NESTED_TRAIT_DECLARATION_IF(priority_queue, BloombergLP::bslma::UsesBslmaAllocator, BloombergLP::bslma::UsesBslmaAllocator< container_type >::value)
CONTAINER c
Definition bslstl_priorityqueue.h:478
CONTAINER::value_type value_type
Definition bslstl_priorityqueue.h:471
void push(const value_type &value)
Definition bslstl_priorityqueue.h:1146
const_reference top() const
Definition bslstl_priorityqueue.h:1230
CONTAINER container_type
Definition bslstl_priorityqueue.h:469
priority_queue & operator=(const priority_queue &rhs)
Definition bslstl_priorityqueue.h:1124
Definition bslstl_vector.h:1120
#define BSLMF_ASSERT(expr)
Definition bslmf_assert.h:231
#define BSLS_COMPILERFEATURES_FORWARD_REF(T)
Definition bsls_compilerfeatures.h:2343
#define BSLS_COMPILERFEATURES_FORWARD(T, V)
Definition bsls_compilerfeatures.h:2349
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(...)
Definition bsls_keyword.h:676
#define BSLSTL_PRIORITY_QUEUE_REQUIRES_CONTAINER_COMPATIBLE_RANGE(R, T)
Definition bslstl_priorityqueue.h:412
Definition bdlat_valuetypefunctions.h:939
ALLOCATOR const STRING_VIEW_LIKE_TYPE & rhs
Definition bslstl_string.h:3918
T::iterator begin(T &container)
Definition bslstl_iterator.h:1593
const from_range_t from_range
T::iterator end(T &container)
Definition bslstl_iterator.h:1621
Definition bslmf_enableif.h:530
Definition bslstl_ranges.h:301
Definition bslmf_issame.h:146
Definition bslmf_usesallocator.h:165