AI 24/25 Project Software
Documentation for the AI 24/25 course programming project software
Loading...
Searching...
No Matches
named_vector.h
1#ifndef ALGORITHMS_NAMED_VECTOR_H
2#define ALGORITHMS_NAMED_VECTOR_H
3
4#include <cassert>
5#include <string>
6#include <vector>
7
8namespace named_vector {
9/*
10 NamedVector is a vector-like collection with optional names
11 associated with each element. It is intended for attaching names
12 to objects in vectors for debugging purposes and is optimized
13 to have minimal overhead when there are no names. Any name which is
14 not specified is the empty string. Accessing a name with
15 an invalid index will result in an error in debug mode.
16 */
17template <typename T>
18class NamedVector {
19 std::vector<T> elements;
20 std::vector<std::string> names;
21
22public:
23 template <typename... _Args>
24 T& emplace_back(_Args&&... __args)
25 {
26 return elements.emplace_back(std::forward<_Args>(__args)...);
27 }
28
29 void push_back(const T& element) { elements.push_back(element); }
30
31 void push_back(T&& element) { elements.push_back(std::move(element)); }
32
33 T& operator[](int index) { return elements[index]; }
34
35 const T& operator[](int index) const { return elements[index]; }
36
37 bool has_names() const { return !names.empty(); }
38
39 void set_name(int index, const std::string& name)
40 {
41 assert(index >= 0 && index < size());
42 int num_names = names.size();
43 if (index >= num_names) {
44 if (name.empty()) {
45 // All unspecified names are empty by default.
46 return;
47 }
48 names.resize(index + 1, "");
49 }
50 names[index] = name;
51 }
52
53 const std::string& get_name(int index) const
54 {
55 assert(index >= 0 && index < size());
56 int num_names = names.size();
57 if (index < num_names) {
58 return names[index];
59 } else {
60 /*
61 All unspecified names are empty by default. We use a static
62 string here to avoid returning a reference to a local object.
63 */
64 static std::string empty;
65 return empty;
66 }
67 }
68
69 int size() const { return elements.size(); }
70
71 bool empty() const { return elements.empty(); }
72
73 typename std::vector<T>::reference back() { return elements.back(); }
74
75 typename std::vector<T>::iterator begin() { return elements.begin(); }
76
77 typename std::vector<T>::iterator end() { return elements.end(); }
78
79 typename std::vector<T>::const_iterator begin() const
80 {
81 return elements.begin();
82 }
83
84 typename std::vector<T>::const_iterator end() const
85 {
86 return elements.end();
87 }
88
89 void clear()
90 {
91 elements.clear();
92 names.clear();
93 }
94
95 void reserve(int capacity)
96 {
97 /* No space is reserved in the names vector because it is kept
98 at minimal size and space is only used when necessary. */
99 elements.reserve(capacity);
100 }
101
102 void resize(int count)
103 {
104 /* The names vector is not resized because it is kept
105 at minimal size and only resized when necessary. */
106 elements.resize(count);
107 }
108
109 void resize(int count, const T& value)
110 {
111 /* The names vector is not resized because it is kept
112 at minimal size and only resized when necessary. */
113 elements.resize(count, value);
114 }
115};
116} // namespace named_vector
117
118#endif