[libcxx-commits] [libcxx] 6d72280 - [libc++][ranges] Add indirectly_comparable concept
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jan 4 14:42:19 PST 2022
Author: Nikolas Klauser
Date: 2022-01-04T23:40:57+01:00
New Revision: 6d722801d1a2cd1af8e139c8052443feb62c0eae
URL: https://github.com/llvm/llvm-project/commit/6d722801d1a2cd1af8e139c8052443feb62c0eae
DIFF: https://github.com/llvm/llvm-project/commit/6d722801d1a2cd1af8e139c8052443feb62c0eae.diff
LOG: [libc++][ranges] Add indirectly_comparable concept
Add `indirectly_comparable` concept
Reviewed By: Quuxplusone, Mordante, #libc
Spies: mgorny, libcxx-commits
Differential Revision: https://reviews.llvm.org/D116268
Added:
libcxx/include/__iterator/indirectly_comparable.h
libcxx/test/libcxx/diagnostics/detail.headers/iterator/indirectly_comparable.module.verify.cpp
libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_comparable.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 ed1900bd12441..2c972f27e0047 100644
--- a/libcxx/docs/Status/RangesPaper.csv
+++ b/libcxx/docs/Status/RangesPaper.csv
@@ -63,7 +63,7 @@ Section,Description,Dependencies,Assignee,Complete
| indirectly_copyable_storable",[iterator.concepts],Zoe Carver,In progress
[common.alg.req]: pt. 2,indirectly_swappable,"| [iterator.concepts]
| [iterator.cust.swap]",Zoe Carver,✅
-[common.alg.req]: pt. 3,indirectly_comparable,[projected],Louis Dionne,Not started
+[common.alg.req]: pt. 3,indirectly_comparable,[projected],Nikolas Klauser,✅
[common.alg.req]: pt. 4,"| permutable
| mergeable
| sortable",[iterator.concepts],Unassigned,Not started
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 180f7d4259cd3..2354244a5f5e6 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -215,6 +215,7 @@ set(files
__iterator/erase_if_container.h
__iterator/front_insert_iterator.h
__iterator/incrementable_traits.h
+ __iterator/indirectly_comparable.h
__iterator/insert_iterator.h
__iterator/istream_iterator.h
__iterator/istreambuf_iterator.h
diff --git a/libcxx/include/__iterator/indirectly_comparable.h b/libcxx/include/__iterator/indirectly_comparable.h
new file mode 100644
index 0000000000000..3129b2dcf65e5
--- /dev/null
+++ b/libcxx/include/__iterator/indirectly_comparable.h
@@ -0,0 +1,30 @@
+// -*- 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_INDIRECTLY_COMPARABLE_H
+#define _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H
+
+#include <__config>
+#include <__functional/identity.h>
+#include <__iterator/concepts.h>
+#include <__iterator/projected.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#ifndef _LIBCPP_HAS_NO_RANGES
+
+template <class _I1, class _I2, class _Rp, class _P1 = identity, class _P2 = identity>
+concept indirectly_comparable =
+ indirect_binary_predicate<_Rp, projected<_I1, _P1>, projected<_I2, _P2>>;
+
+#endif // _LIBCPP_HAS_NO_RANGES
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H
diff --git a/libcxx/include/iterator b/libcxx/include/iterator
index 4dd9902d79a2c..be223192de2df 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -140,6 +140,11 @@ template<class In, class Out>
template<class I1, class I2 = I1>
concept indirectly_swappable = see below; // since C++20
+template<class I1, class I2, class R, class P1 = identity,
+ class P2 = identity>
+ concept indirectly_comparable =
+ indirect_binary_predicate<R, projected<I1, P1>, projected<I2, P2>>; // 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
@@ -593,6 +598,7 @@ template <class E> constexpr const E* data(initializer_list<E> il) noexcept;
#include <__iterator/erase_if_container.h>
#include <__iterator/front_insert_iterator.h>
#include <__iterator/incrementable_traits.h>
+#include <__iterator/indirectly_comparable.h>
#include <__iterator/insert_iterator.h>
#include <__iterator/istreambuf_iterator.h>
#include <__iterator/istream_iterator.h>
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 1dc6db406a742..8eba28b0efb31 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -594,6 +594,7 @@ module std [system] {
module erase_if_container { private header "__iterator/erase_if_container.h" }
module front_insert_iterator { private header "__iterator/front_insert_iterator.h" }
module incrementable_traits { private header "__iterator/incrementable_traits.h" }
+ module indirectly_comparable { private header "__iterator/indirectly_comparable.h" }
module insert_iterator { private header "__iterator/insert_iterator.h" }
module istream_iterator { private header "__iterator/istream_iterator.h" }
module istreambuf_iterator { private header "__iterator/istreambuf_iterator.h" }
diff --git a/libcxx/test/libcxx/diagnostics/detail.headers/iterator/indirectly_comparable.module.verify.cpp b/libcxx/test/libcxx/diagnostics/detail.headers/iterator/indirectly_comparable.module.verify.cpp
new file mode 100644
index 0000000000000..7115f7241e893
--- /dev/null
+++ b/libcxx/test/libcxx/diagnostics/detail.headers/iterator/indirectly_comparable.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/indirectly_comparable.h'}}
+#include <__iterator/indirectly_comparable.h>
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_comparable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_comparable.compile.pass.cpp
new file mode 100644
index 0000000000000..ff415cc4ea32b
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable/indirectinvocable/indirectly_comparable.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
+
+// template<class I1, class I2, class R, class P1, class P2>
+// concept indirectly_comparable;
+
+#include <functional>
+#include <iterator>
+#include <type_traits>
+
+struct Deref {
+ int operator()(int*) const;
+};
+
+static_assert(!std::indirectly_comparable<int, int, std::less<int>>); // not dereferenceable
+static_assert(!std::indirectly_comparable<int*, int*, int>); // not a predicate
+static_assert( std::indirectly_comparable<int*, int*, std::less<int>>);
+static_assert(!std::indirectly_comparable<int**, int*, std::less<int>>);
+static_assert( std::indirectly_comparable<int**, int*, std::less<int>, Deref>);
+static_assert(!std::indirectly_comparable<int**, int*, std::less<int>, Deref, Deref>);
+static_assert(!std::indirectly_comparable<int**, int*, std::less<int>, std::identity, Deref>);
+static_assert( std::indirectly_comparable<int*, int**, std::less<int>, std::identity, Deref>);
+
+template<class F>
+ requires std::indirectly_comparable<int*, char*, F>
+ && true // This true is an additional atomic constraint as a tie breaker
+constexpr bool subsumes(F) { return true; }
+
+template<class F>
+ requires std::indirect_binary_predicate<F, std::projected<int*, std::identity>, std::projected<char*, std::identity>>
+void subsumes(F);
+
+template<class F>
+ requires std::indirect_binary_predicate<F, std::projected<int*, std::identity>, std::projected<char*, std::identity>>
+ && true // This true is an additional atomic constraint as a tie breaker
+constexpr bool is_subsumed(F) { return true; }
+
+template<class F>
+ requires std::indirectly_comparable<int*, char*, F>
+void is_subsumed(F);
+
+static_assert(subsumes(std::less<int>()));
+static_assert(is_subsumed(std::less<int>()));
More information about the libcxx-commits
mailing list