WPILibC++ 2027.0.0-alpha-4
Loading...
Searching...
No Matches
UidVector.hpp
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <iterator>
8#include <utility>
9#include <vector>
10
11namespace wpi::util {
12
13namespace impl {
14template <typename It>
16 public:
17 using iterator_type = std::forward_iterator_tag;
18 using value_type = typename It::value_type;
19 using difference_type = typename It::difference_type;
20 using reference = typename It::reference;
21 using pointer = typename It::pointer;
22
23 UidVectorIterator() = default;
24 explicit UidVectorIterator(It it, It end) : m_it(it), m_end(end) {
25 // advance to first non-empty element
26 while (m_it != m_end && !*m_it) {
27 ++m_it;
28 }
29 }
30
31 reference operator*() const noexcept { return *m_it; }
32 pointer operator->() const noexcept { return m_it.operator->(); }
33
35 // advance past empty elements
36 do {
37 ++m_it;
38 } while (m_it != m_end && !*m_it);
39 return *this;
40 }
41
43 UidVectorIterator it = *this;
44 ++it;
45 return it;
46 }
47
48 bool operator==(const UidVectorIterator& oth) const noexcept {
49 return m_it == oth.m_it;
50 }
51
52 bool operator!=(const UidVectorIterator& oth) const noexcept {
53 return m_it != oth.m_it;
54 }
55
56 private:
57 It m_it;
58 It m_end;
59};
60} // namespace impl
61
62/**
63 * Vector which provides an integrated freelist for removal and reuse of
64 * individual elements.
65 *
66 * @tparam T element type; must be default-constructible and evaluate in
67 * boolean context to false when "empty"
68 * @tparam reuse_threshold how many free elements to store up before starting
69 * to recycle them
70 */
71template <typename T, typename std::vector<T>::size_type reuse_threshold>
72class UidVector {
73 public:
74 using value_type = T;
75 using pointer = T*;
76 using const_pointer = const T*;
77 using reference = T&;
78 using const_reference = const T&;
79 using size_type = typename std::vector<T>::size_type;
80 using difference_type = typename std::vector<T>::difference_type;
84
85 bool empty() const noexcept { return m_active_count == 0; }
86 size_type size() const noexcept { return m_vector.size(); }
87 T& operator[](size_type i) { return m_vector[i]; }
88 const T& operator[](size_type i) const { return m_vector[i]; }
89
90 // Add a new T to the vector. If there are elements on the freelist,
91 // reuses the last one; otherwise adds to the end of the vector.
92 // Returns the resulting element index.
93 template <class... Args>
94 size_type emplace_back(Args&&... args) {
95 size_type uid;
96 if (m_free.size() < reuse_threshold) {
97 uid = m_vector.size();
98 m_vector.emplace_back(std::forward<Args>(args)...);
99 } else {
100 uid = m_free.front();
101 m_free.erase(m_free.begin());
102 m_vector[uid] = T(std::forward<Args>(args)...);
103 }
104 ++m_active_count;
105 return uid;
106 }
107
108 /**
109 * Removes the identified element by replacing it with a default-constructed
110 * one. The element is added to the freelist for later reuse.
111 */
113 if (uid >= m_vector.size() || !m_vector[uid]) {
114 return T();
115 }
116 m_free.push_back(uid);
117 auto rv = std::move(m_vector[uid]);
118 m_vector[uid] = T();
119 --m_active_count;
120 return rv;
121 }
122
123 /**
124 * Removes all elements.
125 */
126 void clear() noexcept {
127 m_vector.clear();
128 m_free.clear();
129 m_active_count = 0;
130 }
131
132 // Iterator access
133 iterator begin() noexcept {
134 return iterator(m_vector.begin(), m_vector.end());
135 }
136 const_iterator begin() const noexcept {
137 return const_iterator(m_vector.begin(), m_vector.end());
138 }
139 const_iterator cbegin() const noexcept {
140 return const_iterator(m_vector.begin(), m_vector.end());
141 }
142 iterator end() noexcept { return iterator(m_vector.end(), m_vector.end()); }
143 const_iterator end() const noexcept {
144 return const_iterator(m_vector.end(), m_vector.end());
145 }
146 const_iterator cend() const noexcept {
147 return const_iterator(m_vector.end(), m_vector.end());
148 }
149
150 private:
151 std::vector<T> m_vector;
152 std::vector<size_type> m_free;
153 size_type m_active_count{0};
154};
155
156} // namespace wpi::util
Vector which provides an integrated freelist for removal and reuse of individual elements.
Definition UidVector.hpp:72
const_iterator end() const noexcept
Definition UidVector.hpp:143
T value_type
Definition UidVector.hpp:74
const_iterator cbegin() const noexcept
Definition UidVector.hpp:139
typename std::vector< T >::size_type size_type
Definition UidVector.hpp:79
void clear() noexcept
Removes all elements.
Definition UidVector.hpp:126
T erase(size_type uid)
Removes the identified element by replacing it with a default-constructed one.
Definition UidVector.hpp:112
size_type size() const noexcept
Definition UidVector.hpp:86
impl::UidVectorIterator< typename std::vector< T >::iterator > iterator
Definition UidVector.hpp:81
T & operator[](size_type i)
Definition UidVector.hpp:87
size_type emplace_back(Args &&... args)
Definition UidVector.hpp:94
const T & operator[](size_type i) const
Definition UidVector.hpp:88
bool empty() const noexcept
Definition UidVector.hpp:85
const T * const_pointer
Definition UidVector.hpp:76
iterator begin() noexcept
Definition UidVector.hpp:133
typename std::vector< T >::difference_type difference_type
Definition UidVector.hpp:80
const T & const_reference
Definition UidVector.hpp:78
const_iterator begin() const noexcept
Definition UidVector.hpp:136
T & reference
Definition UidVector.hpp:77
iterator end() noexcept
Definition UidVector.hpp:142
impl::UidVectorIterator< typename std::vector< T >::const_iterator > const_iterator
Definition UidVector.hpp:82
const_iterator cend() const noexcept
Definition UidVector.hpp:146
T * pointer
Definition UidVector.hpp:75
Definition UidVector.hpp:15
UidVectorIterator(It it, It end)
Definition UidVector.hpp:24
UidVectorIterator & operator++() noexcept
Definition UidVector.hpp:34
UidVectorIterator operator++(int) noexcept
Definition UidVector.hpp:42
pointer operator->() const noexcept
Definition UidVector.hpp:32
reference operator*() const noexcept
Definition UidVector.hpp:31
bool operator==(const UidVectorIterator &oth) const noexcept
Definition UidVector.hpp:48
typename It::difference_type difference_type
Definition UidVector.hpp:19
typename It::pointer pointer
Definition UidVector.hpp:21
typename It::reference reference
Definition UidVector.hpp:20
typename It::value_type value_type
Definition UidVector.hpp:18
std::forward_iterator_tag iterator_type
Definition UidVector.hpp:17
bool operator!=(const UidVectorIterator &oth) const noexcept
Definition UidVector.hpp:52
Definition UidVector.hpp:13
Definition raw_os_ostream.hpp:19