
What
An implementation of zip for C++17. Single header file.
Why
Learning purposes.
Status
In development. Needs proper testing.
Install
Integrate with CMake or just copy the header file.
Usage and Documentation
{c++}
#include <msd/zip.hpp>
#include <algorithm>
#include <cassert>
#include <vector>
int main() {
std::vector actual_numbers = {1, 2, 3};
std::vector expected_numbers = {1, 2, 3};
const std::size_t size = std::min(actual_numbers.size(), expected_numbers.size());
for (std::size_t i = 0; i < size; ++i) {
assert(actual_numbers[i] == expected_numbers[i]);
}
// vs
for (auto [actual, expected] : msd::zip(actual_numbers, expected_numbers)) {
assert(actual == expected);
}
}
For more, see tests and documentation.
Known issues
Calling std::prev on an msd::zip object compiles, but fails at runtime on some std containers.
- list
- forward_list
- unordered_set
- unordered_multiset
- unordered_map
- unordered_multimap
The msd::zip
iterator is bidirectional to better control when you want to stop iterating.
To get only some of the elements from a C++23 zip, you can use std::views::take
:
{c++}
std::forward_list<int> first_list{1, 2, 3, 4, 5};
std::forward_list<int> second_list{1, 2, 3, 4};
auto forward_zip = std::views::zip(first_list, second_list);
for (auto [a, b] : forward_zip | std::views::take(3)) {
std::cout << a << ", " << b << "\n";
}
With msd::zip
, you can write:
{c++}
for (auto it = forward_zip.begin(); it != std::prev(forward_zip.end()); ++it) {
auto [a, b] = *it;
std::cout << a << ", " << b << "\n";
}
But it does not work with the mentioned containers.
Post-increment operator missing
{c++}
// Working
for (auto it = zip.begin(); it != zip.end(); ++it) {}
// Not working
for (auto it = zip.begin(); it != zip.end(); it++) {}
Development
Tools
Actions
- Debug: F5
- Coverage: Ctrl + Shift + P -> Run Task -> Generate Coverage Report
- Show coverage inline: Ctrl + Shift + 7 OR Ctrl + Shift + P -> Coverage Gutters: Display Coverage
- Coverage as HTML: See build/coverage_html/index.html
- Clang tidy: Ctrl + Shift + P -> Run Task -> Run clang-tidy on current file
- Documentation: Ctrl + Shift + P -> Run Task -> Generate Documentation
TODO
- Set up cache for release workflow (apt cache)
- Exception guarantees: set and document
- constexpr
- Write benchmarks
- Ignore google headers from clang-tidy
- Consider checked access that returns an optional reference
- Run clang-tidy on file save
- Cancel running jobs on new commit
- Investigate possible documentation issue: cp: no such file or directory
- Test
- Analyze if LCOV_EXCL_LINE is needed
- Iterator operations: +, -, +=, -=, ++ pre/post, –pre/post, std::prev/next/advance, begin() + size() - begin(), etc.