<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>&lt;T&gt;</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">