diff --git a/wpilibc/src/main/native/cpp/Watchdog.cpp b/wpilibc/src/main/native/cpp/Watchdog.cpp index 35858b851f..81c7cc88b0 100644 --- a/wpilibc/src/main/native/cpp/Watchdog.cpp +++ b/wpilibc/src/main/native/cpp/Watchdog.cpp @@ -11,8 +11,8 @@ #include #include -#include #include +#include #include #include "frc/DriverStation.h" @@ -34,7 +34,8 @@ class Watchdog::Impl { wpi::mutex m_mutex; std::atomic m_notifier; - wpi::PriorityQueue, DerefGreater> + wpi::priority_queue, + DerefGreater> m_watchdogs; void UpdateAlarm(); @@ -97,8 +98,7 @@ void Watchdog::Impl::Main() { // If the condition variable timed out, that means a Watchdog timeout // has occurred, so call its timeout function. - auto watchdog = m_watchdogs.top(); - m_watchdogs.pop(); + auto watchdog = m_watchdogs.pop(); units::second_t now{curTime * 1e-6}; if (now - watchdog->m_lastTimeoutPrintTime > kMinPrintPeriod) { diff --git a/wpiutil/src/main/native/include/wpi/PriorityQueue.h b/wpiutil/src/main/native/include/wpi/PriorityQueue.h deleted file mode 100644 index 37585a3091..0000000000 --- a/wpiutil/src/main/native/include/wpi/PriorityQueue.h +++ /dev/null @@ -1,40 +0,0 @@ -/*----------------------------------------------------------------------------*/ -/* Copyright (c) 2018 FIRST. All Rights Reserved. */ -/* Open Source Software - may be modified and shared by FRC teams. The code */ -/* must be accompanied by the FIRST BSD license file in the root directory of */ -/* the project. */ -/*----------------------------------------------------------------------------*/ - -#ifndef WPIUTIL_WPI_PRIORITYQUEUE_H_ -#define WPIUTIL_WPI_PRIORITYQUEUE_H_ - -#include -#include -#include -#include - -namespace wpi { - -/** - * This class adds a method for removing all elements from the priority queue - * matching the given value. - */ -template , - class Compare = std::less> -class PriorityQueue : public std::priority_queue { - public: - bool remove(const T& value) { - auto it = std::find(this->c.begin(), this->c.end(), value); - if (it != this->c.end()) { - this->c.erase(it); - std::make_heap(this->c.begin(), this->c.end(), this->comp); - return true; - } else { - return false; - } - } -}; - -} // namespace wpi - -#endif // WPIUTIL_WPI_PRIORITYQUEUE_H_ diff --git a/wpiutil/src/main/native/include/wpi/priority_queue.h b/wpiutil/src/main/native/include/wpi/priority_queue.h new file mode 100644 index 0000000000..b1940903bd --- /dev/null +++ b/wpiutil/src/main/native/include/wpi/priority_queue.h @@ -0,0 +1,118 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2018-2020 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +#ifndef WPIUTIL_WPI_PRIORITY_QUEUE_H_ +#define WPIUTIL_WPI_PRIORITY_QUEUE_H_ + +#include +#include +#include +#include + +namespace wpi { + +/** + * This class is the same as std::priority_queue with two changes: + * + * 1. Adds a remove() function for removing all elements from the priority queue + * that match the given value. + * 2. Replaces "void pop()" with "T pop()" so the element can be moved from the + * queue directly instead of copied from top(). + */ +template , + typename Compare = std::less> +class priority_queue { + public: + static_assert(std::is_same_v, + "value_type must be the same as the underlying container"); + + using value_type = typename Sequence::value_type; + using reference = typename Sequence::reference; + using const_reference = typename Sequence::const_reference; + using size_type = typename Sequence::size_type; + using container_type = Sequence; + using value_compare = Compare; + + template {} && + std::is_default_constructible{}>> + priority_queue() {} + + priority_queue(const Compare& comp, const Sequence& c) : c(c), comp(comp) { + std::make_heap(c.begin(), c.end(), comp); + } + + explicit priority_queue(const Compare& comp, Sequence&& c = Sequence{}) + : c(std::move(c)), comp(comp) { + std::make_heap(c.begin(), c.end(), comp); + } + + template + priority_queue(InputIterator first, InputIterator last, const Compare& comp, + const Sequence& c) + : c(c), comp(comp) { + c.insert(c.end(), first, last); + std::make_heap(c.begin(), c.end(), comp); + } + + template + priority_queue(InputIterator first, InputIterator last, + const Compare& comp = Compare{}, Sequence&& c = Sequence{}) + : c(std::move(c)), comp(comp) { + c.insert(c.end(), first, last); + std::make_heap(c.begin(), c.end(), comp); + } + + [[nodiscard]] bool empty() const { return c.empty(); } + + size_type size() const { return c.size(); } + + const_reference top() const { return c.front(); } + + void push(const value_type& value) { + c.push_back(value); + std::push_heap(c.begin(), c.end(), comp); + } + + void push(value_type&& value) { + c.push_back(std::move(value)); + std::push_heap(c.begin(), c.end(), comp); + } + + template + void emplace(Args&&... args) { + c.emplace_back(std::forward(args)...); + std::push_heap(c.begin(), c.end(), comp); + } + + T pop() { + std::pop_heap(c.begin(), c.end(), comp); + auto ret = std::move(c.back()); + c.pop_back(); + return ret; + } + + bool remove(const T& value) { + auto it = std::find(c.begin(), c.end(), value); + if (it != this->c.end()) { + c.erase(it); + std::make_heap(c.begin(), c.end(), comp); + return true; + } else { + return false; + } + } + + protected: + Sequence c; + Compare comp; +}; + +} // namespace wpi + +#endif // WPIUTIL_WPI_PRIORITY_QUEUE_H_