[libcxx-commits] [libcxx] 823fa09 - [libc++][ranges][NFC] Test the specializations of `tuple_{size, element}` for ranges.
Konstantin Varlamov via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Feb 2 22:58:48 PST 2022
Author: Konstantin Varlamov
Date: 2022-02-02T22:58:33-08:00
New Revision: 823fa098aa5558a391decc7b7ee58e902581f0a1
URL: https://github.com/llvm/llvm-project/commit/823fa098aa5558a391decc7b7ee58e902581f0a1
DIFF: https://github.com/llvm/llvm-project/commit/823fa098aa5558a391decc7b7ee58e902581f0a1.diff
LOG: [libc++][ranges][NFC] Test the specializations of `tuple_{size,element}` for ranges.
Also update the synopsis in `<ranges>` to mention the specializations.
Differential Revision: https://reviews.llvm.org/D118686
Added:
libcxx/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.ranges.pass.cpp
Modified:
libcxx/docs/Status/RangesPaper.csv
libcxx/include/ranges
Removed:
################################################################################
diff --git a/libcxx/docs/Status/RangesPaper.csv b/libcxx/docs/Status/RangesPaper.csv
index 1c5f19b2aa0b4..7c654c70f1723 100644
--- a/libcxx/docs/Status/RangesPaper.csv
+++ b/libcxx/docs/Status/RangesPaper.csv
@@ -1,5 +1,5 @@
Section,Description,Dependencies,Assignee,Complete
-`[tuple.helper] <https://wg21.link/tuple.helper>`_,Update <tuple> includes.,None,Konstantin Varlamov,Not started
+`[tuple.helper] <https://wg21.link/tuple.helper>`_,`Update <tuple> includes. <https://llvm.org/D118686>`_,None,Konstantin Varlamov,✅
`[range.cmp] <https://wg21.link/range.cmp>`_,"| `ranges::equal_to <https://llvm.org/D100429>`_
| `ranges::not_equal_to <https://llvm.org/D100429>`_
| `ranges::less <https://llvm.org/D100429>`_
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 2d79d87eef895..e0b20ac26cef6 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -198,6 +198,36 @@ namespace std::ranges {
class join_view;
}
+namespace std {
+ namespace views = ranges::views;
+
+ template<class T> struct tuple_size;
+ template<size_t I, class T> struct tuple_element;
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_size<ranges::subrange<I, S, K>>
+ : integral_constant<size_t, 2> {};
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_element<0, ranges::subrange<I, S, K>> {
+ using type = I;
+ };
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_element<1, ranges::subrange<I, S, K>> {
+ using type = S;
+ };
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_element<0, const ranges::subrange<I, S, K>> {
+ using type = I;
+ };
+
+ template<class I, class S, ranges::subrange_kind K>
+ struct tuple_element<1, const ranges::subrange<I, S, K>> {
+ using type = S;
+ };
+}
*/
// Make sure all feature-test macros are available.
diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.ranges.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.ranges.pass.cpp
new file mode 100644
index 0000000000000..d338dd6072e49
--- /dev/null
+++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.helper/tuple.include.ranges.pass.cpp
@@ -0,0 +1,64 @@
+//===----------------------------------------------------------------------===//
+//
+// 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-no-concepts
+// UNSUPPORTED: libcpp-has-no-incomplete-ranges
+
+// <ranges>
+
+// template<class T> struct tuple_size;
+// template<size_t I, class T> struct tuple_element;
+
+#include <ranges>
+// Note: make sure to not include `<utility>` (or any other header including `<utility>`) because it also makes some
+// tuple specializations available, thus obscuring whether the `<ranges>` includes work correctly.
+
+using Iterator = int*;
+
+class SizedSentinel {
+public:
+ constexpr bool operator==(int*) const;
+ friend constexpr ptr
diff _t operator-(const SizedSentinel&, int*);
+ friend constexpr ptr
diff _t operator-(int*, const SizedSentinel&);
+};
+
+static_assert(std::sized_sentinel_for<SizedSentinel, Iterator>);
+using SizedRange = std::ranges::subrange<Iterator, SizedSentinel>;
+
+using UnsizedSentinel = std::unreachable_sentinel_t;
+static_assert(!std::sized_sentinel_for<UnsizedSentinel, Iterator>);
+using UnsizedRange = std::ranges::subrange<Iterator, UnsizedSentinel>;
+
+// Because the sentinel is unsized while the subrange is sized, an additional integer member will be used to store the
+// size -- make sure it doesn't affect the value of `tuple_size`.
+using ThreeElementRange = std::ranges::subrange<Iterator, UnsizedSentinel, std::ranges::subrange_kind::sized>;
+static_assert(std::ranges::sized_range<ThreeElementRange>);
+
+static_assert(std::tuple_size<SizedRange>::value == 2);
+static_assert(std::tuple_size<UnsizedRange>::value == 2);
+static_assert(std::tuple_size<ThreeElementRange>::value == 2);
+
+template <int I, class Range, class Expected>
+constexpr bool test_tuple_element() {
+ static_assert(std::same_as<typename std::tuple_element<I, Range>::type, Expected>);
+ static_assert(std::same_as<typename std::tuple_element<I, const Range>::type, Expected>);
+ // Note: the Standard does not mandate a specialization of `tuple_element` for volatile, so trying a `volatile Range`
+ // would fail to compile.
+
+ return true;
+}
+
+int main(int, char**) {
+ static_assert(test_tuple_element<0, SizedRange, Iterator>());
+ static_assert(test_tuple_element<1, SizedRange, SizedSentinel>());
+ static_assert(test_tuple_element<0, UnsizedRange, Iterator>());
+ static_assert(test_tuple_element<1, UnsizedRange, UnsizedSentinel>());
+
+ return 0;
+}
More information about the libcxx-commits
mailing list