[libcxx-commits] [libcxx] 8f1d878 - [libc++][ranges] Implement `permutable`.

Konstantin Varlamov via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 9 20:35:56 PST 2022


Author: Konstantin Varlamov
Date: 2022-02-09T20:34:20-08:00
New Revision: 8f1d8785df928040a9ee964eca02f95eb114182a

URL: https://github.com/llvm/llvm-project/commit/8f1d8785df928040a9ee964eca02f95eb114182a
DIFF: https://github.com/llvm/llvm-project/commit/8f1d8785df928040a9ee964eca02f95eb114182a.diff

LOG: [libc++][ranges] Implement `permutable`.

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

Added: 
    libcxx/include/__iterator/permutable.h
    libcxx/test/libcxx/diagnostics/detail.headers/iterator/permutable.module.verify.cpp
    libcxx/test/std/iterators/iterator.requirements/alg.req.permutable/permutable.compile.pass.cpp
    libcxx/test/std/iterators/iterator.requirements/alg.req.permutable/permutable.subsumption.compile.pass.cpp

Modified: 
    libcxx/docs/Status/RangesPaper.csv
    libcxx/include/CMakeLists.txt
    libcxx/include/iterator
    libcxx/include/module.modulemap

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/RangesPaper.csv b/libcxx/docs/Status/RangesPaper.csv
index 5c6ec87baf564..d93371da5d1b9 100644
--- a/libcxx/docs/Status/RangesPaper.csv
+++ b/libcxx/docs/Status/RangesPaper.csv
@@ -64,9 +64,9 @@ Section,Description,Dependencies,Assignee,Complete
 `[alg.req] <https://wg21.link/alg.req>`_: pt. 2,`indirectly_swappable <https://llvm.org/D105304>`_,"| [iterator.concepts]
 | [iterator.cust.swap]",Zoe Carver,✅
 `[alg.req] <https://wg21.link/alg.req>`_: pt. 3,`indirectly_comparable <https://llvm.org/D116268>`_,[projected],Nikolas Klauser,✅
-`[alg.req] <https://wg21.link/alg.req>`_: pt. 4,"| permutable
+`[alg.req] <https://wg21.link/alg.req>`_: pt. 4,"| `permutable <https://llvm.org/D119222>`_
 | mergeable
-| sortable",[iterator.concepts],Unassigned,Not started
+| sortable",[iterator.concepts],Konstantin Varlamov,In progress
 `[std.iterator.tags] <https://wg21.link/std.iterator.tags>`_,"| `contiguous_iterator_tag <https://reviews.llvm.org/rG45d048c20440989df2b4e1be1f9343225e7741ab>`_
 | `iterator_concept specialization for pointers <https://reviews.llvm.org/rG45d048c20440989df2b4e1be1f9343225e7741ab>`_
 ",[iterator.traits],Eric Fiselier,✅

diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 01b769d0ff6c5..8137afb470f1b 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -244,6 +244,7 @@ set(files
   __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
index 0000000000000..85834a23c8fca
--- /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 <class _Iterator>
+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
index 1786c4b8d41ec..654ca75804c23 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -147,6 +147,10 @@ template<class In, class Out>
 template<class I1, class I2 = I1>
   concept indirectly_swappable = see below;                // since C++20
 
+// [alg.req.permutable], concept permutable                // since C++20
+template<class I>
+  concept permutable = see below;
+
 template<class I1, class I2, class R, class P1 = identity,
          class P2 = identity>
   concept indirectly_comparable =
@@ -618,6 +622,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
 #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
index 442958bb736b4..5ef2c1c92ade7 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -628,6 +628,7 @@ module std [system] {
       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
index 0000000000000..ad550d151ec0b
--- /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
index 0000000000000..947ecaee3e30c
--- /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<class I>
+//   concept permutable = see below; // Since C++20
+
+#include <iterator>
+
+#include "MoveOnly.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+using AllConstraintsSatisfied = forward_iterator<int*>;
+static_assert( std::forward_iterator<AllConstraintsSatisfied>);
+static_assert( std::indirectly_movable_storable<AllConstraintsSatisfied, AllConstraintsSatisfied>);
+static_assert( std::indirectly_swappable<AllConstraintsSatisfied>);
+static_assert( std::permutable<AllConstraintsSatisfied>);
+
+using NotAForwardIterator = cpp20_input_iterator<int*>;
+static_assert(!std::forward_iterator<NotAForwardIterator>);
+static_assert( std::indirectly_movable_storable<NotAForwardIterator, NotAForwardIterator>);
+static_assert( std::indirectly_swappable<NotAForwardIterator>);
+static_assert(!std::permutable<NotAForwardIterator>);
+
+struct NonCopyable {
+  NonCopyable(const NonCopyable&) = delete;
+  NonCopyable& operator=(const NonCopyable&) = delete;
+  friend void swap(NonCopyable&, NonCopyable&);
+};
+using NotIMS = forward_iterator<NonCopyable*>;
+
+static_assert( std::forward_iterator<NotIMS>);
+static_assert(!std::indirectly_movable_storable<NotIMS, NotIMS>);
+static_assert( std::indirectly_swappable<NotIMS>);
+static_assert(!std::permutable<NotIMS>);
+
+// 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
index 0000000000000..63a3724652e30
--- /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<class I>
+//   concept permutable = see below; // Since C++20
+
+#include <iterator>
+
+template<class I> void test_subsumption() requires std::forward_iterator<I>;
+template<class I> void test_subsumption() requires std::indirectly_movable_storable<I, I>;
+template<class I> void test_subsumption() requires std::indirectly_swappable<I, I>;
+template<class I> constexpr bool test_subsumption() requires std::permutable<I> { return true; }
+static_assert(test_subsumption<int*>());


        


More information about the libcxx-commits mailing list