[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