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