Files
revng-revng/datastructures.h
T
Alessandro Di Federico 1254f400c3 Introduce OnceQueue
`OnceQueue` is a queue which not only keeps track of what's already in
the queue and prevents it from being re-inserted, but also keeps track
of what has ever been in the queue, and prevents it from returning to
the queue.

`OnceQueue` is implemented by adding a new template parameter to what
was once `UniquedQueue`.
2016-09-17 15:33:55 +02:00

89 lines
1.6 KiB
C++

#ifndef _DATASTRUCTURES_H
#define _DATASTRUCTURES_H
// Standard includes
#include <queue>
#include <set>
#include <stack>
/// \brief Queue where an element cannot be re-inserted if it's already in the
/// queue
template<typename T, bool Once>
class QueueImpl {
public:
void insert(T Element) {
if (Set.count(Element) == 0) {
assert(Element->getParent() != nullptr);
Set.insert(Element);
Queue.push(Element);
}
}
bool empty() const {
return Queue.empty();
}
T pop() {
T Result = Queue.front();
Queue.pop();
if (!Once)
Set.erase(Result);
return Result;
}
size_t size() const { return Queue.size(); }
std::set<T> visited() {
assert(Once);
return std::move(Set);
}
private:
std::set<T> Set;
std::queue<T> Queue;
};
template<typename T>
using UniquedQueue = QueueImpl<T, false>;
template<typename T>
using OnceQueue = QueueImpl<T, true>;
/// \brief Stack where an element cannot be re-inserted in it's already in the
/// stack
template<typename T>
class UniquedStack {
public:
void insert(T Element) {
if (Set.count(Element) == 0) {
assert(Element->getParent() != nullptr);
Set.insert(Element);
Queue.push_back(Element);
}
}
bool empty() const {
return Queue.empty();
}
T pop() {
T Result = Queue.back();
Queue.pop_back();
Set.erase(Result);
return Result;
}
/// \brief Reverses the stack in its current status
void reverse() {
std::reverse(Queue.begin(), Queue.end());
}
size_t size() const { return Queue.size(); }
private:
std::set<T> Set;
std::vector<T> Queue;
};
#endif // _DATASTRUCTURES_H