You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Here we materialize the iterator's value_type and we insert the elements one by one. If we had some kind of "protocol" that allows us to detect that an iterator is in fact a product of other iterators, we could decompose it to get the underlying iterators in the product and pass that directly to the containers. That way, we could call the underlying container's range-based insert method instead of inserting elements one-by-one.
This would apply to e.g. a zip view over two vectors, or when inserting into a flat_map from another flat_map. And given that we have significant optimizations in e.g. std::vector::insert(first, last) for contiguous iterators, this could end up making a big difference.
Example idea:
template <class_InputIterator, class_Sentinel>
requires __is_product_iterator<_InputIterator>
_LIBCPP_HIDE_FROM_ABI size_type __append_no_check(_InputIterator __first, _Sentinel __last) {
auto __first1 = std::__get_product_iterator_element<0>(__first);
auto __first2 = std::__get_product_iterator_element<1>(__first);
auto __last1 = std::__get_product_iterator_element<0>(__last);
auto __last2 = std::__get_product_iterator_element<1>(__last);
size_type __before = __containers_.keys.size();
__containers_.keys.insert(__containers_.keys.end(), __first1, __last1);
size_type __after = __containers_.keys.size();
__containers_.values.insert(__containers_.values.end(), __first2, __last2);
size_type __num_of_appended = __after - __before; // can we do better than that?// We could also have some kind of check like this, but we'd need to do that without making// the assumption that __first & __last are random access._LIBCPP_ASSERT_INTERNAL((__last1 - __first1) == (__last2 - __first2), "something went horribly wrong");
return __num_of_appended;
}
This makes me think about segmented iterator. It's not a category by itself, but it provides a (very useful) side channel to provide additional information to various places in the library. We don't have to implement this optimization day one (in fact we probably shouldn't for simplicity), but I think we really should consider doing it as a follow-up.
CC @philnik777 since this is the kind of stuff you generally like
Here we materialize the iterator's
value_type
and we insert the elements one by one. If we had some kind of "protocol" that allows us to detect that an iterator is in fact a product of other iterators, we could decompose it to get the underlying iterators in the product and pass that directly to the containers. That way, we could call the underlying container's range-basedinsert
method instead of inserting elements one-by-one.This would apply to e.g. a zip view over two vectors, or when inserting into a
flat_map
from anotherflat_map
. And given that we have significant optimizations in e.g.std::vector::insert(first, last)
for contiguous iterators, this could end up making a big difference.Example idea:
This makes me think about segmented iterator. It's not a category by itself, but it provides a (very useful) side channel to provide additional information to various places in the library. We don't have to implement this optimization day one (in fact we probably shouldn't for simplicity), but I think we really should consider doing it as a follow-up.
CC @philnik777 since this is the kind of stuff you generally like
Originally posted by @ldionne in #98643 (comment)
The text was updated successfully, but these errors were encountered: