diff --git a/libcxx/docs/Status/RangesPaper.csv b/libcxx/docs/Status/RangesPaper.csv --- a/libcxx/docs/Status/RangesPaper.csv +++ b/libcxx/docs/Status/RangesPaper.csv @@ -64,9 +64,9 @@ `[alg.req] `_: pt. 2,`indirectly_swappable `_,"| [iterator.concepts] | [iterator.cust.swap]",Zoe Carver,✅ `[alg.req] `_: pt. 3,`indirectly_comparable `_,[projected],Nikolas Klauser,✅ -`[alg.req] `_: pt. 4,"| permutable +`[alg.req] `_: pt. 4,"| `permutable `_ | mergeable -| sortable",[iterator.concepts],Unassigned,Not started +| sortable",[iterator.concepts],Konstantin Varlamov,In progress `[std.iterator.tags] `_,"| `contiguous_iterator_tag `_ | `iterator_concept specialization for pointers `_ ",[iterator.traits],Eric Fiselier,✅ diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -244,6 +244,7 @@ __iterator/next.h __iterator/ostream_iterator.h __iterator/ostreambuf_iterator.h + __iterator/permutable.h __iterator/prev.h __iterator/projected.h __iterator/readable_traits.h diff --git a/libcxx/include/__iterator/permutable.h b/libcxx/include/__iterator/permutable.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__iterator/permutable.h @@ -0,0 +1,35 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___ITERATOR_PERMUTABLE_H +#define _LIBCPP___ITERATOR_PERMUTABLE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iter_swap.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_CONCEPTS) + +template +concept permutable = + forward_iterator<_Iterator> && + indirectly_movable_storable<_Iterator, _Iterator> && + indirectly_swappable<_Iterator, _Iterator>; + +#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ITERATOR_PERMUTABLE_H diff --git a/libcxx/include/iterator b/libcxx/include/iterator --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -147,6 +147,10 @@ template concept indirectly_swappable = see below; // since C++20 +// [alg.req.permutable], concept permutable // since C++20 +template + concept permutable = see below; + template concept indirectly_comparable = @@ -618,6 +622,7 @@ #include <__iterator/next.h> #include <__iterator/ostream_iterator.h> #include <__iterator/ostreambuf_iterator.h> +#include <__iterator/permutable.h> #include <__iterator/prev.h> #include <__iterator/projected.h> #include <__iterator/readable_traits.h> diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap --- a/libcxx/include/module.modulemap +++ b/libcxx/include/module.modulemap @@ -628,6 +628,7 @@ module next { private header "__iterator/next.h" } module ostream_iterator { private header "__iterator/ostream_iterator.h" } module ostreambuf_iterator { private header "__iterator/ostreambuf_iterator.h" } + module permutable { private header "__iterator/permutable.h" } module prev { private header "__iterator/prev.h" } module projected { private header "__iterator/projected.h" } module readable_traits { private header "__iterator/readable_traits.h" } diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/iterator/permutable.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/iterator/permutable.module.verify.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/diagnostics/detail.headers/iterator/permutable.module.verify.cpp @@ -0,0 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// REQUIRES: modules-build + +// WARNING: This test was generated by 'generate_private_header_tests.py' +// and should not be edited manually. + +// expected-error@*:* {{use of private header from outside its module: '__iterator/permutable.h'}} +#include <__iterator/permutable.h> diff --git a/libcxx/test/std/iterators/iterator.requirements/alg.req.permutable/permutable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/alg.req.permutable/permutable.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/alg.req.permutable/permutable.compile.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept permutable = see below; // Since C++20 + +#include + +#include "MoveOnly.h" +#include "test_iterators.h" +#include "test_macros.h" + +using AllConstraintsSatisfied = forward_iterator; +static_assert( std::forward_iterator); +static_assert( std::indirectly_movable_storable); +static_assert( std::indirectly_swappable); +static_assert( std::permutable); + +using NotAForwardIterator = cpp20_input_iterator; +static_assert(!std::forward_iterator); +static_assert( std::indirectly_movable_storable); +static_assert( std::indirectly_swappable); +static_assert(!std::permutable); + +struct NonCopyable { + NonCopyable(const NonCopyable&) = delete; + NonCopyable& operator=(const NonCopyable&) = delete; + friend void swap(NonCopyable&, NonCopyable&); +}; +using NotIMS = forward_iterator; + +static_assert( std::forward_iterator); +static_assert(!std::indirectly_movable_storable); +static_assert( std::indirectly_swappable); +static_assert(!std::permutable); + +// Note: it is impossible for an iterator to satisfy `indirectly_movable_storable` but not `indirectly_swappable`: +// `indirectly_swappable` requires both iterators to be `indirectly_readable` and for `ranges::iter_swap` to be +// well-formed for both iterators. `indirectly_movable_storable` also requires the iterator to be `indirectly_readable`. +// `ranges::iter_swap` is always defined for `indirectly_movable_storable` iterators. diff --git a/libcxx/test/std/iterators/iterator.requirements/alg.req.permutable/permutable.subsumption.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/alg.req.permutable/permutable.subsumption.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/iterators/iterator.requirements/alg.req.permutable/permutable.subsumption.compile.pass.cpp @@ -0,0 +1,21 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +// template +// concept permutable = see below; // Since C++20 + +#include + +template void test_subsumption() requires std::forward_iterator; +template void test_subsumption() requires std::indirectly_movable_storable; +template void test_subsumption() requires std::indirectly_swappable; +template constexpr bool test_subsumption() requires std::permutable { return true; } +static_assert(test_subsumption());