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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
#ifndef mbl_priority_bounded_queue_h_
#define mbl_priority_bounded_queue_h_
//:
// \file
// \brief Describes a bounded priority queue
// \author Ian Scott
// \date Fri Oct 5 2001
#include <vcl_vector.h>
#include <vcl_functional.h>
#include <vcl_algorithm.h>
//: A bounded priority queue
// This is identical to a vcl_priority_queue, but
// as more elements are added past the queue's bound size
// the largest values are thrown out.
// So this queue keeps the n smallest values that
// are passed to it.
//
// To store the largest values, use vcl_more as the comparator O.
//
// top() returns the value that is closest to being thrown out,
// which is the largest value in the case of the default predicate.
template <class T, class C= vcl_vector<T>, class O= vcl_less<
#ifndef VCL_VC
typename
#endif
C::value_type> >
class mbl_priority_bounded_queue
{
public:
typedef typename C::value_type value_type;
typedef typename C::size_type size_type;
#if defined(VCL_SGI_CC)
typedef vcl_alloc allocator_type; // there is no way to find out second template argument type
#else
typedef typename C::allocator_type allocator_type;
#endif
explicit
mbl_priority_bounded_queue(unsigned bound_size = 10, const O& comp = O()):
b_size_(bound_size), comp_(comp) { }
#if 0 // #if VCL_HAS_MEMBER_TEMPLATES
template <class ITER>
#else
typedef const value_type *ITER;
#endif
//: Construct a bounded priority queue from a controlled sequence.
// The bounded size will be the length of the sequence.
mbl_priority_bounded_queue(
size_type bound_size, ITER first, ITER last, const O& comp = O(),
const allocator_type& alloc = allocator_type()):
b_size_(0), c_(alloc), comp_(comp)
{for (; first != last; ++first) {++b_size_; push(*first);} }
//: The largest size the queue can be before it starts throwing out data.
size_type bound_size() const {return b_size_;}
//: Set the largest size the queue can be before it starts throwing out data.
// If the bound_size is smaller that the current size, then data will be thrown out.
void set_bound_size(size_type bound_size) {
while (bound_size > size()) pop();
b_size_ = bound_size; }
bool empty() const {return c_.empty(); }
size_type size() const {return c_.size(); }
value_type& top() {return c_.front(); }
const value_type& top() const {return c_.front(); }
void push(const value_type & x) {
if (size() >= b_size_)
{
if ( comp_(x, top()) )
pop();
else return;
}
c_.push_back(x);
vcl_push_heap(c_.begin(), c_.end(), comp_); } // ignore purify:UMR error here
// It can be resolved by replacing a comparator object with a function pointer.
// It seems that when using an object, some compilers put a small data marker in
// to represent the object. But it contains no useful data.
// Ignore purify:UMR error on next line as well - same cause.
void pop() {vcl_pop_heap(c_.begin(), c_.end(), comp_); c_.pop_back(); }
protected:
size_type b_size_;
C c_;
O comp_;
};
#endif // mbl_priority_bounded_queue_h_
|