cgal/Spatial_searching/include/CGAL/internal/bounded_priority_queue.h

141 lines
3.3 KiB
C++

// Copyright (c) 2007-10 INRIA (FRANCE).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Gael Guennebaud (gael.guennebaud@inria.fr)
#ifndef CGAL_INTERNAL_BOUNDED_PRIORITY_QUEUE_H
#define CGAL_INTERNAL_BOUNDED_PRIORITY_QUEUE_H
#include <CGAL/license/Spatial_searching.h>
#include <vector>
#include <functional>
#include <algorithm>
#include <boost/next_prior.hpp>
namespace CGAL {
namespace internal{
/**
* A priority queue with fixed maximum capacity.
* While the queue has not reached its maximum capacity, elements are
* inserted as they will be in a heap, the root (top()) being such that
* Compare(top(),x)=false for any x in the queue.
* Once the queue is full, trying to insert x in the queue will have no effect if
* Compare(x,top())=false. Otherwise, the element at the root of the heap is removed
* and x is inserted so as to keep the heap property.
*/
template <typename T, typename Compare = std::less<T> >
class bounded_priority_queue
{
public:
typedef T value_type;
typedef typename std::vector<value_type>::const_iterator const_iterator;
bounded_priority_queue(const Compare& comp = Compare())
: m_comp(comp)
{}
bounded_priority_queue(int size, const Compare& comp = Compare())
: m_count(0), m_data(size), m_comp(comp)
{}
/** Sets the max number of elements in the queue */
void resize(int new_size)
{
if (m_data.size()!=new_size)
m_data.resize(new_size);
clear();
}
/** \returns the number of elements in the queue */
inline unsigned int size() const { return m_count; }
/** Removes all elements of the queue. The max size remains unchanged. */
inline void clear() { m_count = 0; }
inline bool full() const { return m_count == m_data.size(); }
inline bool empty() const { return m_count == 0; }
/** \returns greatest element */
inline const value_type& top() const { return m_data[0]; }
inline void insert(const value_type& x)
{
value_type* data1 = (&m_data[0]-1);
if (full())
{
if (m_comp(x, top()))
{
//insert x in the heap at the correct place,
//going down in the tree.
unsigned int j(1), k(2);
while (k <= m_count)
{
value_type* z = &(data1[k]);
if ((k < m_count) && m_comp(*z, data1[k+1]))
z = &(data1[++k]);
if (m_comp(*z, x))
break;
data1[j] = *z;
j = k;
k = j << 1; //a son of j in the tree
}
data1[j] = x;
}
}
else
{
//insert element as in a heap
int i(++m_count), j;
while (i >= 2)
{
j = i >> 1; //father of i in the tree
value_type& y = data1[j];
if (m_comp(x, y))
break;
data1[i] = y;
i = j;
}
data1[i] = x;
}
}
const_iterator begin() const { return m_data.begin(); }
const_iterator end() const
{
const_iterator res = m_data.begin();
res += m_count;
return res;
}
void sort()
{
std::sort(m_data.begin(), boost::next(m_data.begin(),m_count), m_comp);
}
protected:
unsigned int m_count;
std::vector<value_type> m_data;
Compare m_comp;
};
} } //namespace CGAL::internal
#endif //CGAL_INTERNAL_BOUNDED_PRIORITY_QUEUE_H