diff --git a/libcxx/docs/OneRangesProposalStatus.csv b/libcxx/docs/OneRangesProposalStatus.csv --- a/libcxx/docs/OneRangesProposalStatus.csv +++ b/libcxx/docs/OneRangesProposalStatus.csv @@ -3,7 +3,7 @@ [tuple.helper],Update includes.,,,, [function.objects],"Comparison functions: equal_to, less, etc.",[concepts],Zoe Carver,D100429, [memory.syn],Add specializations for uninitialized_* and destroy_*. ,"[concepts], [readable.traits]: iter_value_t",,, -[readable.traits]: indirectly_readable_traits,indirectly_readable_traits only. ,[concepts],Christopher Di Bella,D99461, +[readable.traits]: indirectly_readable_traits,indirectly_readable_traits only. ,[concepts],Christopher Di Bella,D99461,✅ [iterator.traits],Mainly updates to iterator_traits.,"[readable.traits]: indirectly_readable_traits, [concepts]",Christopher Di Bella,"D99854, D99855", [readable.traits]: iter_value_t,Finish implementing readable.traits.,"[readable.traits]: indirectly_readable_traits, [concepts], [iterator.traits]",Christopher Di Bella,D99863, [specialized.algorithms],NOT FINISHED,NOT FINISHED,,, @@ -58,4 +58,4 @@ [range.split],split_view,[range.all],,, [range.counted],view::counted,[range.subrange],,, [range.common],common_view,[range.all],,, -[range.reverse],reverse_view,[range.all],,, \ No newline at end of file +[range.reverse],reverse_view,[range.all],,, diff --git a/libcxx/include/iterator b/libcxx/include/iterator --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -48,6 +48,11 @@ using iter_rvalue_reference_t = decltype(ranges::iter_move(declval())); +// [iterator.concepts], iterator concepts +// [iterator.concept.readable], concept indirectly_­readable +template + concept indirectly_readable = see below; // since C++20 + template struct iterator @@ -2513,6 +2518,23 @@ requires requires(_Tp& __t) { { ranges::iter_move(__t) } -> __referenceable; } using iter_rvalue_reference_t = decltype(ranges::iter_move(declval<_Tp&>())); +// [iterator.concept.readable] +template +concept __indirectly_readable_impl = + requires(const _In __in) { + typename iter_value_t<_In>; + typename iter_reference_t<_In>; + typename iter_rvalue_reference_t<_In>; + { *__in } -> same_as>; + { ranges::iter_move(__in) } -> same_as>; + } && + common_reference_with&&, iter_value_t<_In>&> && + common_reference_with&&, iter_rvalue_reference_t<_In>&&> && + common_reference_with&&, const iter_value_t<_In>&>; + +template +concept indirectly_readable = __indirectly_readable_impl>; + #undef _LIBCPP_NOEXCEPT_RETURN #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, reverse_iterator, const_reverse_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::reverse_iterator>); +static_assert(std::indirectly_readable::const_reverse_iterator>); diff --git a/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, reverse_iterator, const_reverse_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::reverse_iterator>); +static_assert(std::indirectly_readable::const_reverse_iterator>); diff --git a/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, reverse_iterator, const_reverse_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::reverse_iterator>); +static_assert(std::indirectly_readable::const_reverse_iterator>); diff --git a/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, reverse_iterator, const_reverse_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::reverse_iterator>); +static_assert(std::indirectly_readable::const_reverse_iterator>); diff --git a/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, reverse_iterator, const_reverse_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::reverse_iterator>); +static_assert(std::indirectly_readable::const_reverse_iterator>); diff --git a/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, reverse_iterator, const_reverse_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::reverse_iterator>); +static_assert(std::indirectly_readable::const_reverse_iterator>); diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); diff --git a/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, reverse_iterator, const_reverse_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::reverse_iterator>); +static_assert(std::indirectly_readable::const_reverse_iterator>); diff --git a/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, reverse_iterator, const_reverse_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::reverse_iterator>); +static_assert(std::indirectly_readable::const_reverse_iterator>); diff --git a/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, local_iterator, const_local_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::local_iterator>); +static_assert(std::indirectly_readable::const_local_iterator>); diff --git a/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, local_iterator, const_local_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::local_iterator>); +static_assert(std::indirectly_readable::const_local_iterator>); diff --git a/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, local_iterator, const_local_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::local_iterator>); +static_assert(std::indirectly_readable::const_local_iterator>); diff --git a/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, const_iterator, local_iterator, const_local_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::const_iterator>); +static_assert(std::indirectly_readable::local_iterator>); +static_assert(std::indirectly_readable::const_local_iterator>); diff --git a/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// iterator, reverse_iterator + +#include + +#include + +static_assert(std::indirectly_readable::iterator>); +static_assert(std::indirectly_readable::reverse_iterator>); diff --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// directory_iterator, recursive_directory_iterator + +#include "filesystem_include.h" + +#include + +static_assert(std::indirectly_readable); +static_assert(std::indirectly_readable); diff --git a/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.readable/indirectly_readable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.readable/indirectly_readable.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/iterator.concepts/iterator.concept.readable/indirectly_readable.compile.pass.cpp @@ -0,0 +1,176 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// concept indirectly_readable; + +#include + +#include +#include + +#include "read_write.h" + +template +[[nodiscard]] constexpr bool check_indirectly_readable() { + constexpr bool result = std::indirectly_readable; + static_assert(std::indirectly_readable == result); + static_assert(std::indirectly_readable == result); + static_assert(std::indirectly_readable == result); + static_assert(std::indirectly_readable == result); + static_assert(std::indirectly_readable == result); + static_assert(std::indirectly_readable == result); + static_assert(std::indirectly_readable == result); + static_assert(std::indirectly_readable == result); + static_assert(std::indirectly_readable == result); + return result; +} + +static_assert(check_indirectly_readable()); +static_assert(check_indirectly_readable()); +static_assert(check_indirectly_readable()); +static_assert(check_indirectly_readable()); + +struct indirection_mismatch { + using value_type = int; + float& operator*() const; +}; +static_assert(!std::same_as, std::iter_reference_t > && + check_indirectly_readable()); +static_assert(!check_indirectly_readable()); + +// `iter_rvalue_reference_t` can't be missing unless the dereference operator is also missing. + +struct iter_move_mismatch { + using value_type = int; + value_type& operator*() const; + + friend float& iter_move(iter_move_mismatch&); +}; +static_assert(!check_indirectly_readable()); + +struct indirection_and_iter_move_mismatch { + using value_type = int; + float& operator*() const; + + friend unsigned long long& iter_move(indirection_and_iter_move_mismatch&); +}; +static_assert(!check_indirectly_readable()); + +struct missing_iter_value_t { + int operator*() const; +}; +static_assert(!check_indirectly_readable()); + +struct unrelated_lvalue_ref_and_rvalue_ref {}; + +struct iter_ref1 {}; +namespace std { +template <> +struct common_reference {}; + +template <> +struct common_reference {}; +} // namespace std +static_assert(!std::common_reference_with); + +struct bad_iter_reference_t { + using value_type = int; + iter_ref1& operator*() const; +}; +static_assert(!check_indirectly_readable()); + +struct iter_ref2 {}; +struct iter_rvalue_ref {}; + +struct unrelated_iter_ref_rvalue_and_iter_rvalue_ref_rvalue { + using value_type = iter_ref2; + iter_ref2& operator*() const; + friend iter_rvalue_ref&& iter_move(unrelated_iter_ref_rvalue_and_iter_rvalue_ref_rvalue); +}; +static_assert(!check_indirectly_readable()); + +struct iter_ref3 { + operator iter_rvalue_ref() const; +}; +namespace std { +template