1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <algorithm>
struct task
{
enum priority_t : unsigned int { IF_TIME_PERMITS = 0, LOW = 1, NORMAL = 2, HIGH = 3, URGENT = 4 };
priority_t priority ; //
std::string description ;
friend std::ostream& operator<< ( std::ostream& stm, task t )
{
static const std::vector<std::string> descr { "IF_TIME_PERMITS", "LOW", "NORMAL", "HIGH", "URGENT" };
if( t.priority < descr.size() ) stm << descr[t.priority] ;
else stm << "*** " << t.priority << " *** (SOS)";
return stm << ": " << t.description ;
}
};
struct task_queue_2d // mult-idimensional queue
{
bool empty() const
{ return std::all_of( pending.begin(), pending.end(), []( auto& q ) { return q.empty() ; } ) ; }
void push( task t )
{
if( t.priority >= pending.size() ) pending.resize( t.priority+1 ) ;
pending[t.priority].push( std::move(t) ) ;
}
task& front() // invariant: !empty()
{
for( auto iter = pending.rbegin() ; iter != pending.rend() ; ++iter )
if( !iter->empty() ) return iter->front() ;
throw std::runtime_error( "empty queue" ) ;
}
void pop() // invariant: !empty()
{
for( auto iter = pending.rbegin() ; iter != pending.rend() ; ++iter )
if( !iter->empty() ) { iter->pop() ; return ; }
}
std::vector< std::queue<task> > pending ;
};
int main()
{
task_queue_2d q2d ;
q2d.push( { task::LOW, "say hello" } ) ;
q2d.push( { task::IF_TIME_PERMITS, "see what is in the lounge" } ) ;
q2d.push( { task::NORMAL, "comment code" } ) ;
q2d.push( { task::HIGH, "peer review" } ) ;
q2d.push( { task::priority_t(9), "make coffee" } ) ;
q2d.push( { task::NORMAL, "improve performance" } ) ;
q2d.push( { task::URGENT, "fix critical bug" } ) ;
q2d.push( { task::LOW, "exploit C++17 features" } ) ;
while( !q2d.empty() )
{
std::cout << q2d.front() << '\n' ;
q2d.pop() ;
}
}
|