[libcxx-commits] [libcxx] 8e97946 - [libc++][ranges] Implement `std::sortable`.

Konstantin Varlamov via libcxx-commits libcxx-commits at lists.llvm.org
Thu Feb 17 20:17:58 PST 2022


Author: Konstantin Varlamov
Date: 2022-02-17T20:17:42-08:00
New Revision: 8e979460bb27610d574733ca5b75afae0cdfb3c9

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

LOG: [libc++][ranges] Implement `std::sortable`.

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

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

Modified: 
    libcxx/docs/Status/RangesPaper.csv
    libcxx/include/CMakeLists.txt
    libcxx/include/iterator
    libcxx/include/module.modulemap
    libcxx/test/std/iterators/iterator.requirements/alg.req.permutable/permutable.compile.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/RangesPaper.csv b/libcxx/docs/Status/RangesPaper.csv
index e67abd35873dc..ebbc5c10916cc 100644
--- a/libcxx/docs/Status/RangesPaper.csv
+++ b/libcxx/docs/Status/RangesPaper.csv
@@ -66,7 +66,7 @@ Section,Description,Dependencies,Assignee,Complete
 `[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 <https://llvm.org/D119222>`_
 | `mergeable <https://llvm.org/D119489>`_
-| sortable",[iterator.concepts],Konstantin Varlamov,In progress
+| `sortable <https://llvm.org/D119619>`_",[iterator.concepts],Konstantin Varlamov,✅
 `[std.iterator.tags] <https://wg21.link/std.iterator.tags>`_,"| `contiguous_iterator_tag <https://llvm.org/rG45d048c20440989df2b4e1be1f9343225e7741ab>`_
 | `iterator_concept specialization for pointers <https://llvm.org/rG45d048c20440989df2b4e1be1f9343225e7741ab>`_
 ",[iterator.traits],Eric Fiselier,✅

diff  --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 0858a90fe2a6d..72d06fc3a7532 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -255,6 +255,7 @@ set(files
   __iterator/reverse_access.h
   __iterator/reverse_iterator.h
   __iterator/size.h
+  __iterator/sortable.h
   __iterator/unreachable_sentinel.h
   __iterator/wrap_iter.h
   __libcpp_version

diff  --git a/libcxx/include/__iterator/sortable.h b/libcxx/include/__iterator/sortable.h
new file mode 100644
index 0000000000000..77a553d3ec30e
--- /dev/null
+++ b/libcxx/include/__iterator/sortable.h
@@ -0,0 +1,37 @@
+// -*- 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_SORTABLE_H
+#define _LIBCPP___ITERATOR_SORTABLE_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__functional/ranges_operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/permutable.h>
+#include <__iterator/projected.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+template <class _Iter, class _Comp = ranges::less, class _Proj = identity>
+concept sortable =
+  permutable<_Iter> &&
+  indirect_strict_weak_order<_Comp, projected<_Iter, _Proj>>;
+
+#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ITERATOR_SORTABLE_H

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index 1668be3a60c8e..6e2eb4a78c287 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -138,10 +138,10 @@ template<class In, class Out>
 
 // [alg.req.ind.copy], concept indirectly_copyable
 template<class In, class Out>
-  concept indirectly_copyable = see below;                  // since C++20
+  concept indirectly_copyable = see below;                 // since C++20
 
 template<class In, class Out>
-  concept indirectly_copyable_storable = see below;         // since C++20
+  concept indirectly_copyable_storable = see below;        // since C++20
 
 // [alg.req.ind.swap], concept indirectly_swappable
 template<class I1, class I2 = I1>
@@ -152,15 +152,19 @@ template<class I1, class I2, class R, class P1 = identity,
   concept indirectly_comparable =
     indirect_binary_predicate<R, projected<I1, P1>, projected<I2, P2>>; // since C++20
 
-// [alg.req.permutable], concept permutable                // since C++20
+// [alg.req.permutable], concept permutable
 template<class I>
-  concept permutable = see below;
+  concept permutable = see below;                          // since C++20
 
  // [alg.req.mergeable], concept mergeable
 template<class I1, class I2, class Out,
     class R = ranges::less, class P1 = identity, class P2 = identity>
   concept mergeable = see below;                           // since C++20
 
+// [alg.req.sortable], concept sortable
+template<class I, class R = ranges::less, class P = identity>
+  concept sortable = see below;                            // since C++20
+
 template<input_or_output_iterator I, sentinel_for<I> S>
   requires (!same_as<I, S> && copyable<I>)
 class common_iterator;                                     // since C++20
@@ -640,6 +644,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
 #include <__iterator/reverse_access.h>
 #include <__iterator/reverse_iterator.h>
 #include <__iterator/size.h>
+#include <__iterator/sortable.h>
 #include <__iterator/unreachable_sentinel.h>
 #include <__iterator/wrap_iter.h>
 #include <__memory/addressof.h>

diff  --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index ea050751d9ca7..890b7fef933ad 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -640,6 +640,7 @@ module std [system] {
       module reverse_access        { private header "__iterator/reverse_access.h" }
       module reverse_iterator      { private header "__iterator/reverse_iterator.h" }
       module size                  { private header "__iterator/size.h" }
+      module sortable              { private header "__iterator/sortable.h" }
       module unreachable_sentinel  { private header "__iterator/unreachable_sentinel.h" }
       module wrap_iter             { private header "__iterator/wrap_iter.h" }
     }

diff  --git a/libcxx/test/libcxx/diagnostics/detail.headers/iterator/sortable.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/iterator/sortable.module.verify.cpp
new file mode 100644
index 0000000000000..47ed326bccc54
--- /dev/null
+++ b/libcxx/test/libcxx/diagnostics/detail.headers/iterator/sortable.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/sortable.h'}}
+#include <__iterator/sortable.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
index 947ecaee3e30c..b72e684bf90c3 100644
--- 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
@@ -14,9 +14,7 @@
 
 #include <iterator>
 
-#include "MoveOnly.h"
 #include "test_iterators.h"
-#include "test_macros.h"
 
 using AllConstraintsSatisfied = forward_iterator<int*>;
 static_assert( std::forward_iterator<AllConstraintsSatisfied>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/alg.req.sortable/sortable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/alg.req.sortable/sortable.compile.pass.cpp
new file mode 100644
index 0000000000000..44f6ef8444dd7
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/alg.req.sortable/sortable.compile.pass.cpp
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: libcpp-has-no-incomplete-ranges
+
+// template<class I, class R = ranges::less, class P = identity>
+//   concept sortable = see below;                            // since C++20
+
+#include <iterator>
+
+#include <functional>
+
+using CompInt = bool(*)(int, int);
+using CompDefault = std::ranges::less;
+
+using AllConstraintsSatisfied = int*;
+static_assert( std::permutable<AllConstraintsSatisfied>);
+static_assert( std::indirect_strict_weak_order<CompDefault, AllConstraintsSatisfied>);
+static_assert( std::sortable<AllConstraintsSatisfied>);
+static_assert( std::indirect_strict_weak_order<CompInt, AllConstraintsSatisfied>);
+static_assert( std::sortable<AllConstraintsSatisfied, CompInt>);
+
+struct Foo {};
+using Proj = int(*)(Foo);
+static_assert( std::permutable<Foo*>);
+static_assert(!std::indirect_strict_weak_order<CompDefault, Foo*>);
+static_assert( std::indirect_strict_weak_order<CompDefault, std::projected<Foo*, Proj>>);
+static_assert(!std::sortable<Foo*, CompDefault>);
+static_assert( std::sortable<Foo*, CompDefault, Proj>);
+static_assert(!std::indirect_strict_weak_order<CompInt, Foo*>);
+static_assert( std::indirect_strict_weak_order<CompInt, std::projected<Foo*, Proj>>);
+static_assert(!std::sortable<Foo*, CompInt>);
+static_assert( std::sortable<Foo*, CompInt, Proj>);
+
+using NotPermutable = const int*;
+static_assert(!std::permutable<NotPermutable>);
+static_assert( std::indirect_strict_weak_order<CompInt, NotPermutable>);
+static_assert(!std::sortable<NotPermutable, CompInt>);
+
+struct Empty {};
+using NoIndirectStrictWeakOrder = Empty*;
+static_assert( std::permutable<NoIndirectStrictWeakOrder>);
+static_assert(!std::indirect_strict_weak_order<CompInt, NoIndirectStrictWeakOrder>);
+static_assert(!std::sortable<NoIndirectStrictWeakOrder, CompInt>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/alg.req.sortable/sortable.subsumption.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/alg.req.sortable/sortable.subsumption.compile.pass.cpp
new file mode 100644
index 0000000000000..135499d60a508
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/alg.req.sortable/sortable.subsumption.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: libcpp-has-no-incomplete-ranges
+
+// template<class I, class R = ranges::less, class P = identity>
+//   concept sortable = see below;                            // since C++20
+
+#include <iterator>
+
+#include <functional>
+
+template <class I, class R, class P> void test_subsumption() requires std::permutable<I>;
+
+template <class I, class R, class P> void test_subsumption()
+    requires std::indirect_strict_weak_order<R, std::projected<I, P>>;
+
+template <class I, class R, class P> constexpr bool test_subsumption() requires std::sortable<I, R, P> { return true; }
+
+static_assert(test_subsumption<int*, std::ranges::less, std::identity>());


        


More information about the libcxx-commits mailing list