diff --git a/libcxx/include/__ranges/enable_view.h b/libcxx/include/__ranges/enable_view.h index f570926eb67c3..6dee6ea3fa3d2 100644 --- a/libcxx/include/__ranges/enable_view.h +++ b/libcxx/include/__ranges/enable_view.h @@ -14,7 +14,6 @@ #include <__concepts/same_as.h> #include <__config> #include <__type_traits/is_class.h> -#include <__type_traits/is_convertible.h> #include <__type_traits/remove_cv.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -34,12 +33,12 @@ template class view_interface; template - requires is_convertible_v<_Op*, view_interface<_Yp>*> -void __is_derived_from_view_interface(const _Op*, const view_interface<_Yp>*); + requires(!same_as<_Op, view_interface<_Yp>>) +void __is_derived_from_view_interface(view_interface<_Yp>*); template inline constexpr bool enable_view = derived_from<_Tp, view_base> || requires { - ranges::__is_derived_from_view_interface((_Tp*)nullptr, (_Tp*)nullptr); + ranges::__is_derived_from_view_interface>((remove_cv_t<_Tp>*)nullptr); }; } // namespace ranges diff --git a/libcxx/test/std/ranges/range.req/range.view/enable_view.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.view/enable_view.compile.pass.cpp index 6412234dce048..202b5bba451ce 100644 --- a/libcxx/test/std/ranges/range.req/range.view/enable_view.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.req/range.view/enable_view.compile.pass.cpp @@ -25,6 +25,12 @@ static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); // Derives from view_base, but privately struct PrivateViewBase : private std::ranges::view_base { }; @@ -34,6 +40,12 @@ static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); // Derives from view_base, but specializes enable_view to false struct EnableViewFalse : std::ranges::view_base { }; @@ -44,6 +56,12 @@ static_assert(!std::ranges::enable_view); static_assert(std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); +static_assert(std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); // Derives from view_base struct PublicViewBase : std::ranges::view_base { }; @@ -53,6 +71,12 @@ static_assert(!std::ranges::enable_view); static_assert(std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); +static_assert(std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); // Does not derive from view_base, but specializes enable_view to true struct EnableViewTrue { }; @@ -63,6 +87,12 @@ static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); // Make sure that enable_view is a bool, not some other contextually-convertible-to-bool type. ASSERT_SAME_TYPE(decltype(std::ranges::enable_view), const bool); @@ -75,6 +105,12 @@ static_assert(!std::ranges::enable_view); static_assert(std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); +static_assert(std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); struct V2 : std::ranges::view_interface, std::ranges::view_interface {}; static_assert(!std::ranges::enable_view); @@ -83,6 +119,12 @@ static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); struct V3 : std::ranges::view_interface {}; static_assert(std::ranges::enable_view); @@ -91,13 +133,35 @@ static_assert(!std::ranges::enable_view); static_assert(std::ranges::enable_view); static_assert(!std::ranges::enable_view); static_assert(!std::ranges::enable_view); +static_assert(std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); struct PrivateInherit : private std::ranges::view_interface {}; static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); + +// https://github.com/llvm/llvm-project/issues/132577 +// enable_view> should be false. +static_assert(!std::ranges::enable_view>); +static_assert(!std::ranges::enable_view>); +static_assert(!std::ranges::enable_view>); +static_assert(!std::ranges::enable_view>); // ADL-proof struct Incomplete; template struct Holder { T t; }; static_assert(!std::ranges::enable_view*>); +static_assert(!std::ranges::enable_view*>); +static_assert(!std::ranges::enable_view*>); +static_assert(!std::ranges::enable_view*>); static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); +static_assert(!std::ranges::enable_view); diff --git a/libcxx/test/std/ranges/range.req/range.view/view.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.view/view.compile.pass.cpp index e7a7f30cb20fb..38828cbe46b5b 100644 --- a/libcxx/test/std/ranges/range.req/range.view/view.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.req/range.view/view.compile.pass.cpp @@ -15,8 +15,6 @@ #include -#include "test_macros.h" - // The type would be a view, but it's not moveable. struct NotMoveable : std::ranges::view_base { NotMoveable() = default; @@ -90,3 +88,98 @@ static_assert(std::movable); static_assert(std::default_initializable); static_assert(std::ranges::enable_view); static_assert(std::ranges::view); + +// const view types + +struct ConstView1 : std::ranges::view_base { + ConstView1(const ConstView1&&); + const ConstView1& operator=(const ConstView1&&) const; + + friend void swap(const ConstView1&, const ConstView1&); + + friend int* begin(const ConstView1&); + friend int* end(const ConstView1&); +}; +static_assert(std::ranges::range); +static_assert(std::movable); +static_assert(!std::default_initializable); +static_assert(std::ranges::enable_view); +static_assert(std::ranges::view); + +struct ConstView2 : std::ranges::view_interface { + ConstView2(const ConstView2&&); + const ConstView2& operator=(const ConstView2&&) const; + + friend void swap(const ConstView2&, const ConstView2&); + + friend int* begin(const ConstView2&); + friend int* end(const ConstView2&); +}; +static_assert(std::ranges::range); +static_assert(std::movable); +static_assert(!std::default_initializable); +static_assert(std::ranges::enable_view); +static_assert(std::ranges::view); + +// volatile view types +struct VolatileView1 : std::ranges::view_base { + VolatileView1(volatile VolatileView1&&); + volatile VolatileView1& operator=(volatile VolatileView1&&) volatile; + + friend void swap(volatile VolatileView1&, volatile VolatileView1&); + + friend int* begin(volatile VolatileView1&); + friend int* end(volatile VolatileView1&); +}; +static_assert(std::ranges::range); +static_assert(std::movable); +static_assert(!std::default_initializable); +static_assert(std::ranges::enable_view); +static_assert(std::ranges::view); + +struct VolatileView2 : std::ranges::view_interface { + VolatileView2(volatile VolatileView2&&); + volatile VolatileView2& operator=(volatile VolatileView2&&) volatile; + + friend void swap(volatile VolatileView2&, volatile VolatileView2&); + + friend int* begin(volatile VolatileView2&); + friend int* end(volatile VolatileView2&); +}; +static_assert(std::ranges::range); +static_assert(std::movable); +static_assert(!std::default_initializable); +static_assert(std::ranges::enable_view); +static_assert(std::ranges::view); + +// const-volatile view types + +struct ConstVolatileView1 : std::ranges::view_base { + ConstVolatileView1(const volatile ConstVolatileView1&&); + const volatile ConstVolatileView1& operator=(const volatile ConstVolatileView1&&) const volatile; + + friend void swap(const volatile ConstVolatileView1&, const volatile ConstVolatileView1&); + + friend int* begin(const volatile ConstVolatileView1&); + friend int* end(const volatile ConstVolatileView1&); +}; +static_assert(std::ranges::range); +static_assert(std::movable); +static_assert(!std::default_initializable); +static_assert(std::ranges::enable_view); +static_assert(std::ranges::view); + +struct ConstVolatileView2 : std::ranges::view_interface { + ConstVolatileView2(const volatile ConstVolatileView2&&); + const volatile ConstVolatileView2& operator=(const volatile ConstVolatileView2&&) const volatile; + + friend void swap(const volatile ConstVolatileView2&, const volatile ConstVolatileView2&); + + friend int* begin(const volatile ConstVolatileView2&); + friend int* end(const volatile ConstVolatileView2&); +}; +static_assert(std::ranges::range); +static_assert(std::movable); +static_assert(!std::default_initializable); +static_assert(std::ranges::enable_view); +static_assert(std::ranges::view);