[all-commits] [llvm/llvm-project] bf738d: [ADT] Make mapped_iterator copy assignable

kazutakahirata via All-commits all-commits at lists.llvm.org
Sun Oct 30 14:37:21 PDT 2022


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: bf738d2e77846826964402f2cccdd0681c71c038
      https://github.com/llvm/llvm-project/commit/bf738d2e77846826964402f2cccdd0681c71c038
  Author: James Player <james.w.player at gmail.com>
  Date:   2022-10-30 (Sun, 30 Oct 2022)

  Changed paths:
    M llvm/include/llvm/ADT/STLExtras.h
    M llvm/unittests/ADT/MappedIteratorTest.cpp

  Log Message:
  -----------
  [ADT] Make mapped_iterator copy assignable

As mentioned in https://discourse.llvm.org/t/rfc-extend-ranges-infrastructure-to-better-match-c-20/65377

Lambda objects are not copy assignable, and therefore neither are
iterator types which hold a lambda.  STL code require iterators be
copy assignable.  Users may not use mapped_iterator with a std::deque
for example: https://godbolt.org/z/4Px7odEEd

This blog post [1] explains the problem and solution.  We define a
wrapper class to store callable objects with two specialization.

1. Specialization for non-function types
    - Use a std::optional as storage for non-function callable.
    - Define operator=() implementation(s) which use
      std::optional::emplace() instead of the assignment operator.
2. Specialization for function types
    - Store as a pointer (even if template argument is a function reference).
    - Default construct pointer to nullptr.

This Callable wrapper class is now default constructible (with invalid
state) and copy/move assignable.

With these new properties available on the callable object,
mapped_iterator can define a default constructor as well.

[1] https://www.fluentcpp.com/2019/04/16/an-alternative-design-to-iterators-and-ranges-using-stdoptional/

Reviewed By: kazu

Differential Revision: https://reviews.llvm.org/D134675




More information about the All-commits mailing list