[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