::fast_io::vector
1. What is a vector?
A ::fast_io::vector<T> stores a sequence of elements of type T.
It grows automatically when you add more items, and all elements stay together in one continuous block of memory.
You can think of it as a “growing list of values” that keeps everything tightly packed.
2. Creating a vector
You can create an empty vector or one with an initial size:
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> a; // empty
::fast_io::vector<std::size_t> b(5zu); // 5 default-initialized elements
::fast_io::vector<std::size_t> c(3zu, 42zu); // 3 copies of value 42
println("b size = ", b.size());
println("c[0] = ", c[0]);
}
3. Adding elements
The most common way to add elements is push_back():
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> v;
v.push_back(10zu);
v.push_back(20zu);
v.push_back(30zu);
println("Size: ", v.size()); // 3
}
When the vector runs out of space, it automatically allocates more memory.
4. Accessing elements safely
You can access elements using front(), back(), or operator[]:
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> v{1zu, 2zu, 3zu, 4zu};
println("Front: ", v.front()); // 1
println("Back: ", v.back()); // 4
println("Index 2: ", v[2]); // 3
}
⚠️ Safety note: If you access an element that does not exist (for example, calling
v.front() on an empty vector or using an out-of-range index), fast_io performs a
boundary check. If the check fails, the program stops immediately using __builtin_trap().
Safe usage
if(!v.is_empty()) {
println("Front: ", v.front());
}
std::size_t i = 2zu;
if(i < v.size()) {
println("v[2] = ", v[i]);
}
5. Iterating through elements
Preferred: Range‑based for loop
This is the simplest way to go through all elements:
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> v{10zu, 20zu, 30zu};
for(std::size_t x : v) {
println(x);
}
}
Alternative: Index loop
Useful when you need the position:
for(std::size_t i{}, n{v.size()}; i != n; ++i) {
println("Index ", i, ": ", v[i]);
}
Advanced: Iterators
In Section 3.1 (string iterators), we introduced the idea that an iterator behaves like a pointer
into a container’s memory. A ::fast_io::vector<T> uses the same iterator model
as ::fast_io::string.
This means:
- iterators are contiguous and support arithmetic (
+/-,[], comparisons) - iteration uses a left‑inclusive, right‑exclusive range:
[begin(), end()) - stepping outside this range is undefined behavior
- iterators become invalid if the vector reallocates (for example, after
push_back()when full)
Example:
#include <fast_io.h>
#include <fast_io_dsal/vector.h>
int main() {
using namespace ::fast_io::iomnp;
::fast_io::vector<std::size_t> v{10zu, 20zu, 30zu};
for(auto it = v.begin(), ed = v.end(); it != ed; ++it) {
println(*it);
}
}
Iterator arithmetic
Just like with strings, vector iterators allow random‑access operations:
auto it = v.begin(); // first element
println(*(it + 1)); // move forward
println((it + 2)[0]); // same as v[2]
println((it + 2)[-1]); // move backward from a valid position
These operations are fast, but they do not check bounds.
Iterator invalidation
Any operation that causes the vector to grow may reallocate its storage. When this happens, all existing iterators become invalid.
auto it2 = v.begin();
v.push_back(999zu); // may reallocate
// ⚠️ it2 may now point to old memory
// println(*it2); // undefined behavior
If you need to keep positions across reallocation, store an index instead of an iterator.
6. Removing elements
pop_back()
Removes the last element:
v.pop_back();
⚠️ Calling pop_back() on an empty vector stops the program immediately.
7. Clearing and releasing memory
clear()
Removes all elements but keeps the allocated memory. This is useful when you plan to reuse the vector soon.
v.clear();
println(v.size()); // 0
clear_destroy()
Removes all elements and releases the memory back to the allocator. After this call, the vector becomes completely empty with no storage.
v.clear_destroy(); // memory returned to allocator
println(v.size()); // 0
Use clear_destroy() when you are done with the vector and want to free its memory.
Key takeaways
::fast_io::vector<T>stores a growing sequence of tightly packed elements.push_back()adds new items and expands storage automatically when needed.front(),back(), andoperator[]give fast access, but require manual bounds checking.- Vector iterators behave exactly like string iterators: contiguous, arithmetic‑friendly, and using
[begin(), end()). clear()removes elements but keeps memory;clear_destroy()removes elements and frees memory.