diff options
author | Joe Loser <joeloser93@gmail.com> | 2022-01-19 15:16:15 -0500 |
---|---|---|
committer | Joe Loser <joeloser93@gmail.com> | 2022-01-22 22:52:46 -0500 |
commit | 2513b79030636e62a785019bb9477920c8140d85 (patch) | |
tree | 2382fc52ffe22a9765e99db563c28de413cc6c62 | |
parent | 37d1d02200b9472082304c191f396f0489d00e05 (diff) | |
download | llvm-2513b79030636e62a785019bb9477920c8140d85.tar.gz |
[libc++] Implement LWG3549: view_interface need not inherit from view_base
Implement LWG3549 by making `view_interface` not inherit from `view_base`. Types
are still views if they have a public and unambiguous derivation from
`view_interface`, so adjust the `enable_view` machinery as such to account for
that.
Differential Revision: https://reviews.llvm.org/D117714
-rw-r--r-- | libcxx/docs/Status/Cxx2bIssues.csv | 2 | ||||
-rw-r--r-- | libcxx/include/__ranges/enable_view.h | 12 | ||||
-rw-r--r-- | libcxx/include/__ranges/view_interface.h | 3 | ||||
-rw-r--r-- | libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp | 9 |
4 files changed, 22 insertions, 4 deletions
diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv index 726668f3bdb2..a91e3b52a170 100644 --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -91,7 +91,7 @@ `3544 <https://wg21.link/LWG3544>`__,"``format-arg-store::args`` is unintentionally not exposition-only","June 2021","","","|format|" `3546 <https://wg21.link/LWG3546>`__,"``common_iterator``'s postfix-proxy is not quite right","June 2021","","","|ranges|" `3548 <https://wg21.link/LWG3548>`__,"``shared_ptr`` construction from ``unique_ptr`` should move (not copy) the deleter","June 2021","","" -`3549 <https://wg21.link/LWG3549>`__,"``view_interface`` is overspecified to derive from ``view_base``","June 2021","","","|ranges|" +`3549 <https://wg21.link/LWG3549>`__,"``view_interface`` is overspecified to derive from ``view_base``","June 2021","|Complete|","14.0","|ranges|" `3551 <https://wg21.link/LWG3551>`__,"``borrowed_{iterator,subrange}_t`` are overspecified","June 2021","","","|ranges|" `3552 <https://wg21.link/LWG3552>`__,"Parallel specialized memory algorithms should require forward iterators","June 2021","","" `3553 <https://wg21.link/LWG3553>`__,"Useless constraint in ``split_view::outer-iterator::value_type::begin()``","June 2021","","","|ranges|" diff --git a/libcxx/include/__ranges/enable_view.h b/libcxx/include/__ranges/enable_view.h index a09de11da81e..e1daec046fc0 100644 --- a/libcxx/include/__ranges/enable_view.h +++ b/libcxx/include/__ranges/enable_view.h @@ -12,6 +12,7 @@ #include <__config> #include <concepts> +#include <type_traits> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -25,8 +26,17 @@ namespace ranges { struct view_base { }; +template<class _Derived> + requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> +class view_interface; + +template<class _Op, class _Yp> + requires is_convertible_v<_Op*, view_interface<_Yp>*> +void __is_derived_from_view_interface(const _Op*, const view_interface<_Yp>*); + template <class _Tp> -inline constexpr bool enable_view = derived_from<_Tp, view_base>; +inline constexpr bool enable_view = derived_from<_Tp, view_base> || + requires { ranges::__is_derived_from_view_interface((_Tp*)nullptr, (_Tp*)nullptr); }; } // end namespace ranges diff --git a/libcxx/include/__ranges/view_interface.h b/libcxx/include/__ranges/view_interface.h index 8a1f5d8c9251..c5215cbcb8e3 100644 --- a/libcxx/include/__ranges/view_interface.h +++ b/libcxx/include/__ranges/view_interface.h @@ -18,7 +18,6 @@ #include <__ranges/access.h> #include <__ranges/concepts.h> #include <__ranges/empty.h> -#include <__ranges/enable_view.h> #include <concepts> #include <type_traits> @@ -40,7 +39,7 @@ void __implicitly_convert_to(type_identity_t<_Tp>) noexcept; template<class _Derived> requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> -class view_interface : public view_base { +class view_interface { _LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept { static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>); diff --git a/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp b/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp index ebc443ebe08d..b3f9b972a0cb 100644 --- a/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp +++ b/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp @@ -79,6 +79,11 @@ struct MoveOnlyForwardRange : std::ranges::view_interface<MoveOnlyForwardRange> }; static_assert(std::ranges::view<MoveOnlyForwardRange>); +struct MI : std::ranges::view_interface<InputRange>, + std::ranges::view_interface<MoveOnlyForwardRange> { +}; +static_assert(!std::ranges::view<MI>); + struct EmptyIsTrue : std::ranges::view_interface<EmptyIsTrue> { int buff[8] = {0, 1, 2, 3, 4, 5, 6, 7}; constexpr ForwardIter begin() const { return ForwardIter(const_cast<int*>(buff)); } @@ -300,6 +305,10 @@ constexpr bool testFrontBack() { return true; } +struct V1 : std::ranges::view_interface<V1> { }; +struct V2 : std::ranges::view_interface<V2> { V1 base_; }; +static_assert(sizeof(V2) == sizeof(V1)); + int main(int, char**) { testEmpty(); static_assert(testEmpty()); |