[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
This commit is contained in:
Nikolas Klauser 2022-01-04 19:55:37 +01:00
parent 090f8ec8a8
commit 6d722801d1
7 changed files with 105 additions and 1 deletions

View File

@ -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

1 Section Description Dependencies Assignee Complete
63
64
65
66
67
68
69

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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" }

View File

@ -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>

View File

@ -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>()));