[libcxx-commits] [libcxx] 3450398 - [libcxx][ranges] Add contiguous_range.

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jun 24 10:40:34 PDT 2021


Author: zoecarver
Date: 2021-06-24T10:40:05-07:00
New Revision: 34503987385b8e2a21ca4f9a29c9135c03b427e4

URL: https://github.com/llvm/llvm-project/commit/34503987385b8e2a21ca4f9a29c9135c03b427e4
DIFF: https://github.com/llvm/llvm-project/commit/34503987385b8e2a21ca4f9a29c9135c03b427e4.diff

LOG: [libcxx][ranges] Add contiguous_range.

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

Added: 
    libcxx/test/std/ranges/range.req/range.refinements/contiguous_range.compile.pass.cpp

Modified: 
    libcxx/include/__ranges/concepts.h
    libcxx/include/__ranges/ref_view.h
    libcxx/include/ranges
    libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/views/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/ranges/range.req/range.refinements/subsumption.compile.pass.cpp
    libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp
    libcxx/test/std/strings/string.view/range_concept_conformance.compile.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h
index 25fd0ef510476..364275da813b3 100644
--- a/libcxx/include/__ranges/concepts.h
+++ b/libcxx/include/__ranges/concepts.h
@@ -17,6 +17,7 @@
 #include <__iterator/readable_traits.h>
 #include <__ranges/access.h>
 #include <__ranges/enable_borrowed_range.h>
+#include <__ranges/data.h>
 #include <__ranges/enable_view.h>
 #include <__ranges/size.h>
 #include <concepts>
@@ -101,6 +102,14 @@ namespace ranges {
   concept random_access_range =
       bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp> >;
 
+  template<class _Tp>
+  concept contiguous_range =
+    random_access_range<_Tp> &&
+    contiguous_iterator<iterator_t<_Tp>> &&
+    requires(_Tp& __t) {
+      { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>;
+    };
+
   template <class _Tp>
   concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp> >;
 } // namespace ranges

diff  --git a/libcxx/include/__ranges/ref_view.h b/libcxx/include/__ranges/ref_view.h
index c668499883d04..5ca4ca16065c9 100644
--- a/libcxx/include/__ranges/ref_view.h
+++ b/libcxx/include/__ranges/ref_view.h
@@ -63,9 +63,8 @@ namespace ranges {
       requires sized_range<_Range>
     { return ranges::size(*__range_); }
 
-    // TODO: This needs to use contiguous_range.
     constexpr auto data() const
-      requires contiguous_iterator<iterator_t<_Range>>
+      requires contiguous_range<_Range>
     { return ranges::data(*__range_); }
   };
 

diff  --git a/libcxx/include/ranges b/libcxx/include/ranges
index 52c69124a3e1f..338ea0d04c387 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -76,6 +76,12 @@ namespace std::ranges {
   template<class T>
   concept bidirectional_range = see below;
 
+  template<class T>
+  concept random_access_range = see below;
+
+  template<class T>
+  concept contiguous_range = see below;
+
   template <class _Tp>
     concept common_range = see below;
 

diff  --git a/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
index 0b457c3ae4389..f70af72c9bd3d 100644
--- a/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/range_concept_conformance.compile.pass.cpp
@@ -24,6 +24,7 @@ static_assert(!stdr::view<range>);
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::random_access_range<range>);
+static_assert(stdr::contiguous_range<range>);
 static_assert(stdr::sized_range<range>);
 static_assert(!stdr::borrowed_range<range>);
 
@@ -31,5 +32,6 @@ static_assert(!stdr::view<range const>);
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
 static_assert(stdr::random_access_range<range const>);
+static_assert(stdr::contiguous_range<range const>);
 static_assert(stdr::sized_range<range const>);
 static_assert(!stdr::borrowed_range<range const>);

diff  --git a/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
index 1f20686998fe9..7b248e9846ed2 100644
--- a/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,7 @@ namespace stdr = std::ranges;
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::random_access_range<range>);
+static_assert(!stdr::contiguous_range<range>);
 static_assert(!stdr::view<range>);
 static_assert(stdr::sized_range<range>);
 static_assert(!stdr::borrowed_range<range>);
@@ -30,6 +31,7 @@ static_assert(!stdr::borrowed_range<range>);
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
 static_assert(stdr::random_access_range<range const>);
+static_assert(!stdr::contiguous_range<range const>);
 static_assert(!stdr::view<range const>);
 static_assert(stdr::sized_range<range const>);
 static_assert(!stdr::borrowed_range<range const>);

diff  --git a/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
index 5e2b5b0a14c3f..9981d65fd80d0 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,7 @@ namespace stdr = std::ranges;
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::random_access_range<range>);
+static_assert(!stdr::contiguous_range<range>);
 static_assert(!stdr::view<range>);
 static_assert(stdr::sized_range<range>);
 static_assert(!stdr::borrowed_range<range>);
@@ -30,6 +31,7 @@ static_assert(!stdr::borrowed_range<range>);
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
 static_assert(stdr::random_access_range<range const>);
+static_assert(!stdr::contiguous_range<range const>);
 static_assert(!stdr::view<range const>);
 static_assert(stdr::sized_range<range const>);
 static_assert(!stdr::borrowed_range<range const>);

diff  --git a/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp
index f7568d39628dd..117c36b6e1a65 100644
--- a/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/range_concept_conformance.compile.pass.cpp
@@ -23,6 +23,7 @@ namespace stdr = std::ranges;
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::random_access_range<range>);
+static_assert(stdr::contiguous_range<range>);
 static_assert(!stdr::view<range>);
 static_assert(stdr::sized_range<range>);
 static_assert(!stdr::borrowed_range<range>);
@@ -30,6 +31,7 @@ static_assert(!stdr::borrowed_range<range>);
 static_assert(std::same_as<stdr::iterator_t<range const>, range::const_iterator>);
 static_assert(stdr::common_range<range const>);
 static_assert(stdr::random_access_range<range const>);
+static_assert(stdr::contiguous_range<range const>);
 static_assert(!stdr::view<range const>);
 static_assert(stdr::sized_range<range const>);
 static_assert(!stdr::borrowed_range<range const>);

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
index 33b3c9e3296ba..50fdc6a09119f 100644
--- 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,6 +23,7 @@ namespace stdr = std::ranges;
 static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
 static_assert(stdr::common_range<range>);
 static_assert(stdr::random_access_range<range>);
+static_assert(stdr::contiguous_range<range>);
 static_assert(stdr::view<range> && stdr::enable_view<range>);
 static_assert(stdr::sized_range<range>);
 static_assert(stdr::borrowed_range<range>);
@@ -30,6 +31,7 @@ static_assert(stdr::borrowed_range<range>);
 static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
 static_assert(stdr::common_range<range const>);
 static_assert(stdr::random_access_range<range const>);
+static_assert(stdr::contiguous_range<range const>);
 static_assert(!stdr::view<range const> && !stdr::enable_view<range const>);
 static_assert(stdr::sized_range<range const>);
 static_assert(stdr::borrowed_range<range const>);

diff  --git a/libcxx/test/std/ranges/range.req/range.refinements/contiguous_range.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.refinements/contiguous_range.compile.pass.cpp
new file mode 100644
index 0000000000000..538614a41635a
--- /dev/null
+++ b/libcxx/test/std/ranges/range.req/range.refinements/contiguous_range.compile.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: gcc-10
+
+// template<range _Rp>
+// concept contiguous_range;
+
+#include <ranges>
+
+#include "test_range.h"
+#include "test_iterators.h"
+
+namespace ranges = std::ranges;
+
+template <template <class...> class I>
+constexpr bool check_range() {
+  constexpr bool result = ranges::contiguous_range<test_range<I> >;
+  static_assert(ranges::contiguous_range<test_range<I> const> == result);
+  static_assert(ranges::contiguous_range<test_non_const_common_range<I> > == result);
+  static_assert(ranges::contiguous_range<test_non_const_range<I> > == result);
+  static_assert(ranges::contiguous_range<test_common_range<I> > == result);
+  static_assert(ranges::contiguous_range<test_common_range<I> const> == result);
+  static_assert(!ranges::contiguous_range<test_non_const_common_range<I> const>);
+  static_assert(!ranges::contiguous_range<test_non_const_range<I> const>);
+  return result;
+}
+
+static_assert(!check_range<cpp20_input_iterator>());
+static_assert(!check_range<forward_iterator>());
+static_assert(!check_range<bidirectional_iterator>());
+static_assert(!check_range<random_access_iterator>());
+static_assert(check_range<contiguous_iterator>());
+
+struct ContiguousWhenNonConst {
+    const int *begin() const;
+    const int *end() const;
+    int *begin();
+    int *end();
+    int *data() const;
+};
+static_assert( std::ranges::random_access_range<ContiguousWhenNonConst>);
+static_assert( std::ranges::contiguous_range<ContiguousWhenNonConst>);
+static_assert(!std::ranges::contiguous_range<const ContiguousWhenNonConst>);
+
+struct ContiguousWhenConst {
+    const int *begin() const;
+    const int *end() const;
+    int *begin();
+    int *end();
+    const int *data() const;
+};
+static_assert( std::ranges::random_access_range<ContiguousWhenConst>);
+static_assert(!std::ranges::contiguous_range<ContiguousWhenConst>);
+static_assert( std::ranges::contiguous_range<const ContiguousWhenConst>);
+
+struct DataFunctionWrongReturnType {
+    const int *begin() const;
+    const int *end() const;
+    const char *data() const;
+};
+static_assert( std::ranges::random_access_range<DataFunctionWrongReturnType>);
+static_assert(!std::ranges::contiguous_range<const DataFunctionWrongReturnType>);

diff  --git a/libcxx/test/std/ranges/range.req/range.refinements/subsumption.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.refinements/subsumption.compile.pass.cpp
index 4b33d00ca31e9..0d0b9de44c682 100644
--- a/libcxx/test/std/ranges/range.req/range.refinements/subsumption.compile.pass.cpp
+++ b/libcxx/test/std/ranges/range.req/range.refinements/subsumption.compile.pass.cpp
@@ -24,9 +24,8 @@ struct range {
   int* end();
 };
 
-// clang-format off
 template<std::ranges::range R>
-requires std::input_iterator<std::ranges::iterator_t<R> >
+requires std::input_iterator<std::ranges::iterator_t<R>>
 [[nodiscard]] constexpr bool check_input_range_subsumption() {
   return false;
 }
@@ -36,13 +35,11 @@ requires true
 [[nodiscard]] constexpr bool check_input_range_subsumption() {
   return true;
 }
-// clang-format on
 
 static_assert(check_input_range_subsumption<range>());
 
-// clang-format off
 template<std::ranges::input_range R>
-requires std::forward_iterator<std::ranges::iterator_t<R> >
+requires std::forward_iterator<std::ranges::iterator_t<R>>
 [[nodiscard]] constexpr bool check_forward_range_subsumption() {
   return false;
 }
@@ -52,13 +49,11 @@ requires true
 [[nodiscard]] constexpr bool check_forward_range_subsumption() {
   return true;
 }
-// clang-format on
 
 static_assert(check_forward_range_subsumption<range>());
 
-// clang-format off
 template<std::ranges::forward_range R>
-requires std::bidirectional_iterator<std::ranges::iterator_t<R> >
+requires std::bidirectional_iterator<std::ranges::iterator_t<R>>
 [[nodiscard]] constexpr bool check_bidirectional_range_subsumption() {
   return false;
 }
@@ -68,12 +63,11 @@ requires true
 [[nodiscard]] constexpr bool check_bidirectional_range_subsumption() {
   return true;
 }
-// clang-format on
 
 static_assert(check_bidirectional_range_subsumption<range>());
 
 template<std::ranges::bidirectional_range R>
-requires std::random_access_iterator<std::ranges::iterator_t<R> >
+requires std::random_access_iterator<std::ranges::iterator_t<R>>
 constexpr bool check_random_access_range_subsumption() {
   return false;
 }
@@ -85,3 +79,17 @@ constexpr bool check_random_access_range_subsumption() {
 }
 
 static_assert(check_random_access_range_subsumption<range>());
+
+template<std::ranges::random_access_range R>
+requires std::random_access_iterator<std::ranges::iterator_t<R>>
+constexpr bool check_contiguous_range_subsumption() {
+  return false;
+}
+
+template<std::ranges::contiguous_range>
+requires true
+constexpr bool check_contiguous_range_subsumption() {
+  return true;
+}
+
+static_assert(check_contiguous_range_subsumption<range>());

diff  --git a/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp
index c8e8023dddb3d..de92ca20a71c5 100644
--- a/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/re/re.results/range_concept_conformance.compile.pass.cpp
@@ -22,6 +22,7 @@ namespace stdr = std::ranges;
 static_assert(std::same_as<stdr::iterator_t<std::cmatch>, std::cmatch::iterator>);
 static_assert(stdr::common_range<std::cmatch>);
 static_assert(stdr::random_access_range<std::cmatch>);
+static_assert(stdr::contiguous_range<std::cmatch>);
 static_assert(!stdr::view<std::cmatch>);
 static_assert(stdr::sized_range<std::cmatch>);
 static_assert(!stdr::borrowed_range<std::cmatch>);
@@ -29,6 +30,7 @@ static_assert(!stdr::borrowed_range<std::cmatch>);
 static_assert(std::same_as<stdr::iterator_t<std::cmatch const>, std::cmatch::const_iterator>);
 static_assert(stdr::common_range<std::cmatch const>);
 static_assert(stdr::random_access_range<std::cmatch const>);
+static_assert(stdr::contiguous_range<std::cmatch const>);
 static_assert(!stdr::view<std::cmatch const>);
 static_assert(stdr::sized_range<std::cmatch const>);
 static_assert(!stdr::borrowed_range<std::cmatch const>);

diff  --git a/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp
index 6c3bea2d11304..398549696f532 100644
--- a/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/range_concept_conformance.compile.pass.cpp
@@ -22,6 +22,7 @@ namespace stdr = std::ranges;
 static_assert(std::same_as<stdr::iterator_t<std::string>, std::string::iterator>);
 static_assert(stdr::common_range<std::string>);
 static_assert(stdr::random_access_range<std::string>);
+static_assert(stdr::contiguous_range<std::string>);
 static_assert(!stdr::view<std::string>);
 static_assert(stdr::sized_range<std::string>);
 static_assert(!stdr::borrowed_range<std::string>);
@@ -29,6 +30,7 @@ static_assert(!stdr::borrowed_range<std::string>);
 static_assert(std::same_as<stdr::iterator_t<std::string const>, std::string::const_iterator>);
 static_assert(stdr::common_range<std::string const>);
 static_assert(stdr::random_access_range<std::string const>);
+static_assert(stdr::contiguous_range<std::string const>);
 static_assert(!stdr::view<std::string const>);
 static_assert(stdr::sized_range<std::string const>);
 static_assert(!stdr::borrowed_range<std::string const>);

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
index 179382f709bbf..78a803e14f59b 100644
--- 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,6 +22,7 @@ namespace stdr = std::ranges;
 static_assert(std::same_as<stdr::iterator_t<std::string_view>, std::string_view::iterator>);
 static_assert(stdr::common_range<std::string_view>);
 static_assert(stdr::random_access_range<std::string_view>);
+static_assert(stdr::contiguous_range<std::string_view>);
 static_assert(stdr::view<std::string_view> && stdr::enable_view<std::string_view>);
 static_assert(stdr::sized_range<std::string_view>);
 static_assert(stdr::borrowed_range<std::string_view>);
@@ -29,6 +30,7 @@ static_assert(stdr::borrowed_range<std::string_view>);
 static_assert(std::same_as<stdr::iterator_t<std::string_view const>, std::string_view::const_iterator>);
 static_assert(stdr::common_range<std::string_view const>);
 static_assert(stdr::random_access_range<std::string_view const>);
+static_assert(stdr::contiguous_range<std::string_view const>);
 static_assert(!stdr::view<std::string_view const> && !stdr::enable_view<std::string_view const>);
 static_assert(stdr::sized_range<std::string_view const>);
 static_assert(stdr::borrowed_range<std::string_view const>);


        


More information about the libcxx-commits mailing list