js8call/qpriorityqueue.h

255 lines
6.5 KiB
C
Raw Normal View History

2018-07-13 02:44:31 -04:00
/****************************************************************************
**
** Copyright (C) 2015 Corentin Chary <corentin.chary@gmail.cm>
**
** This file could be part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPRIORITY_QUEUE_H
#define QPRIORITY_QUEUE_H
#include <QtCore/qalgorithms.h>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
QT_MODULE(Core)
template <class T> class QList;
#ifndef QT_NO_STL
#include <queue>
#include <vector>
#else
/* Fallback class used when stl is not available */
template <class T, typename LessThan = qLess < T > >
class QPriorityQueuePrivate {
public:
inline QPriorityQueuePrivate(LessThan l) : lessThan(l), d() {}
inline ~QPriorityQueuePrivate() {}
inline void clear() { return d.clear(); }
inline int size() const { return d.size(); }
inline bool empty() const { return d.empty(); }
inline T &top() { return d.front(); }
void pop();
void push(const T &value);
private:
inline int parent(int i) {
return (i - 1) / 2;
}
inline int leftChild(int i) {
return 2 * i + 1;
}
inline int rightChild(int i) {
return 2 * i + 2;
}
LessThan lessThan;
QList < T > d;
};
#endif
template <class T, typename LessThan = qLess < T > >
class Q_CORE_EXPORT QPriorityQueue
{
public:
inline QPriorityQueue(LessThan l = qLess < T >())
: lessThan(l), d(lessThan) { }
inline QPriorityQueue(const QPriorityQueue<T> &q)
: lessThan(q.lessThan), d(q.d) { }
inline ~QPriorityQueue() { }
QPriorityQueue<T> &operator=(const QPriorityQueue<T> &q) {
d = q.d; return *this;
}
inline int size() const { return d.size(); }
inline bool isEmpty() const { return empty(); }
// like qlist
void clear();
void append(const T &t) { return enqueue(t); }
void append(const QList<T> &t);
T takeFirst() { return dequeue(); }
inline int length() const { return size(); } // Same as count()
inline T& first() { return head(); }
inline const T& first() const { return head(); }
inline void removeFirst() { pop(); }
inline bool startsWith(const T &t) const
{ return !isEmpty() && first() == t; }
// like qqueue
inline void enqueue(const T &t) { push(t); }
inline T dequeue() { T t = d.top(); d.pop(); return t; }
inline T &head() { return const_cast<T&>(top()); }
inline const T &head() const { return top(); }
2018-07-13 02:44:31 -04:00
// stl compatibility
typedef int size_type;
typedef T value_type;
inline bool empty() const { return d.empty(); }
inline const value_type& top() { Q_ASSERT(!isEmpty()); return d.top(); }
inline void push(const value_type& x) { return d.push(x); }
inline void pop() { Q_ASSERT(!isEmpty()); d.pop(); }
// comfort
inline QPriorityQueue<T> &operator+=(const T &t) {
enqueue(t); return *this;
}
inline QPriorityQueue<T> &operator<< (const T &t) {
enqueue(t); return *this;
}
inline QPriorityQueue<T> &operator>> (T &t) {
t = d.top(); d.pop(); return *this;
}
#ifndef QT_NO_STL
static inline QPriorityQueue<T>fromStdPriorityQueue(
const std::priority_queue<T> &q) {
QPriorityQueue<T> tmp; tmp.d = q; return tmp;
}
inline std::priority_queue<T> toStdPriorityQueue() const {
return d;
}
#endif
private:
LessThan lessThan;
#ifndef QT_NO_STL
std::priority_queue <T, std::vector < T >, LessThan> d;
#else
QPriorityQueuePrivate <T> d;
#endif
};
#ifndef QT_NO_STL
template <typename T, typename LessThan>
Q_INLINE_TEMPLATE void QPriorityQueue<T, LessThan>::clear()
{
d = std::priority_queue <T, std::vector < T >, LessThan>(lessThan);
//d = std::priority_queue<T>(lessThan);
2018-07-13 02:44:31 -04:00
}
#else
template <typename T, typename LessThan>
Q_INLINE_TEMPLATE void QPriorityQueue<T, LessThan>::clear()
{
d.clear();
}
#endif
template <typename T, typename LessThan>
Q_OUTOFLINE_TEMPLATE void QPriorityQueue<T, LessThan>::append(const QList<T> &t)
{
foreach (T & e, t)
push(e);
}
// Re-implement std::priority_queue if STL not available, probably
// less efficient.
#ifdef QT_NO_STL
/*!
* Pop an element from the queue and reorder it using an
* inlined binary heap.
*
* \internal
*/
template <typename T, typename LessThan>
Q_OUTOFLINE_TEMPLATE void QPriorityQueuePrivate<T, LessThan>::pop()
{
int i = 0;
ssize_t size = d.size();;
if(!size)
return;
if(size == 1)
return d.clear();
d[0] = d.takeLast();
while(i < size - 1) {
int left = leftChild(i);
int right = rightChild(i);
bool validLeft = left < size;
bool validRight = right < size;
if(validLeft && lessThan(d.at(i), d.at(left)))
if(validRight && !lessThan(d.at(right), d.at(left))) {
d.swap(i, right);
i = right;
} else {
d.swap(i, left);
i = left;
}
else if(validRight && lessThan(d.at(i), d.at(right))) {
d.swap(i, right);
i = right;
}
else
break;
}
}
/*!
* Push an element with a given priority to the right place.
*
* \internal
*/
template <typename T, typename LessThan>
Q_OUTOFLINE_TEMPLATE void QPriorityQueuePrivate<T, LessThan>::push(const T &value)
{
int i = d.size();
d.append(value);
while(i != 0 && !lessThan(d.at(i), d.at(parent(i)))) {
d.swap(i, parent(i));
i = parent(i);
}
}
#endif
QT_END_NAMESPACE
QT_END_HEADER
#endif // QPRIORITY_QUEUE_H