Skip to content

[libc++] Introduce a concept for "product" iterators #108624

Closed
@ldionne

Description

@ldionne

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

Originally posted by @ldionne in #98643 (comment)

Metadata

Metadata

Assignees

Labels

libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions