Ch9.5: Unchecked Operations
Overview
Every checked operation has a corresponding _unchecked variant
that skips bounds checking. Use these only when you have already verified
that the index or condition is valid. Using an unchecked operation with
invalid arguments is undefined behaviour.
1. Unchecked Operation Table
| Checked (safe) | Unchecked (fast) | Applies to |
|---|---|---|
operator[](idx) |
index_unchecked(idx) |
vector, deque, array, span, index_span, string_view |
front() |
front_unchecked() |
All owning containers, span, string_view |
back() |
back_unchecked() |
All except forward_list |
pop_back() |
pop_back_unchecked() |
vector, deque, list, bitvec |
pop_front() |
pop_front_unchecked() |
deque, list, forward_list |
push_back() |
push_back_unchecked() |
vector, bitvec |
emplace_back() |
emplace_back_unchecked() |
vector |
2. Example: reserve + push_back_unchecked
#include <fast_io_dsal/vector.h>
#include <fast_io.h>
int main() {
::fast_io::vector<::std::size_t> v;
v.reserve(100zu); // Pre-allocate space for 100 elements
// Safe: push_back checks capacity and may reallocate
v.push_back(42zu);
// Fast: assumes capacity is available (we just reserved 100)
for (::std::size_t i{}; i < 50zu; ++i) {
v.push_back_unchecked(i); // No capacity check
}
}
Tip: Use
reserve() + push_back_unchecked()
in tight loops where you know the final size. This avoids repeated capacity
checks and is significantly faster than calling push_back()
in a loop.
Key takeaways
- Every checked operation has an
_uncheckedcounterpart. - Unchecked operations skip bounds/capacity checks — undefined behaviour on invalid input.
- Use
reserve()+push_back_unchecked()for fast bulk insertion. - Only use unchecked operations when you can prove the preconditions hold.