#include <algorithm>
#include <iterator>
template<class queueT>
struct fixed_size_queue_iterator {
using value_type = typename queueT::value_type;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using reference = value_type&;
using iterator_category = std::output_iterator_tag;
using value_compare = typename queueT::value_compare;
fixed_size_queue_iterator(queueT& queue, std::size_t max_size)
: queue_(&queue), max_size_(max_size), comp_() {}
fixed_size_queue_iterator& operator=(const fixed_size_queue_iterator& it) {
queue_ = it.queue_;
max_size_ = it.max_size_;
comp_ = it.comp_;
}
fixed_size_queue_iterator& operator=(const value_type& v) {
if (queue_->size()<max_size_ || comp_(queue_->top(), v)) {
queue_->pop();
queue_->push(v);
}
return *this;
}
fixed_size_queue_iterator& operator=(value_type&& v) {
if (queue_->size()<max_size_ || comp_(queue_->top(), v)) {
queue_->pop();
queue_->push(std::move(v));
}
return *this;
}
fixed_size_queue_iterator& operator*() {return *this;}
fixed_size_queue_iterator& operator++() {return *this;}
fixed_size_queue_iterator& operator++(int) {return *this;}
private:
queueT* queue_;
std::size_t max_size_;
value_compare comp_;
};
template<class queueT>
fixed_size_queue_iterator<queueT> fixed_size_queue_inserter(queueT& queue, std::size_t max_size) {
return {queue,max_size};
}
template<class queueT>
struct pop_queue_iterator {
using value_type = typename queueT::value_type;
using difference_type = std::ptrdiff_t;
using pointer = value_type*;
using const_pointer = const value_type*;
using reference = value_type&;
using const_reference = const value_type&;
using iterator_category = std::output_iterator_tag;
pop_queue_iterator() : queue_(nullptr) {}
pop_queue_iterator(queueT& queue) : queue_(&queue) {}
const_reference operator*() {return queue_->top();}
const_pointer operator->() {return &queue_->top();}
pop_queue_iterator& operator++() {queue_->pop(); return *this;}
pop_queue_iterator& operator++(int) {queue_->pop(); return *this;}
bool operator==(const pop_queue_iterator& it) const {return empty()==it.empty();}
bool operator!=(const pop_queue_iterator& it) const {return empty()!=it.empty();}
private:
queueT* queue_;
bool empty() const {return queue_==nullptr||queue_->empty();}
};
template<class queueT>
pop_queue_iterator<queueT> pop_queue_begin_iterator(queueT& queue) {
return {queue};
}
template<class queueT>
pop_queue_iterator<queueT> pop_queue_end_iterator(queueT&) {
return {};
}
#include <iostream>
#include <queue>
int main() {
int random[] = {5, 7, 3, 1, 9, 8, 4, 0, 2, 6};
std::priority_queue<int,std::vector<int>,std::greater<int>> queue;
std::copy(std::begin(random), std::end(random), fixed_size_queue_inserter(queue, 4));
std::copy(pop_queue_begin_iterator(queue), pop_queue_end_iterator(queue), std::ostream_iterator<int>(std::cout," "));
}