diff --git a/libcxx/docs/Cxx2aStatusIssuesStatus.csv b/libcxx/docs/Cxx2aStatusIssuesStatus.csv --- a/libcxx/docs/Cxx2aStatusIssuesStatus.csv +++ b/libcxx/docs/Cxx2aStatusIssuesStatus.csv @@ -246,7 +246,7 @@ "`3323 `__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","","" "`3324 `__","Special-case ``std::strong/weak/partial_order``\ for pointers","Prague","","" "`3325 `__","Constrain return type of transformation function for ``transform_view``\ ","Prague","","" -"`3326 `__","``enable_view``\ has false positives","Prague","","" +"`3326 `__","``enable_view``\ has false positives","Prague","|In progress|","" "`3327 `__","Format alignment specifiers vs. text direction","Prague","|Nothing To Do|","" "`3328 `__","Clarify that ``std::string``\ is not good for UTF-8","Prague","","" "`3329 `__","``totally_ordered_with``\ both directly and indirectly requires ``common_reference_with``\ ","Prague","|Complete|","13.0" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -49,9 +49,9 @@ __ranges/data.h __ranges/empty.h __ranges/empty_view.h + __ranges/enable_view.h __ranges/enable_borrowed_range.h __ranges/view_interface.h - __ranges/view.h __ranges/size.h __split_buffer __std_stream diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h --- a/libcxx/include/__ranges/concepts.h +++ b/libcxx/include/__ranges/concepts.h @@ -13,6 +13,7 @@ #include <__iterator/concepts.h> #include <__ranges/access.h> #include <__ranges/size.h> +#include <__ranges/enable_view.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -63,6 +64,24 @@ // `disable_sized_range` defined in `<__ranges/size.h>` + // [range.view], views + + // `enable_view` defined in <__ranges/enable_view.h> + // `view_base` defined in <__ranges/enable_view.h> + + template + concept view = + range<_Tp> && + movable<_Tp> && + default_initializable<_Tp> && + enable_view<_Tp>; + + template + concept __simple_view = + view<_Range> && range && + same_as, iterator_t > && + same_as, iterator_t >; + // [range.refinements], other range refinements template concept input_range = range<_Tp> && input_iterator >; diff --git a/libcxx/include/__ranges/view.h b/libcxx/include/__ranges/enable_view.h rename from libcxx/include/__ranges/view.h rename to libcxx/include/__ranges/enable_view.h --- a/libcxx/include/__ranges/view.h +++ b/libcxx/include/__ranges/enable_view.h @@ -11,7 +11,6 @@ #define _LIBCPP___RANGES_VIEW_H #include <__config> -#include <__ranges/concepts.h> #include @@ -33,18 +32,6 @@ template inline constexpr bool enable_view = derived_from<_Tp, view_base>; -template -concept view = - range<_Tp> && - movable<_Tp> && - default_initializable<_Tp> && - enable_view<_Tp>; - -template -concept __simple_view = - view<_Range> && range && - same_as, iterator_t> && - same_as, iterator_t>; } // end namespace ranges #endif // !_LIBCPP_HAS_NO_RANGES diff --git a/libcxx/include/__ranges/view_interface.h b/libcxx/include/__ranges/view_interface.h --- a/libcxx/include/__ranges/view_interface.h +++ b/libcxx/include/__ranges/view_interface.h @@ -15,7 +15,7 @@ #include <__iterator/prev.h> #include <__ranges/access.h> #include <__ranges/empty.h> -#include <__ranges/view.h> +#include <__ranges/enable_view.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/ranges b/libcxx/include/ranges --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -99,9 +99,9 @@ #include <__ranges/empty.h> #include <__ranges/empty_view.h> #include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> #include <__ranges/size.h> #include <__ranges/view_interface.h> -#include <__ranges/view.h> #include // Required by the standard. #include // Required by the standard. #include // Required by the standard. diff --git a/libcxx/include/span b/libcxx/include/span --- a/libcxx/include/span +++ b/libcxx/include/span @@ -22,6 +22,10 @@ template class span; +template + inline constexpr bool ranges::enable_view> = + Extent == 0 || Extent == dynamic_extent; + template inline constexpr bool ranges::enable_borrowed_range> = true; @@ -127,6 +131,7 @@ #include <__config> #include <__debug> #include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> #include // for array #include // for byte #include // for iterators @@ -529,6 +534,9 @@ }; #if !defined(_LIBCPP_HAS_NO_RANGES) +template +inline constexpr bool ranges::enable_view> = _Extent == 0 || _Extent == dynamic_extent; + template inline constexpr bool ranges::enable_borrowed_range > = true; #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/string_view b/libcxx/include/string_view --- a/libcxx/include/string_view +++ b/libcxx/include/string_view @@ -19,6 +19,9 @@ template> class basic_string_view; + template + inline constexpr bool ranges::enable_view> = true; + template inline constexpr bool ranges::enable_borrowed_range> = true; // C++20 @@ -184,6 +187,7 @@ #include <__config> #include <__debug> #include <__ranges/enable_borrowed_range.h> +#include <__ranges/enable_view.h> #include <__string> #include #include @@ -654,6 +658,9 @@ }; #if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) +template +inline constexpr bool ranges::enable_view> = true; + template inline constexpr bool ranges::enable_borrowed_range > = true; #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp @@ -23,13 +23,13 @@ static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); -static_assert(!stdr::view); +static_assert(stdr::view&& stdr::enable_view); static_assert(stdr::sized_range); static_assert(stdr::borrowed_range); static_assert(std::same_as, range::iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); -static_assert(!stdr::view); +static_assert(!stdr::view && !stdr::enable_view); static_assert(stdr::sized_range); static_assert(stdr::borrowed_range); diff --git a/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp --- a/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp +++ b/libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp @@ -22,13 +22,13 @@ static_assert(std::same_as, std::string_view::iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); -static_assert(!stdr::view); +static_assert(stdr::view&& stdr::enable_view); static_assert(stdr::sized_range); static_assert(stdr::borrowed_range); static_assert(std::same_as, std::string_view::const_iterator>); static_assert(stdr::common_range); static_assert(stdr::random_access_range); -static_assert(!stdr::view); // FIXME: string_view needs to be patched so this is true +static_assert(!stdr::view && !stdr::enable_view); static_assert(stdr::sized_range); static_assert(stdr::borrowed_range);