BDE 4.14.0 Production release
|
Provide container adapter class template priority_queue .
Canonical header: bsl_queue.h
This component defines a class template, bsl::priority_queue
, holding a container (of a template parameter type, CONTAINER
, containing elements of another template parameter type, VALUE
), and adapting it to provide highest-priority-first priority queue data structure. The component takes a third template parameter type, COMPARATOR
, for customized priorities comparison between two elements.
An instantiation of priority_queue is an allocator-aware, value-semantic type whose salient attributes are its size (number of held elements) and the sorted sequence of values (of held elements). If priority_queue is instantiated with a value type, that is not itself value-semantic, then it will not retain all of its value-semantic qualities. A priority_queue cannot be tested for equality, but its value type must be able to be tested for comparing less by its comparator type.
The priority_queue implemented here adheres to the C++11 standard when compiled with a C++11 compiler, and makes the best approximation when compiled with a C++03 compiler. In particular, for C++03 we emulate move semantics, but limit forwarding (in emplace
) to const
lvalues, and make no effort to emulate noexcept
or initializer-lists.
The type supplied as an ALLOCATOR
template parameter in some of priority_queue constructors determines how the held container (of the (template parameter) type CONTAINER
) will allocate memory. A priority_queue supports allocators meeting the requirements of the C++11 standard [17.6.3.5] as long as the held container does. In addition it supports scoped-allocators derived from the bslma::Allocator
memory allocation protocol. Clients intending to use bslma
-style allocators should use bsl::allocator
as the ALLOCATOR
template parameter, providing a C++11 standard-compatible adapter for a bslma::Allocator
object.
When the CONTAINER
template parameter is omitted the VALUE
template parameter specifies the value_type
of bsl::vector
, the default container type. The VALUE
template has no other role.
For C++17 and later, the behavior is undefined unless:
Prior to C++17, CONTAINER::value_type
determines the contained value type and VALUE
is simply ignored. The resulting code may work with instances of VALUE
(e.g., VALUE
is convertible to CONTAINER::value_type
) or not (compiler errors).
The C++11 standard [23.6.4] declares any container type supporting operations front
, push_back
, and pop_back can be used to instantiate the (template parameter) type CONTAINER
. Below is a list of public methods of priority_queue class that are effectively implemented as calling the corresponding operations in the held container (referenced as c
).
In this section we show intended use of this component.
In this example, we will use the bsl::priority_queue
class to implement a task scheduler that schedules a group of tasks based on their designated priorities.
Suppose we want to write a background process that runs tasks needed by foreground applications. Each task has a task id, a priority, and a function pointer that can be invoked by the background process. This background process has two threads: one thread (receiving thread) receives requests from other applications, passing required tasks to a task scheduler; the other thread (processing thread) runs the task scheduler, executing the tasks one-by-one from higher to lower priorities. To implement this functionality, we can use bsl::priority_queue
in the task scheduler to buffer received, but as yet unprocessed, tasks. The task scheduler adds newly received tasks into the priority queue in the receiving thread, and extracts tasks from the priority queue for execution according to their priorities in the processing thread.
First, we define a TaskFunction
type:
Then, we define a Task
class, which contains a task id, a TaskFunction
object and an associated task priority:
Next, we define a functor to compare the priorities of two Task
objects:
Then, we define a TaskScheduler
class that provides methods to hold and schedule unprocessed tasks:
Here, we define a private data member that is an instantiation of bsl::priority_queue
, which uses Task
for its VALUE
(template parameter) type, bsl::vector<Task>
for its CONTAINER
(template parameter) type, and TaskComparator
for its COMPARATOR
(template parameter) type:
Next, we implement the TaskScheduler
constructor:
Notice that we pass to the contained d_taskPriorityQueue
object the bslma::Allocator
supplied to the TaskScheduler
at construction.
Then, we implement the addTask
method, which constructs a Task
object and adds it into the priority queue:
Next, we implement the processTasks
method, which extracts tasks from the priority queue in order of descending priorities, and executes them:
Note that the top
method always returns the Task
object having the highest priority in the priority queue.
Then, we define two task functions:
Next, we create a global TaskScheduler
object:
Now, we call the addTask
method of taskScheduler
in the receiving thread:
Finally, we call the processTasks
method of taskScheduler
in the processing thread: