<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/132577>132577</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[libc++] `view_interface` is not `view`
</td>
</tr>
<tr>
<th>Labels</th>
<td>
libc++
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
SainoNamkho
</td>
</tr>
</table>
<pre>
https://eel.is/c++draft/range.view#6 says
> For a type `T`, <code><em>is-derived-from-view-interface</em><T></code> is `true` if and only if `T` has exactly one public base class `view_interface<U>` for some type `U` and `T` has no base classes of type `view_interface<V>` for any other type `V`.
Is `view_interface<U>` a base of itself? The answer is no. The standard explicit points it out when reflexivity is additionally accepted.
> https://eel.is/c++draft/concept.derived#note-1
> `derived_from<Derived, Base>` is satisfied if and only if `Derived` is publicly and unambiguously derived from `Base`, **or `Derived` and `Base` are the same class type ignoring cv-qualifiers**.
> https://eel.is/c++draft/type.traits#meta.rel
> `Base` is a base class of `Derived` without regard to cv-qualifiers **or `Base` and `Derived` are not unions and name the same class type without regard to cv-qualifiers**
libc++ and MS STL do not exclude `view_interface` from `enable_view`, libstdc++ does not exclude references ([Godbolt link](https://godbolt.org/z/YeM56ePfj)).
```c++
#include <ranges>
using namespace std::ranges;
struct Incomplete;
struct X : view_interface<X> {};
struct Y : view_interface<Incomplete> {};
struct Z : view_interface<X> {};
static_assert(enable_view<X>);
static_assert(enable_view<Y> && enable_view<Z>); // conforming, should reject, maybe a CWG issue is needed
#if defined(_LIBCPP_VERSION) || defined(_MSVC_STL_UPDATE)
static_assert(!enable_view<X&>); // correct
static_assert(enable_view<view_interface<X>>); // wrong
static_assert(enable_view<view_interface<Incomplete>>); // wrong
static_assert(enable_view<view_interface<Y>>); // wrong
#else // libstdc++
static_assert(enable_view<X&>); // wrong
static_assert(!enable_view<view_interface<X>>); // correct
static_assert(!enable_view<view_interface<Incomplete>>); // correct
static_assert(!enable_view<view_interface<Y>>); // correct
#endif
```
Current implemetaion:
https://github.com/llvm/llvm-project/blob/616737c386776b0cfbda888a4d52e6036ccf1af8/libcxx/include/__ranges/enable_view.h#L36-L43
I think the `is_convertible_v<_Op*, view_interface<_Yp>*>` check is unnecessary, as it will have failed in template argument deduction ambiguity when there're multiple such bases.
Maybe this?
```c++
namespace fix {
namespace impl {
template<class T>
view_interface<T> is_derived_from_view_interface_helper(const view_interface<T>*);
}
template<class T>
constexpr bool enable_view = std::derived_from<T, view_base> || requires(T* p) {
requires !std::same_as<decltype(impl::is_derived_from_view_interface_helper(p)), T>;
};
static_assert(enable_view<view_base>);
static_assert(enable_view<X>);
static_assert(enable_view<Y> && enable_view<Z>);
static_assert(!enable_view<X&>);
static_assert(!enable_view<view_interface<X>>);
static_assert(!enable_view<view_interface<Incomplete>>);
static_assert(!enable_view<view_interface<Y>>);
}
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysV9Fu27gS_RrmZRBDJmPZfvCDrdSLAuluceP2bvZFoMiRxS1Nakkqie_XX1CSHcV2tinaokAMcXhm5szozIh7r7YGcUEmKzK5veJNqKxb3HNl7O98962yV4WV-0UVQu0JWxK6JnSNqEfKE7oWhK4IXUnHy0Do2nGzxdGjwidCWQqe7z1JloR9gLV1wCHsawSSJhuSJoRmQFgmrETCPhCW4Y6wD8pfS3TqEeV16ezuOmJdKxPQlVwgYVn0Hg0JTXUgbLUhNN3GH91ZDwfKRz_BNUjSBFQJ3EiwRu_j7z4CqLgHfOYi6D1Yg1A3hVYCCu4RhOa-xYgR5MMIvkTvaQKldeDtDo9ZfYlPo58hvrEDPPRgy6P9GfLXATI3e7ChQnc0_0rSZBTpTJYf_z0y3rm0JajgUZeErWFTIXDjn9BFbowdtU984EZyJwGfa62EClBbZYIHFcA2AZ4qNOCw1PisHlXYx7tcShWUNVzrPXAhsA4oR32d39cnwpp4bdSXmlBmbMDrcQ9C0qQ_yWMTEJbdHgwzWHGPfZ7Kg-dB-VKhvFDjw6XOsituDNlIaAzfFWrb2MbrPfTOIDqLF1sXfYfSJaFL607w-ir3hsAdQoh08t2hc9qqqa2xTpktiMfrfxquVanQ-Q6zL-X7SYuIo-C4Cp5QtsPARw71C2WHYGKJhj1sT8l4UqGKxXW4jaUP9nV4r3I-ZtglPKTAIRgboDHKGt8amJj-JR6-47Fz2PGhVdHn3UJ-uof7zR1I2_rCZ6EbeenliW9NXz00vNCYtyrUFVGrwgd5gJUW_Ss0hyU6NAJj6jMyWf1mZWF1AK3MNzK5JXT2ukLb7nxk3ZbQ9f8IXT_gp0mKn8u_CZ0TOj_UNk26_73r-IgyZfokWNbqpY_d3No3PvZKZNHXXMS3U0afbHmwW3V2PrhGBPhohN3VGgOenvwJhC3hTB_-bDtluiLT29MbD5dvDF28dfWvH3HGgxJ5VEIXCJ0NS9XdiPy9z_qhxacpoSm8PvnriAPQFQyENaV1O2W2sR98ZRstweHfKEJ8sOP7AoFD9t_fQHnfYKuRiBJlX0nKVAkSS2WiCs3yu4-r7PPn_OuH_9x__ON3QudAphmZZkObT_dfs_x-c5d_-Xy73LQhnSdF6PiUBZq-JHCM37kY6_dIuViFM7QnZ832x7FeNcOAY4CfBH44wzv-OwEmlKH2-HLw6tV-R4dd4PatoM8q8z5y3y7V9wHfZvgXgL_N8hl4pNlIVQ41rHsRssY5NAFUDDPOIGVN1KhkeSKRKlRNMRJ2R-ha68fDn-va2e6tWxfaFoSu03E6ZVPBZul0mhaJKAvJZ7MZv5ETimnCUiHKMS9nEUAV4vmZ0HUvoYSu87zXRroepD-qCGV3LL2-u2H9xgShUuZbO51ImiifC2se0QXV3iEsy_-o2zmUnUtZ_lC3xC37vUNUKL5FiWiMQYHec7ePF3m7Nz0praHijwglVzpuJgYC7mrNAwJ322YXCZQoGxHXKOg2kbhctdtW3PmQ0KlD2DU6qFoj-EZU7Uj3I-jy-dQqVqiUJ2x9edS8zJFSPbdKPHwWC9g_jC1wCDBu5O3c3nRTKZ6d8bHpNux8uKTlr63yCnWNjtCZsMaHyxgt3we9n96SZPlWGC0IPtcOCmv1UO-BsNuXQXmyNm6O5Sy6rfGg0g7_aZSLbTPbELqEulPwAxuHYyB0fMSOS03OPWGZRKHjXkPoLNLYHb-Xj7pbEWJkbXLH7N839obZHMn7gbn680P1cpT_Psd-Xl5_oZ7-vHoe-_X42l3JBZNzNudXuBhPb2g6Z4zOr6rFhE6KJKGcluWcsnRWJuOCS56KlM2lLNmVWtCEThJGWTKmMzYdlQkv0_mYlTdFUWDKyE2CO670KOpn3Dmv2hVlMWZ0Mp1eaV6g9u33O6Uv2zOhNH7Pu0WrukWz9eQm0coH_4ITVNDtl__g2uT28natup25P4sZN04vflj029CjWvfRPy7o_wMAAP__D_A03Q">