ArrowProxy (last few commits) vs previous implementationm (first commits, no the PairView approach):
Pros:
Simpler implementation (no AssignableStorage/std::optional needed)
Iterators are std::is_trivially_copyable_v and a bit lighter, as they don't store a pair of references.
Cons:
A bit more work for multiple consecutive usages of ->.
Does not return an l-value reference, but a value. This means:
1) Need to suppress -Wrange-loop-bind-reference globally because they trigger on common loops (in contrast to std::map):
for (const auto& key_and_value : s) { }
for (const auto& [key, value] : s) { }
2) These non-cost & don't work at all (in contrast to std::map):
// error: non-const lvalue reference to type 'pair<...>' cannot bind to a temporary of type
// 'pair<...>'
for (auto& key_and_value : s) { }
// error: non-const lvalue reference to type 'pair<...>' cannot bind to a temporary of type
// 'pair<...>'
for (auto& [key, value] : s) { }
3) range-v3 has issues (but not std::ranges, std::map works with either):
int first_entry = (*f.begin()).second; // Can't use arrow with range-v3 because it requires
// l-value. Note that std::ranges works
All of the above work on std::map, so it's less of a drop-in replacement.
All of the above is demo'ed in the unit tests.
ArrowProxy
(last few commits) vs previous implementationm (first commits, no the PairView approach):Pros:
std::is_trivially_copyable_v
and a bit lighter, as they don't store a pair of references.Cons:
->
.Does not return an l-value reference, but a value. This means: 1) Need to suppress
-Wrange-loop-bind-reference
globally because they trigger on common loops (in contrast tostd::map
):2) These
non-cost &
don't work at all (in contrast tostd::map
):3) range-v3 has issues (but not std::ranges,
std::map
works with either):All of the above work on
std::map
, so it's less of a drop-in replacement. All of the above is demo'ed in the unit tests.