Algorithms that are generalized to take projections typically default the
projection to std::identity, which is equivalent to no projection at all.
In that case, I believe we could shortcut the projection logic to return
the iterator unchanged rather than wrapping it. This should reduce compile
times especially after P2609R3 which made the indirect invocability
concepts more expensive to check when actual projections are involved.
libstdc++-v3/ChangeLog:
* include/bits/iterator_concepts.h (__detail::__projected): Define
an optimized partial specialization for when the projection is
std::identity.
* testsuite/24_iterators/indirect_callable/projected.cc: Verify the
optimization.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
using __projected_Proj = _Proj;
};
};
+
+ // Optimize the common case of the projection being std::identity.
+ template<typename _Iter>
+ struct __projected<_Iter, identity>
+ { using __type = _Iter; };
} // namespace __detail
/// [projected], projected
template<typename T>
using PI = std::projected<T, std::identity>;
+#if __GLIBCXX__
+// Verify our projected<I, identity> optimization.
+static_assert(std::same_as<PI<int*>, int*>);
+#else
static_assert(std::same_as<PI<int*>::value_type, int>);
+#endif
static_assert(std::same_as<decltype(*std::declval<const PI<int*>&>()), int&>);
struct X