[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