Skip to content

Commit

Permalink
[libc++][ranges] Implement indirectly_copyable{,_storable}.
Browse files Browse the repository at this point in the history
Also refactor tests for `indirectly_movable{,_storable}`.

Differential Revision: https://reviews.llvm.org/D118432
  • Loading branch information
var-const committed Feb 2, 2022
1 parent 712b31e commit e65d376
Show file tree
Hide file tree
Showing 43 changed files with 770 additions and 100 deletions.
4 changes: 2 additions & 2 deletions libcxx/docs/Status/RangesPaper.csv
Expand Up @@ -59,8 +59,8 @@ Section,Description,Dependencies,Assignee,Complete
`[projected] <https://wg21.link/projected>`_,`ranges::projected <https://llvm.org/D101277>`_,[iterator.concepts],Louis Dionne,✅
`[common.alg.req] <https://wg21.link/common.alg.req>`_: pt. 1,"| `indirectly_movable <https://llvm.org/D102639>`_
| `indirectly_movable_storable <https://llvm.org/D102639>`_
| indirectly_copyable
| indirectly_copyable_storable",[iterator.concepts],Zoe Carver,In progress
| `indirectly_copyable <https://llvm.org/D118432>`_
| `indirectly_copyable_storable <https://llvm.org/D118432>`_",[iterator.concepts],Zoe Carver and Konstantin Varlamov,✅
`[common.alg.req] <https://wg21.link/common.alg.req>`_: pt. 2,`indirectly_swappable <https://llvm.org/D105304>`_,"| [iterator.concepts]
| [iterator.cust.swap]",Zoe Carver,✅
`[common.alg.req] <https://wg21.link/common.alg.req>`_: pt. 3,`indirectly_comparable <https://llvm.org/D116268>`_,[projected],Nikolas Klauser,✅
Expand Down
16 changes: 16 additions & 0 deletions libcxx/include/__iterator/concepts.h
Expand Up @@ -254,6 +254,22 @@ concept indirectly_movable_storable =
constructible_from<iter_value_t<_In>, iter_rvalue_reference_t<_In>> &&
assignable_from<iter_value_t<_In>&, iter_rvalue_reference_t<_In>>;

template<class _In, class _Out>
concept indirectly_copyable =
indirectly_readable<_In> &&
indirectly_writable<_Out, iter_reference_t<_In>>;

template<class _In, class _Out>
concept indirectly_copyable_storable =
indirectly_copyable<_In, _Out> &&
indirectly_writable<_Out, iter_value_t<_In>&> &&
indirectly_writable<_Out, const iter_value_t<_In>&> &&
indirectly_writable<_Out, iter_value_t<_In>&&> &&
indirectly_writable<_Out, const iter_value_t<_In>&&> &&
copyable<iter_value_t<_In>> &&
constructible_from<iter_value_t<_In>, iter_reference_t<_In>> &&
assignable_from<iter_value_t<_In>&, iter_reference_t<_In>>;

// Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle
// (both iter_swap and indirectly_swappable require indirectly_readable).

Expand Down
7 changes: 7 additions & 0 deletions libcxx/include/iterator
Expand Up @@ -136,6 +136,13 @@ template<class In, class Out>
template<class In, class Out>
concept indirectly_movable_storable = see below; // since C++20
// [alg.req.ind.copy], concept indirectly_copyable
template<class In, class Out>
concept indirectly_copyable = see below; // since C++20
template<class In, class Out>
concept indirectly_copyable_storable = see below; // since C++20
// [alg.req.ind.swap], concept indirectly_swappable
template<class I1, class I2 = I1>
concept indirectly_swappable = see below; // since C++20
Expand Down
Expand Up @@ -34,6 +34,8 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
static_assert( std::indirectly_movable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<iterator, std::pair<int, int>*>);
static_assert( std::indirectly_copyable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<iterator, iterator>);

static_assert(std::bidirectional_iterator<const_iterator>);
Expand Down
Expand Up @@ -34,6 +34,8 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
static_assert( std::indirectly_movable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<iterator, std::pair<int, int>*>);
static_assert( std::indirectly_copyable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<iterator, iterator>);

static_assert(std::bidirectional_iterator<const_iterator>);
Expand Down
Expand Up @@ -34,6 +34,8 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
static_assert(std::indirectly_movable<iterator, int*>);
static_assert(std::indirectly_movable_storable<iterator, int*>);
static_assert(std::indirectly_copyable<iterator, int*>);
static_assert(std::indirectly_copyable_storable<iterator, int*>);
static_assert(!std::indirectly_swappable<iterator, iterator>);

static_assert(std::bidirectional_iterator<const_iterator>);
Expand Down
Expand Up @@ -34,6 +34,8 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
static_assert(std::indirectly_movable<iterator, int*>);
static_assert(std::indirectly_movable_storable<iterator, int*>);
static_assert(std::indirectly_copyable<iterator, int*>);
static_assert(std::indirectly_copyable_storable<iterator, int*>);
static_assert(!std::indirectly_swappable<iterator, iterator>);

static_assert(std::bidirectional_iterator<const_iterator>);
Expand Down
Expand Up @@ -38,6 +38,14 @@ static_assert( std::indirectly_movable<iterator, reverse_iterator>);
static_assert( std::indirectly_movable_storable<iterator, reverse_iterator>);
static_assert(!std::indirectly_movable<iterator, const_reverse_iterator>);
static_assert(!std::indirectly_movable_storable<iterator, const_reverse_iterator>);
static_assert( std::indirectly_copyable<iterator, iterator>);
static_assert( std::indirectly_copyable_storable<iterator, iterator>);
static_assert(!std::indirectly_copyable<iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<iterator, const_iterator>);
static_assert( std::indirectly_copyable<iterator, reverse_iterator>);
static_assert( std::indirectly_copyable_storable<iterator, reverse_iterator>);
static_assert(!std::indirectly_copyable<iterator, const_reverse_iterator>);
static_assert(!std::indirectly_copyable_storable<iterator, const_reverse_iterator>);
static_assert( std::indirectly_swappable<iterator, iterator>);

static_assert(std::contiguous_iterator<const_iterator>);
Expand All @@ -58,4 +66,12 @@ static_assert( std::indirectly_movable<const_iterator, reverse_iterator>);
static_assert( std::indirectly_movable_storable<const_iterator, reverse_iterator>);
static_assert(!std::indirectly_movable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_movable_storable<const_iterator, const_reverse_iterator>);
static_assert( std::indirectly_copyable<const_iterator, iterator>);
static_assert( std::indirectly_copyable_storable<const_iterator, iterator>);
static_assert(!std::indirectly_copyable<const_iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<const_iterator, const_iterator>);
static_assert( std::indirectly_copyable<const_iterator, reverse_iterator>);
static_assert( std::indirectly_copyable_storable<const_iterator, reverse_iterator>);
static_assert(!std::indirectly_copyable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_copyable_storable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);
Expand Up @@ -40,6 +40,14 @@ static_assert( std::indirectly_movable<iterator, reverse_iterator>);
static_assert( std::indirectly_movable_storable<iterator, reverse_iterator>);
static_assert(!std::indirectly_movable<iterator, const_reverse_iterator>);
static_assert(!std::indirectly_movable_storable<iterator, const_reverse_iterator>);
static_assert( std::indirectly_copyable<iterator, iterator>);
static_assert( std::indirectly_copyable_storable<iterator, iterator>);
static_assert(!std::indirectly_copyable<iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<iterator, const_iterator>);
static_assert( std::indirectly_copyable<iterator, reverse_iterator>);
static_assert( std::indirectly_copyable_storable<iterator, reverse_iterator>);
static_assert(!std::indirectly_copyable<iterator, const_reverse_iterator>);
static_assert(!std::indirectly_copyable_storable<iterator, const_reverse_iterator>);
static_assert(std::indirectly_swappable<iterator, iterator>);

static_assert(std::random_access_iterator<const_iterator>);
Expand All @@ -61,4 +69,12 @@ static_assert( std::indirectly_movable<const_iterator, reverse_iterator>);
static_assert( std::indirectly_movable_storable<const_iterator, reverse_iterator>);
static_assert(!std::indirectly_movable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_movable_storable<const_iterator, const_reverse_iterator>);
static_assert( std::indirectly_copyable<const_iterator, iterator>);
static_assert( std::indirectly_copyable_storable<const_iterator, iterator>);
static_assert(!std::indirectly_copyable<const_iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<const_iterator, const_iterator>);
static_assert( std::indirectly_copyable<const_iterator, reverse_iterator>);
static_assert( std::indirectly_copyable_storable<const_iterator, reverse_iterator>);
static_assert(!std::indirectly_copyable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_copyable_storable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);
Expand Up @@ -30,6 +30,10 @@ static_assert( std::indirectly_movable<iterator, iterator>);
static_assert( std::indirectly_movable_storable<iterator, iterator>);
static_assert(!std::indirectly_movable<iterator, const_iterator>);
static_assert(!std::indirectly_movable_storable<iterator, const_iterator>);
static_assert( std::indirectly_copyable<iterator, iterator>);
static_assert( std::indirectly_copyable_storable<iterator, iterator>);
static_assert(!std::indirectly_copyable<iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<iterator, const_iterator>);
static_assert(std::indirectly_swappable<iterator, iterator>);

static_assert(std::forward_iterator<const_iterator>);
Expand All @@ -43,4 +47,8 @@ static_assert( std::indirectly_movable<const_iterator, iterator>);
static_assert( std::indirectly_movable_storable<const_iterator, iterator>);
static_assert(!std::indirectly_movable<const_iterator, const_iterator>);
static_assert(!std::indirectly_movable_storable<const_iterator, const_iterator>);
static_assert( std::indirectly_copyable<const_iterator, iterator>);
static_assert( std::indirectly_copyable_storable<const_iterator, iterator>);
static_assert(!std::indirectly_copyable<const_iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<const_iterator, const_iterator>);
static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);
Expand Up @@ -40,6 +40,14 @@ static_assert( std::indirectly_movable<iterator, reverse_iterator>);
static_assert( std::indirectly_movable_storable<iterator, reverse_iterator>);
static_assert(!std::indirectly_movable<iterator, const_reverse_iterator>);
static_assert(!std::indirectly_movable_storable<iterator, const_reverse_iterator>);
static_assert( std::indirectly_copyable<iterator, iterator>);
static_assert( std::indirectly_copyable_storable<iterator, iterator>);
static_assert(!std::indirectly_copyable<iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<iterator, const_iterator>);
static_assert( std::indirectly_copyable<iterator, reverse_iterator>);
static_assert( std::indirectly_copyable_storable<iterator, reverse_iterator>);
static_assert(!std::indirectly_copyable<iterator, const_reverse_iterator>);
static_assert(!std::indirectly_copyable_storable<iterator, const_reverse_iterator>);
static_assert(std::indirectly_swappable<iterator, iterator>);

static_assert(std::bidirectional_iterator<const_iterator>);
Expand All @@ -61,4 +69,12 @@ static_assert( std::indirectly_movable<const_iterator, reverse_iterator>);
static_assert( std::indirectly_movable_storable<const_iterator, reverse_iterator>);
static_assert(!std::indirectly_movable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_movable_storable<const_iterator, const_reverse_iterator>);
static_assert( std::indirectly_copyable<const_iterator, iterator>);
static_assert( std::indirectly_copyable_storable<const_iterator, iterator>);
static_assert(!std::indirectly_copyable<const_iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<const_iterator, const_iterator>);
static_assert( std::indirectly_copyable<const_iterator, reverse_iterator>);
static_assert( std::indirectly_copyable_storable<const_iterator, reverse_iterator>);
static_assert(!std::indirectly_copyable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_copyable_storable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);
Expand Up @@ -36,6 +36,8 @@ static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_reverse_iterator>);
static_assert(std::indirectly_movable<iterator, bool*>);
static_assert(std::indirectly_movable_storable<iterator, bool*>);
static_assert(std::indirectly_copyable<iterator, bool*>);
static_assert(std::indirectly_copyable_storable<iterator, bool*>);
static_assert(std::indirectly_swappable<iterator, iterator>);

static_assert( std::random_access_iterator<const_iterator>);
Expand Down
Expand Up @@ -41,6 +41,14 @@ static_assert( std::indirectly_movable<iterator, reverse_iterator>);
static_assert( std::indirectly_movable_storable<iterator, reverse_iterator>);
static_assert(!std::indirectly_movable<iterator, const_reverse_iterator>);
static_assert(!std::indirectly_movable_storable<iterator, const_reverse_iterator>);
static_assert( std::indirectly_copyable<iterator, iterator>);
static_assert( std::indirectly_copyable_storable<iterator, iterator>);
static_assert(!std::indirectly_copyable<iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<iterator, const_iterator>);
static_assert( std::indirectly_copyable<iterator, reverse_iterator>);
static_assert( std::indirectly_copyable_storable<iterator, reverse_iterator>);
static_assert(!std::indirectly_copyable<iterator, const_reverse_iterator>);
static_assert(!std::indirectly_copyable_storable<iterator, const_reverse_iterator>);
static_assert(std::indirectly_swappable<iterator, iterator>);

static_assert( std::contiguous_iterator<const_iterator>);
Expand All @@ -63,4 +71,12 @@ static_assert( std::indirectly_movable<const_iterator, reverse_iterator>);
static_assert( std::indirectly_movable_storable<const_iterator, reverse_iterator>);
static_assert(!std::indirectly_movable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_movable_storable<const_iterator, const_reverse_iterator>);
static_assert( std::indirectly_copyable<const_iterator, iterator>);
static_assert( std::indirectly_copyable_storable<const_iterator, iterator>);
static_assert(!std::indirectly_copyable<const_iterator, const_iterator>);
static_assert(!std::indirectly_copyable_storable<const_iterator, const_iterator>);
static_assert( std::indirectly_copyable<const_iterator, reverse_iterator>);
static_assert( std::indirectly_copyable_storable<const_iterator, reverse_iterator>);
static_assert(!std::indirectly_copyable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_copyable_storable<const_iterator, const_reverse_iterator>);
static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);
Expand Up @@ -32,6 +32,8 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(std::indirectly_movable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<iterator, std::pair<int, int>*>);
static_assert(std::indirectly_copyable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<iterator, iterator>);

static_assert(std::forward_iterator<const_iterator>);
Expand All @@ -43,6 +45,8 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(std::indirectly_movable<const_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<const_iterator, std::pair<int, int>*>);
static_assert(std::indirectly_copyable<const_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<const_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);

static_assert(std::forward_iterator<local_iterator>);
Expand All @@ -54,6 +58,8 @@ static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
static_assert(std::indirectly_movable<local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<local_iterator, std::pair<int, int>*>);
static_assert(std::indirectly_copyable<local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<local_iterator, local_iterator>);

static_assert(std::forward_iterator<const_local_iterator>);
Expand All @@ -65,4 +71,6 @@ static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
static_assert(std::indirectly_movable<const_local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<const_local_iterator, std::pair<int, int>*>);
static_assert(std::indirectly_copyable<const_local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<const_local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<const_local_iterator, const_local_iterator>);
Expand Up @@ -32,6 +32,8 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
static_assert(!std::sized_sentinel_for<iterator, const_iterator>);
static_assert(std::indirectly_movable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<iterator, std::pair<int, int>*>);
static_assert(std::indirectly_copyable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<iterator, iterator>);

static_assert(std::forward_iterator<const_iterator>);
Expand All @@ -43,6 +45,8 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
static_assert(std::indirectly_movable<const_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<const_iterator, std::pair<int, int>*>);
static_assert(std::indirectly_copyable<const_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<const_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);

static_assert(std::forward_iterator<local_iterator>);
Expand All @@ -54,6 +58,8 @@ static_assert(!std::sized_sentinel_for<local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<local_iterator, const_local_iterator>);
static_assert(std::indirectly_movable<local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<local_iterator, std::pair<int, int>*>);
static_assert(std::indirectly_copyable<local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<local_iterator, local_iterator>);

static_assert(std::forward_iterator<const_local_iterator>);
Expand All @@ -65,4 +71,6 @@ static_assert(!std::sized_sentinel_for<const_local_iterator, local_iterator>);
static_assert(!std::sized_sentinel_for<const_local_iterator, const_local_iterator>);
static_assert(std::indirectly_movable<const_local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_movable_storable<const_local_iterator, std::pair<int, int>*>);
static_assert(std::indirectly_copyable<const_local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_copyable_storable<const_local_iterator, std::pair<int, int>*>);
static_assert(!std::indirectly_swappable<const_local_iterator, const_local_iterator>);

0 comments on commit e65d376

Please sign in to comment.