#ifndef _DATASTRUCTURES_H #define _DATASTRUCTURES_H // // This file is distributed under the MIT License. See LICENSE.md for details. // // Standard includes #include #include #include #include #include /// \brief Queue where an element cannot be re-inserted if it's already in the /// queue template 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 head() const { return Queue.front(); } T pop() { T Result = head(); Queue.pop(); if (!Once) Set.erase(Result); return Result; } size_t size() const { return Queue.size(); } std::set visited() { assert(Once); return std::move(Set); } void clear() { std::set().swap(Set); std::queue().swap(Queue); } private: std::set Set; std::queue Queue; }; template using UniquedQueue = QueueImpl; template using OnceQueue = QueueImpl; /// \brief Stack where an element cannot be re-inserted in it's already in the /// stack template 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 Set; std::vector Queue; }; template static inline void freeContainer(T &Container) { T Empty; Empty.swap(Container); } #endif // _DATASTRUCTURES_H