[libcxx-commits] [libcxx] 0102527 - [libc++][ranges] Implement `views::single`.

Konstantin Varlamov via libcxx-commits libcxx-commits at lists.llvm.org
Fri May 6 14:27:17 PDT 2022


Author: Konstantin Varlamov
Date: 2022-05-06T14:27:08-07:00
New Revision: 0102527352ff50a6d66402ab0fd8d857dcac3c5a

URL: https://github.com/llvm/llvm-project/commit/0102527352ff50a6d66402ab0fd8d857dcac3c5a
DIFF: https://github.com/llvm/llvm-project/commit/0102527352ff50a6d66402ab0fd8d857dcac3c5a.diff

LOG: [libc++][ranges] Implement `views::single`.

This only adds the customization point object (which isn't pipeable),
the view itself has already been implemented previously.

Differential Revision: https://reviews.llvm.org/D124978

Added: 
    libcxx/test/std/ranges/range.factories/range.single.view/cpo.pass.cpp

Modified: 
    libcxx/include/__ranges/lazy_split_view.h
    libcxx/include/__ranges/single_view.h
    libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
    libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.range.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__ranges/lazy_split_view.h b/libcxx/include/__ranges/lazy_split_view.h
index 68617c48f8712..e559a76ef7b77 100644
--- a/libcxx/include/__ranges/lazy_split_view.h
+++ b/libcxx/include/__ranges/lazy_split_view.h
@@ -87,8 +87,7 @@ class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>>
   _LIBCPP_HIDE_FROM_ABI
   constexpr lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
     : __base_(views::all(std::forward<_Range>(__r)))
-    // TODO(varconst): use `views::single` once it's implemented.
-    , __pattern_(ranges::single_view(std::move(__e))) {}
+    , __pattern_(views::single(std::move(__e))) {}
 
   _LIBCPP_HIDE_FROM_ABI
   constexpr _View base() const& requires copy_constructible<_View> { return __base_; }

diff  --git a/libcxx/include/__ranges/single_view.h b/libcxx/include/__ranges/single_view.h
index e6a873058fce2..98ebe5f3839f4 100644
--- a/libcxx/include/__ranges/single_view.h
+++ b/libcxx/include/__ranges/single_view.h
@@ -11,6 +11,7 @@
 
 #include <__config>
 #include <__ranges/copyable_box.h>
+#include <__ranges/range_adaptor.h>
 #include <__ranges/view_interface.h>
 #include <__utility/forward.h>
 #include <__utility/in_place.h>
@@ -70,8 +71,27 @@ namespace ranges {
     constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
   };
 
-  template<class _Tp>
-  single_view(_Tp) -> single_view<_Tp>;
+template<class _Tp>
+single_view(_Tp) -> single_view<_Tp>;
+
+namespace views {
+namespace __single_view {
+
+struct __fn : __range_adaptor_closure<__fn> {
+  template<class _Range>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+  constexpr auto operator()(_Range&& __range) const
+    noexcept(noexcept(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))))
+    -> decltype(      single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)))
+    { return          single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)); }
+};
+} // namespace __single_view
+
+inline namespace __cpo {
+  inline constexpr auto single = __single_view::__fn{};
+} // namespace __cpo
+
+} // namespace views
 } // namespace ranges
 
 #endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)

diff  --git a/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp b/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
index 16c54246bcd1b..6d766686aae87 100644
--- a/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
+++ b/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
@@ -80,7 +80,7 @@ static_assert(test(std::ranges::ssize, a));
 static_assert(test(std::views::iota, 1));
 static_assert(test(std::views::iota, 1, 10));
 //static_assert(test(std::views::istream<int>, 1);
-//static_assert(test(std::views::single, 4));
+static_assert(test(std::views::single, 4));
 
 // [range.adaptors]
 static_assert(test(std::views::all, a));

diff  --git a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.range.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.range.pass.cpp
index 45796c63debaa..bde1cb650f189 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.range.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.lazy.split/ctor.range.pass.cpp
@@ -125,7 +125,6 @@ constexpr bool test() {
   {
     using Range = RangeWithCounting;
     using Element = ElementWithCounting;
-    // TODO(varconst): use `views::single` once it's implemented.
     using Pattern = std::ranges::single_view<Element>;
 
     // Arguments are lvalues.

diff  --git a/libcxx/test/std/ranges/range.factories/range.single.view/cpo.pass.cpp b/libcxx/test/std/ranges/range.factories/range.single.view/cpo.pass.cpp
new file mode 100644
index 0000000000000..984f541e5598e
--- /dev/null
+++ b/libcxx/test/std/ranges/range.factories/range.single.view/cpo.pass.cpp
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-has-no-incomplete-ranges
+
+// std::views::single
+
+#include <ranges>
+
+#include <cassert>
+#include <concepts>
+#include <utility>
+#include "MoveOnly.h"
+
+// Can't invoke without arguments.
+static_assert(!std::is_invocable_v<decltype((std::views::single))>);
+// Can't invoke with a move-only type.
+static_assert(!std::is_invocable_v<decltype((std::views::single)), MoveOnly>);
+
+constexpr bool test() {
+  // Lvalue.
+  {
+    int x = 42;
+    std::same_as<std::ranges::single_view<int>> decltype(auto) v = std::views::single(x);
+    assert(v.size() == 1);
+    assert(v.front() == x);
+  }
+
+  // Prvalue.
+  {
+    std::same_as<std::ranges::single_view<int>> decltype(auto) v = std::views::single(42);
+    assert(v.size() == 1);
+    assert(v.front() == 42);
+  }
+
+  // Const lvalue.
+  {
+    const int x = 42;
+    std::same_as<std::ranges::single_view<int>> decltype(auto) v = std::views::single(x);
+    assert(v.size() == 1);
+    assert(v.front() == x);
+  }
+
+  // Xvalue.
+  {
+    int x = 42;
+    std::same_as<std::ranges::single_view<int>> decltype(auto) v = std::views::single(std::move(x));
+    assert(v.size() == 1);
+    assert(v.front() == x);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+
+  return 0;
+}


        


More information about the libcxx-commits mailing list