<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/57233>57233</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libc++] Automatic `iterator_category` detection misbehaves when `::reference` is an rvalue reference, refuses to accept a forward iterator
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
HolyBlackCat
</td>
</tr>
</table>
<pre>
Since C++20, `std::iterator_traits` can auto-detect `::iterator_category`, if the iterator doesn't set it.
Forward iterators require `::reference` (aka the return type of `operator*`) to be a reference (any reference), but libc++ only accepts lvalue references here.
Example:
```cpp
#include <iterator>
#include <type_traits>
template <typename T>
struct A
{
using value_type = std::remove_cvref_t<T>;
using difference_type = int;
T operator*() const;
A &operator++();
A operator++(int);
bool operator==(const A &) const;
};
// Ok.
static_assert(std::is_same_v<std::iterator_traits<A<int &>>::iterator_category, std::forward_iterator_tag>);
// Should pass but fails, the category is `std::input_iterator_tag`.
static_assert(std::is_same_v<std::iterator_traits<A<int &&>>::iterator_category, std::forward_iterator_tag>);
```
I blame this on cppreference, which used to incorrectly say that only lvalue references are allowed there. It was fixed since then.
See [`[forward.iterators]/1.3`](https://eel.is/c++draft/iterators#forward.iterators-1.3). Also see [LWG issue 1211](https://cplusplus.github.io/LWG/issue1211) (from 2009), which was resolved by [N3066](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3066.html) (in 2010).
This was discussed on SO: https://stackoverflow.com/q/73353152
[libstdc++](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106676) and MSVC's standard library share the exact same bug.
This was tested on Clang 14.0.0 and on trunk (16.0.0).
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy1VkuT4jYQ_jXmohqXLPMwBw7ADMlWJdnDTG2OlCzLtnaE5ZVkGPLr0y0DHh5zSygBttTq_vrxtZSb4rh4VY2QZB2xFQxGI7Ym0ZQ6X0TpEoby0nJv7NZbrryDJSJ4Q3jnzVMhvRQexW9kBfeyMvaIK6BPlcTXkpyXSWGkayI288RJD9NxRJ8juux_N8YeuC0u0o5Y-atTVg52rCyllQAb0UQs4-88GLDSd7Yh_thKYkqUN22vJGLLgGVOvCG5JJxcdAQFzXGYACkEnXeeaJWLPjDENPpIuBCy9Y7oPdedHLY4UsPDlRsvH3zXaomA-1kwH4Zo29MMSyH0uisAQro-uxulL4-W0adzCi4S4ddLsAPxPks1fCfJ20XIedtBjs4oZqv-gcCnc6qpSHBlG2IWpc_kkngrd2Yvt2IPXm49KA8607v9hSpPURiUqMZfSb6Rz4lgGSZCmMZdSy0hFdNBcBUGyt5I3YmguRup3Bg9CKbPOFgWbPZ27iFEs-fh-ZSCDQzy_T0-x5J7JbbcOWnBYjaQxG0dhH27hzB9yZx0vcQ8Nz6Yx1i-fEUbKL-LmrLnw3ZQxyvc-snhE87X2nS6IC3gC9VbcqUd6kJunHUT5a753bSdv1Y-pf-Dv_-1y2c6fc7XN5JrrH5fg5OmIUC1T6xek0OtRA1lKwtsA8AuYy00MCC240fYxX1P83t6c2g_XGtzwK2B6-SbJwfuSKk-YM6FJgorzVUTeJXAh8kKYU5WJ6_iS2OLJlCTmyROwzrWZ-196zAGIaFS6lhBAjenHlRYXkIaNoMClt4pfUJ9bB6TpXYG-msA8Mffv0HeHfiUsCR5ZEu0unP4jSvl6y6PlYFZ2If2cGfYCJyBnaU1O8IonZ86ZR9WDIaVzug9xCM_otm_UjqdPrJ2OBxiIGfzBCmPja1g6qcXoH_jBGMoUDF8K4xA_1sORMYHRhNo4psG9ca13-kTItWQfml-Ff43rAPEVSgnOod5h6p4_Q44yDUgqHTxDu3OlpDjWJgdzP2C7yxNJ2kyYVddYbKCcwGQn9LyyMFKiLhqupNveVf9o7TmaKg2hy28x6JSUbpRUPHPCXgzCw2JNwX58_UHHMYzB3SAVzwJwZrlwFxXYxkimeUHh56OFCSo66HPXjrfO7zWHPp0Mo5pTIMJmINToXnH0CVTnMbIjeQimU5pNqHzZDwqFmkxT-d85JXXctE7PXhMlnAB2GF7wG7y6OAn_e1AgbGdcrms-R6IdACKfHGQA264WNgb7mGBwQuQ1iFp-xMYzu_y5pow6qxe3CShr-Q-m1rvz39PrTU_Adq5tLGyJjOWpqN6MeOFZCWdUsqEzHhBqcjLmaDFmM45LecjzXOpHcYjYqyRh55X8AxBGakFo4zRLMmSOcvScTzOZiXLKZukE1Zm43k0pnIHbTlGHFgdI7sIkCCNDha1ct4Ni9B5VdXIEH7UD7eu2tjF70YfVxoqds39KNhfBPz_Ar6CCTs">