mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-27 02:01:42 +00:00
wpiutil UidVector: Implement clear() and forward iterator (#1293)
The forward iterator only iterates over "live" elements. Also add a couple of unit tests for UidVector.
This commit is contained in:
@@ -8,11 +8,59 @@
|
||||
#ifndef WPIUTIL_WPI_UIDVECTOR_H_
|
||||
#define WPIUTIL_WPI_UIDVECTOR_H_
|
||||
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace wpi {
|
||||
|
||||
namespace impl {
|
||||
template <typename It>
|
||||
class UidVectorIterator {
|
||||
public:
|
||||
using iterator_type = std::forward_iterator_tag;
|
||||
using value_type = typename It::value_type;
|
||||
using difference_type = typename It::difference_type;
|
||||
using reference = typename It::reference;
|
||||
using pointer = typename It::pointer;
|
||||
|
||||
UidVectorIterator() = default;
|
||||
explicit UidVectorIterator(It it, It end) : m_it(it), m_end(end) {
|
||||
// advance to first non-empty element
|
||||
while (m_it != m_end && !*m_it) ++m_it;
|
||||
}
|
||||
|
||||
reference operator*() const noexcept { return *m_it; }
|
||||
pointer operator->() const noexcept { return m_it.operator->(); }
|
||||
|
||||
UidVectorIterator& operator++() noexcept {
|
||||
// advance past empty elements
|
||||
do {
|
||||
++m_it;
|
||||
} while (m_it != m_end && !*m_it);
|
||||
return *this;
|
||||
}
|
||||
|
||||
UidVectorIterator operator++(int)noexcept {
|
||||
UidVectorIterator it = *this;
|
||||
++it;
|
||||
return it;
|
||||
}
|
||||
|
||||
bool operator==(const UidVectorIterator& oth) const noexcept {
|
||||
return m_it == oth.m_it;
|
||||
}
|
||||
|
||||
bool operator!=(const UidVectorIterator& oth) const noexcept {
|
||||
return m_it != oth.m_it;
|
||||
}
|
||||
|
||||
private:
|
||||
It m_it;
|
||||
It m_end;
|
||||
};
|
||||
} // namespace impl
|
||||
|
||||
// Vector which provides an integrated freelist for removal and reuse of
|
||||
// individual elements.
|
||||
// @tparam T element type; must be default-constructible and evaluate in
|
||||
@@ -22,7 +70,16 @@ namespace wpi {
|
||||
template <typename T, typename std::vector<T>::size_type reuse_threshold>
|
||||
class UidVector {
|
||||
public:
|
||||
typedef typename std::vector<T>::size_type size_type;
|
||||
using value_type = T;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
using size_type = typename std::vector<T>::size_type;
|
||||
using difference_type = typename std::vector<T>::difference_type;
|
||||
using iterator = impl::UidVectorIterator<typename std::vector<T>::iterator>;
|
||||
using const_iterator =
|
||||
impl::UidVectorIterator<typename std::vector<T>::const_iterator>;
|
||||
|
||||
bool empty() const { return m_active_count == 0; }
|
||||
size_type size() const { return m_vector.size(); }
|
||||
@@ -56,6 +113,31 @@ class UidVector {
|
||||
--m_active_count;
|
||||
}
|
||||
|
||||
// Removes all elements.
|
||||
void clear() {
|
||||
m_vector.clear();
|
||||
m_free.clear();
|
||||
m_active_count = 0;
|
||||
}
|
||||
|
||||
// Iterator access
|
||||
iterator begin() noexcept {
|
||||
return iterator(m_vector.begin(), m_vector.end());
|
||||
}
|
||||
const_iterator begin() const noexcept {
|
||||
return const_iterator(m_vector.begin(), m_vector.end());
|
||||
}
|
||||
const_iterator cbegin() const noexcept {
|
||||
return const_iterator(m_vector.begin(), m_vector.end());
|
||||
}
|
||||
iterator end() noexcept { return iterator(m_vector.end(), m_vector.end()); }
|
||||
const_iterator end() const noexcept {
|
||||
return const_iterator(m_vector.end(), m_vector.end());
|
||||
}
|
||||
const_iterator cend() const noexcept {
|
||||
return const_iterator(m_vector.end(), m_vector.end());
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T> m_vector;
|
||||
std::vector<size_type> m_free;
|
||||
|
||||
Reference in New Issue
Block a user