diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h --- a/libcxx/include/__iterator/concepts.h +++ b/libcxx/include/__iterator/concepts.h @@ -12,6 +12,10 @@ #include <__config> #include +#include <__iterator/iter_move.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header @@ -24,18 +28,36 @@ #if !defined(_LIBCPP_HAS_NO_RANGES) -template -using __with_reference = _Tp&; +// clang-format off -template -concept __referenceable = requires { - typename __with_reference<_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 __dereferenceable = requires(_Tp& __t) { - { *__t } -> __referenceable; // not required to be equality-preserving -}; +template +concept indirectly_readable = __indirectly_readable_impl >; + +// [iterator.concept.writable] +template +concept indirectly_writable = + requires(_Out&& __o, _Tp&& __t) { + *__o = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + *_VSTD::forward<_Out>(__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*__o) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + const_cast&&>(*_VSTD::forward<_Out>(__o)) = _VSTD::forward<_Tp>(__t); // not required to be equality-preserving + }; + +// clang-format on #endif // !defined(_LIBCPP_HAS_NO_RANGES) diff --git a/libcxx/include/__iterator/incrementable_traits.h b/libcxx/include/__iterator/incrementable_traits.h --- a/libcxx/include/__iterator/incrementable_traits.h +++ b/libcxx/include/__iterator/incrementable_traits.h @@ -11,7 +11,7 @@ #define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H #include <__config> -#include <__iterator/concepts.h> +#include #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__iterator/iter_move.h b/libcxx/include/__iterator/iter_move.h --- a/libcxx/include/__iterator/iter_move.h +++ b/libcxx/include/__iterator/iter_move.h @@ -11,7 +11,7 @@ #define _LIBCPP___ITERATOR_ITER_MOVE_H #include <__config> -#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> #include // __class_or_enum #include #include diff --git a/libcxx/include/__iterator/iterator_traits.h b/libcxx/include/__iterator/iterator_traits.h --- a/libcxx/include/__iterator/iterator_traits.h +++ b/libcxx/include/__iterator/iterator_traits.h @@ -27,9 +27,23 @@ #if !defined(_LIBCPP_HAS_NO_RANGES) +template +using __with_reference = _Tp&; + +template +concept __referenceable = requires { + typename __with_reference<_Tp>; +}; + +template +concept __dereferenceable = requires(_Tp& __t) { + { *__t } -> __referenceable; // not required to be equality-preserving +}; + // [iterator.traits] template<__dereferenceable _Tp> using iter_reference_t = decltype(*declval<_Tp&>()); + #endif // !defined(_LIBCPP_HAS_NO_RANGES) template diff --git a/libcxx/include/__iterator/readable_traits.h b/libcxx/include/__iterator/readable_traits.h --- a/libcxx/include/__iterator/readable_traits.h +++ b/libcxx/include/__iterator/readable_traits.h @@ -11,7 +11,8 @@ #define _LIBCPP___ITERATOR_READABLE_TRAITS_H #include <__config> -#include <__iterator/concepts.h> +#include +#include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/libcxx/include/iterator b/libcxx/include/iterator --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -43,6 +43,15 @@ requires ... using iter_rvalue_reference_t = decltype(ranges::iter_move(declval())); // since C++20 +// [iterator.concepts], iterator concepts +// [iterator.concept.readable], concept indirectly_­readable +template + concept indirectly_readable = see below; // since C++20 + +// [iterator.concept.writable], concept indirectly_­writable +template + concept indirectly_writable = see below; // since C++20 + template struct iterator @@ -438,6 +447,7 @@ #include #if !defined(_LIBCPP_HAS_NO_RANGES) +#include <__iterator/concepts.h> # include <__iterator/iter_move.h> #endif 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,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::map::iterator; +using const_iterator = std::map::const_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::multimap::iterator; +using const_iterator = std::multimap::const_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::multiset::iterator; +using const_iterator = std::multiset::const_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::set::iterator; +using const_iterator = std::set::const_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,26 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::array::iterator; +using const_iterator = std::array::const_iterator; + +static_assert(std::indirectly_readable); +static_assert(std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::deque::iterator; +using const_iterator = std::deque::const_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::forward_list::iterator; +using const_iterator = std::forward_list::const_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::list::iterator; +using const_iterator = std::list::const_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); diff --git a/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::vector::iterator; +using const_iterator = std::vector::const_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::vector::iterator; +using const_iterator = std::vector::const_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::unordered_map::iterator; +using const_iterator = std::unordered_map::const_iterator; +using local_iterator = std::unordered_map::local_iterator; +using const_local_iterator = std::unordered_map::const_local_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::unordered_multimap::iterator; +using const_iterator = std::unordered_multimap::const_iterator; +using local_iterator = std::unordered_multimap::local_iterator; +using const_local_iterator = std::unordered_multimap::const_local_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::unordered_multiset::iterator; +using const_iterator = std::unordered_multiset::const_iterator; +using local_iterator = std::unordered_multiset::local_iterator; +using const_local_iterator = std::unordered_multiset::const_local_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,35 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::unordered_set::iterator; +using const_iterator = std::unordered_set::const_iterator; +using local_iterator = std::unordered_set::local_iterator; +using const_local_iterator = std::unordered_set::const_local_iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); + +static_assert(std::indirectly_readable); +static_assert(!std::indirectly_writable); 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,23 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +using iterator = std::span::iterator; +using value_type = iterator::value_type; + +static_assert(std::indirectly_readable); +static_assert(std::indirectly_writable); 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,24 @@ +//===----------------------------------------------------------------------===// +// +// 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_writable); + +static_assert(std::indirectly_readable); +static_assert( + !std::indirectly_writable); 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,199 @@ +//===----------------------------------------------------------------------===// +// +// 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 "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()); + +static_assert(check_indirectly_readable()); +static_assert(check_indirectly_readable()); +static_assert(check_indirectly_readable()); +static_assert(check_indirectly_readable()); + +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