[libcxx-commits] [libcxx] edc1f0c - [libcxx][ranges] Implement indirectly_swappable.

via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jul 1 15:08:49 PDT 2021


Author: zoecarver
Date: 2021-07-01T15:08:23-07:00
New Revision: edc1f0c12c836abaeeab7b0d9f7e8fb73c233ae6

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

LOG: [libcxx][ranges] Implement indirectly_swappable.

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

Added: 
    libcxx/test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.compile.pass.cpp
    libcxx/test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.subsumption.compile.pass.cpp

Modified: 
    libcxx/docs/OneRangesProposalStatus.csv
    libcxx/include/__iterator/concepts.h
    libcxx/include/__iterator/iter_swap.h
    libcxx/include/iterator
    libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/utilities/memory/unique.ptr/iterator_concept_conformance.compile.pass.cpp
    libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/iterator_concept_conformance.compile.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/OneRangesProposalStatus.csv b/libcxx/docs/OneRangesProposalStatus.csv
index 0b6ca9ed127c7..0bfb00d441846 100644
--- a/libcxx/docs/OneRangesProposalStatus.csv
+++ b/libcxx/docs/OneRangesProposalStatus.csv
@@ -61,7 +61,7 @@ Section,Description,Dependencies,Assignee,Complete
 | indirectly_copyable
 | indirectly_copyable_storable",[iterator.concepts],Zoe Carver,In progress
 [common.alg.req]: pt. 2,indirectly_swappable,"| [iterator.concepts]
-| [iterator.cust.swap]",Louis Dionne,Not started
+| [iterator.cust.swap]",Zoe Carver,✅
 [common.alg.req]: pt. 3,indirectly_comparable,[projected],Louis Dionne,Not started
 [common.alg.req]: pt. 4,"| permutable
 | mergeable

diff  --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h
index e3664db14ae26..94e5f5d0a6cc4 100644
--- a/libcxx/include/__iterator/concepts.h
+++ b/libcxx/include/__iterator/concepts.h
@@ -249,6 +249,9 @@ 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>>;
 
+// Note: indirectly_swappable is located in iter_swap.h to prevent a dependency cycle
+// (both iter_swap and indirectly_swappable require indirectly_readable).
+
 // clang-format on
 
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)

diff  --git a/libcxx/include/__iterator/iter_swap.h b/libcxx/include/__iterator/iter_swap.h
index a529472e2a13d..17153728f0846 100644
--- a/libcxx/include/__iterator/iter_swap.h
+++ b/libcxx/include/__iterator/iter_swap.h
@@ -85,6 +85,16 @@ inline namespace __cpo {
 
 } // namespace ranges
 
+template<class _I1, class _I2 = _I1>
+concept indirectly_swappable =
+  indirectly_readable<_I1> && indirectly_readable<_I2> &&
+  requires(const _I1 __i1, const _I2 __i2) {
+    ranges::iter_swap(__i1, __i1);
+    ranges::iter_swap(__i2, __i2);
+    ranges::iter_swap(__i1, __i2);
+    ranges::iter_swap(__i2, __i1);
+  };
+
 #endif // !defined(_LIBCPP_HAS_NO_RANGES)
 
 _LIBCPP_END_NAMESPACE_STD

diff  --git a/libcxx/include/iterator b/libcxx/include/iterator
index b4e15c283d935..f6b0d2ae0a963 100644
--- a/libcxx/include/iterator
+++ b/libcxx/include/iterator
@@ -132,6 +132,10 @@ template<class In, class Out>
 template<class In, class Out>
   concept indirectly_movable_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
+
 template<class Category, class T, class Distance = ptr
diff _t,
          class Pointer = T*, class Reference = T&>
 struct iterator                                            // deprecated in C++17

diff  --git a/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
index 43fa91d8a451a..08be1b48725e7 100644
--- a/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/map/iterator_concept_conformance.compile.pass.cpp
@@ -35,6 +35,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
 static_assert(!std::random_access_iterator<const_iterator>);
@@ -47,3 +48,4 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
index 539d01e002ef0..d768e3152d287 100644
--- a/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/multimap/iterator_concept_conformance.compile.pass.cpp
@@ -35,6 +35,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
 static_assert(!std::random_access_iterator<const_iterator>);
@@ -47,3 +48,4 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
index 0b44c3ed40694..61a200cfb7a92 100644
--- a/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/multiset/iterator_concept_conformance.compile.pass.cpp
@@ -35,6 +35,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
 static_assert(!std::random_access_iterator<const_iterator>);
@@ -47,3 +48,4 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
index 76b42fef33943..5bcf23d10906e 100644
--- a/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/associative/set/iterator_concept_conformance.compile.pass.cpp
@@ -35,6 +35,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
 static_assert(!std::random_access_iterator<const_iterator>);
@@ -47,3 +48,4 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
index 29a0f3ade42a8..24c13d25d8eea 100644
--- a/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/array/iterator_concept_conformance.compile.pass.cpp
@@ -39,6 +39,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert(std::contiguous_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, int>);
@@ -58,3 +59,4 @@ 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_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
index 1b1bf60272f2e..c66b818c2862a 100644
--- a/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/deque/iterator_concept_conformance.compile.pass.cpp
@@ -41,6 +41,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert(std::random_access_iterator<const_iterator>);
 static_assert(!std::contiguous_iterator<const_iterator>);
@@ -61,3 +62,4 @@ 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_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
index 8caa26e1fde3f..bf4cc81a0cdfb 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.iter/iterator_concept_conformance.compile.pass.cpp
@@ -31,6 +31,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert(std::forward_iterator<const_iterator>);
 static_assert(!std::bidirectional_iterator<const_iterator>);
@@ -43,3 +44,4 @@ 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_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
index 2a4ffe57d9000..bf0553107a88c 100644
--- a/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/list/iterator_concept_conformance.compile.pass.cpp
@@ -41,6 +41,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert(std::bidirectional_iterator<const_iterator>);
 static_assert(!std::random_access_iterator<const_iterator>);
@@ -61,3 +62,4 @@ 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_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
index 037383af0308f..d051f7e36645a 100644
--- a/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector.bool/iterator_concept_conformance.compile.pass.cpp
@@ -37,6 +37,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert( std::random_access_iterator<const_iterator>);
 static_assert( std::random_access_iterator<const_reverse_iterator>);
@@ -51,3 +52,4 @@ static_assert( std::sized_sentinel_for<const_iterator, iterator>);
 static_assert( std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
index 3af726723176b..3280402a620cc 100644
--- a/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/sequences/vector/iterator_concept_conformance.compile.pass.cpp
@@ -42,6 +42,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert( std::contiguous_iterator<const_iterator>);
 static_assert( std::random_access_iterator<const_reverse_iterator>);
@@ -63,3 +64,4 @@ 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_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
index 7f8403029f2d9..b2bcabf1a7afb 100644
--- a/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.map/iterator_concept_conformance.compile.pass.cpp
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_local_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_swappable<iterator, iterator>);
 
 static_assert(std::forward_iterator<const_iterator>);
 static_assert(!std::bidirectional_iterator<const_iterator>);
@@ -47,6 +48,7 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);
 
 static_assert(std::forward_iterator<local_iterator>);
 static_assert(!std::bidirectional_iterator<local_iterator>);
@@ -61,6 +63,7 @@ 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_swappable<local_iterator, local_iterator>);
 
 static_assert(std::forward_iterator<const_local_iterator>);
 static_assert(!std::bidirectional_iterator<const_local_iterator>);
@@ -73,3 +76,4 @@ static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
 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_swappable<const_local_iterator, const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
index b5afdc11a2f7e..2223ce7a0ee76 100644
--- a/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multimap/iterator_concept_conformance.compile.pass.cpp
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_local_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_swappable<iterator, iterator>);
 
 static_assert(std::forward_iterator<const_iterator>);
 static_assert(!std::bidirectional_iterator<const_iterator>);
@@ -47,6 +48,7 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);
 
 static_assert(std::forward_iterator<local_iterator>);
 static_assert(!std::bidirectional_iterator<local_iterator>);
@@ -61,6 +63,7 @@ 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_swappable<local_iterator, local_iterator>);
 
 static_assert(std::forward_iterator<const_local_iterator>);
 static_assert(!std::bidirectional_iterator<const_local_iterator>);
@@ -73,3 +76,4 @@ static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
 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_swappable<const_local_iterator, const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
index eb318ca19e954..9063d604b059d 100644
--- a/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.multiset/iterator_concept_conformance.compile.pass.cpp
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
 static_assert(std::indirectly_movable<iterator, int*>);
 static_assert(std::indirectly_movable_storable<iterator, int*>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);
 
 static_assert(std::forward_iterator<const_iterator>);
 static_assert(!std::bidirectional_iterator<const_iterator>);
@@ -47,6 +48,7 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);
 
 static_assert(std::forward_iterator<local_iterator>);
 static_assert(!std::bidirectional_iterator<local_iterator>);
@@ -61,6 +63,7 @@ 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, int*>);
 static_assert(std::indirectly_movable_storable<local_iterator, int*>);
+static_assert(!std::indirectly_swappable<local_iterator, local_iterator>);
 
 static_assert(std::forward_iterator<const_local_iterator>);
 static_assert(!std::bidirectional_iterator<const_local_iterator>);
@@ -73,3 +76,4 @@ static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
 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_swappable<const_local_iterator, const_local_iterator>);

diff  --git a/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp
index db4d5c1159897..d77df390de576 100644
--- a/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/unord/unord.set/iterator_concept_conformance.compile.pass.cpp
@@ -35,6 +35,7 @@ static_assert(!std::sized_sentinel_for<iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<iterator, const_local_iterator>);
 static_assert(std::indirectly_movable<iterator, int*>);
 static_assert(std::indirectly_movable_storable<iterator, int*>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);
 
 static_assert(std::forward_iterator<const_iterator>);
 static_assert(!std::bidirectional_iterator<const_iterator>);
@@ -47,6 +48,7 @@ static_assert(!std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, local_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_local_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);
 
 static_assert(std::forward_iterator<local_iterator>);
 static_assert(!std::bidirectional_iterator<local_iterator>);
@@ -60,6 +62,7 @@ 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, int*>);
 static_assert(std::indirectly_movable_storable<local_iterator, int*>);
+static_assert(!std::indirectly_swappable<local_iterator, local_iterator>);
 
 static_assert(std::forward_iterator<const_local_iterator>);
 static_assert(!std::bidirectional_iterator<const_local_iterator>);
@@ -72,3 +75,4 @@ static_assert(!std::sized_sentinel_for<const_local_iterator, iterator>);
 static_assert(!std::sized_sentinel_for<const_local_iterator, const_iterator>);
 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_swappable<const_local_iterator, const_local_iterator>);

diff  --git a/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp
index bbbddcd211e33..a64f8a69c136b 100644
--- a/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/containers/views/span.iterators/iterator_concept_conformance.compile.pass.cpp
@@ -28,3 +28,4 @@ static_assert(std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, reverse_iterator>);
 static_assert(std::indirectly_movable<iterator, int*>);
 static_assert(std::indirectly_movable_storable<iterator, int*>);
+static_assert(std::indirectly_swappable<iterator, iterator>);

diff  --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp
index 1d3016ca9833b..ac168a08aab2a 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/iterator_concept_conformance.compile.pass.cpp
@@ -26,6 +26,7 @@ static_assert(std::sentinel_for<fs::directory_iterator, fs::directory_iterator>)
 static_assert(!std::sized_sentinel_for<fs::directory_iterator, fs::directory_iterator>);
 static_assert(!std::indirectly_movable<fs::directory_iterator, fs::directory_iterator>);
 static_assert(!std::indirectly_movable_storable<fs::directory_iterator, fs::directory_iterator>);
+static_assert(!std::indirectly_swappable<fs::directory_iterator, fs::directory_iterator>);
 
 static_assert(std::input_iterator<fs::recursive_directory_iterator>);
 static_assert(!std::forward_iterator<fs::recursive_directory_iterator>);
@@ -35,3 +36,4 @@ static_assert(std::sentinel_for<fs::recursive_directory_iterator, fs::recursive_
 static_assert(!std::sized_sentinel_for<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
 static_assert(!std::indirectly_movable<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
 static_assert(!std::indirectly_movable_storable<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);
+static_assert(!std::indirectly_swappable<fs::recursive_directory_iterator, fs::recursive_directory_iterator>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.compile.pass.cpp
new file mode 100644
index 0000000000000..d91d81e2fe888
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.compile.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: gcc-10
+
+// template<class I1, class I2>
+// concept indirectly_swappable;
+
+#include <iterator>
+
+#include "test_macros.h"
+
+template<class T, class ValueType = T>
+struct PointerTo {
+  using value_type = ValueType;
+  T& operator*() const;
+};
+
+static_assert(std::indirectly_swappable<PointerTo<int>>);
+static_assert(std::indirectly_swappable<PointerTo<int>, PointerTo<int>>);
+
+struct B;
+
+struct A {
+  friend void iter_swap(const PointerTo<A>&, const PointerTo<A>&);
+};
+
+// Is indirectly swappable.
+struct B {
+  friend void iter_swap(const PointerTo<B>&, const PointerTo<B>&);
+  friend void iter_swap(const PointerTo<A>&, const PointerTo<B>&);
+  friend void iter_swap(const PointerTo<B>&, const PointerTo<A>&);
+};
+
+// Valid except ranges::iter_swap(i2, i1).
+struct C {
+  friend void iter_swap(const PointerTo<C>&, const PointerTo<C>&);
+  friend void iter_swap(const PointerTo<A>&, const PointerTo<C>&);
+  friend void iter_swap(const PointerTo<C>&, const PointerTo<A>&) = delete;
+};
+
+// Valid except ranges::iter_swap(i1, i2).
+struct D {
+  friend void iter_swap(const PointerTo<D>&, const PointerTo<D>&);
+  friend void iter_swap(const PointerTo<A>&, const PointerTo<D>&) = delete;
+  friend void iter_swap(const PointerTo<D>&, const PointerTo<A>&);
+};
+
+// Valid except ranges::iter_swap(i2, i2).
+struct E {
+  E operator=(const E&) = delete;
+  friend void iter_swap(const PointerTo<E>&, const PointerTo<E>&) = delete;
+  friend void iter_swap(const PointerTo<A>&, const PointerTo<E>&);
+  friend void iter_swap(const PointerTo<E>&, const PointerTo<A>&);
+};
+
+struct F {
+  friend void iter_swap(const PointerTo<F>&, const PointerTo<F>&) = delete;
+};
+
+// Valid except ranges::iter_swap(i1, i1).
+struct G {
+  friend void iter_swap(const PointerTo<G>&, const PointerTo<G>&);
+  friend void iter_swap(const PointerTo<F>&, const PointerTo<G>&);
+  friend void iter_swap(const PointerTo<G>&, const PointerTo<F>&);
+};
+
+
+static_assert( std::indirectly_swappable<PointerTo<A>, PointerTo<B>>);
+static_assert(!std::indirectly_swappable<PointerTo<A>, PointerTo<C>>);
+static_assert(!std::indirectly_swappable<PointerTo<A>, PointerTo<D>>);
+static_assert(!std::indirectly_swappable<PointerTo<A>, PointerTo<E>>);
+static_assert(!std::indirectly_swappable<PointerTo<A>, PointerTo<G>>);

diff  --git a/libcxx/test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.subsumption.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.subsumption.compile.pass.cpp
new file mode 100644
index 0000000000000..adbc6fa26d517
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/alg.req.ind.swap/indirectly_swappable.subsumption.compile.pass.cpp
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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: gcc-10
+
+// template<class I1, class I2>
+// concept indirectly_swappable;
+
+#include <iterator>
+
+#include <concepts>
+
+template<class I1, class I2>
+  requires std::indirectly_readable<I1> && std::indirectly_readable<I2>
+constexpr bool indirectly_swappable_subsumption() {
+  return false;
+}
+
+template<class I1, class I2>
+  requires std::indirectly_swappable<I1, I2>
+constexpr bool indirectly_swappable_subsumption() {
+  return true;
+}
+
+static_assert(indirectly_swappable_subsumption<int*, int*>());

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp
index ea04ea8482b22..536f1df2249ae 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/back.insert.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -26,3 +26,4 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::input_iterator<iterator>);
 static_assert(std::indirectly_movable<int*, iterator>);
 static_assert(std::indirectly_movable_storable<int*, iterator>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp
index 13e8b0352baf9..ec488240c7e3c 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/front.insert.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -26,3 +26,4 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::input_iterator<iterator>);
 static_assert(std::indirectly_movable<int*, iterator>);
 static_assert(std::indirectly_movable_storable<int*, iterator>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp
index b73ca79491474..3f95ccd99a504 100644
--- a/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/insert.iterators/insert.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -25,3 +25,4 @@ static_assert(!std::sentinel_for<iterator, iterator>);
 static_assert(!std::input_iterator<iterator>);
 static_assert(std::indirectly_movable<int*, iterator>);
 static_assert(std::indirectly_movable_storable<int*, iterator>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp
index bd28036dc6de3..4f01334412b92 100644
--- a/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/move.iterators/move.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -16,7 +16,6 @@
 
 using iterator = std::move_iterator<int*>;
 
-
 static_assert(std::input_iterator<iterator>);
 static_assert(!std::forward_iterator<iterator>);
 static_assert(!std::indirectly_writable<iterator, int>);
@@ -25,3 +24,4 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::indirectly_movable<int*, iterator>);
 static_assert(!std::indirectly_movable_storable<int*, iterator>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
index 687d37db30cd8..25e208e27153a 100644
--- a/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/predef.iterators/reverse.iterators/iterator_concept_conformance.compile.pass.cpp
@@ -32,6 +32,7 @@ static_assert(!std::random_access_iterator<reverse_bidirectional_iterator>);
 static_assert(!std::sized_sentinel_for<reverse_bidirectional_iterator, reverse_bidirectional_iterator>);
 static_assert( std::indirectly_movable<reverse_bidirectional_iterator, reverse_bidirectional_iterator>);
 static_assert( std::indirectly_movable_storable<reverse_bidirectional_iterator, reverse_bidirectional_iterator>);
+static_assert( std::indirectly_swappable<reverse_bidirectional_iterator, reverse_bidirectional_iterator>);
 
 using reverse_random_access_iterator = std::reverse_iterator<random_access_iterator<int*>>;
 static_assert(common_reverse_iterator_checks<reverse_random_access_iterator>());
@@ -40,6 +41,7 @@ static_assert(!std::contiguous_iterator<reverse_random_access_iterator>);
 static_assert(std::sized_sentinel_for<reverse_random_access_iterator, reverse_random_access_iterator>);
 static_assert( std::indirectly_movable<reverse_random_access_iterator, reverse_random_access_iterator>);
 static_assert( std::indirectly_movable_storable<reverse_random_access_iterator, reverse_random_access_iterator>);
+static_assert( std::indirectly_swappable<reverse_random_access_iterator, reverse_random_access_iterator>);
 
 using reverse_contiguous_iterator = std::reverse_iterator<contiguous_iterator<int*>>;
 static_assert(common_reverse_iterator_checks<reverse_contiguous_iterator>());
@@ -48,3 +50,4 @@ static_assert(!std::contiguous_iterator<reverse_contiguous_iterator>);
 static_assert(std::sized_sentinel_for<reverse_contiguous_iterator, reverse_contiguous_iterator>);
 static_assert( std::indirectly_movable<reverse_contiguous_iterator, reverse_contiguous_iterator>);
 static_assert( std::indirectly_movable_storable<reverse_contiguous_iterator, reverse_contiguous_iterator>);
+static_assert( std::indirectly_swappable<reverse_contiguous_iterator, reverse_contiguous_iterator>);

diff  --git a/libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp
index 8bb5e94218f42..e4116cb67b2c0 100644
--- a/libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istream.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -26,3 +26,4 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(std::input_iterator<iterator>);
 static_assert(!std::indirectly_movable<int*, iterator>);
 static_assert(!std::indirectly_movable_storable<int*, iterator>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
index 2e529ca1fe2a1..cd4fe7690eb70 100644
--- a/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/istreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -27,3 +27,4 @@ static_assert(std::sentinel_for<iterator, iterator>);
 static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(std::indirectly_movable<iterator, char*>);
 static_assert(std::indirectly_movable_storable<iterator, char*>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp
index 068692e637742..9ce64a71a3bf2 100644
--- a/libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/ostream.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -26,3 +26,4 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::input_iterator<iterator>);
 static_assert(std::indirectly_movable<int*, iterator>);
 static_assert(std::indirectly_movable_storable<int*, iterator>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);

diff  --git a/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
index 2b2d0f9cbdd97..18c3608d77fe5 100644
--- a/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/iterators/stream.iterators/ostreambuf.iterator/iterator_concept_conformance.compile.pass.cpp
@@ -27,3 +27,4 @@ static_assert(!std::sized_sentinel_for<iterator, iterator>);
 static_assert(!std::input_iterator<iterator>);
 static_assert(std::indirectly_movable<char*, iterator>);
 static_assert(std::indirectly_movable_storable<char*, iterator>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);

diff  --git a/libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp
index 7818c475330c6..d13f770c241dd 100644
--- a/libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/re/re.iter/re.regiter/iterator_concept_conformance.compile.pass.cpp
@@ -23,3 +23,4 @@ static_assert(std::sentinel_for<std::cregex_iterator, std::cregex_iterator>);
 static_assert(!std::sized_sentinel_for<std::cregex_iterator, std::cregex_iterator>);
 static_assert(!std::indirectly_movable<std::cregex_iterator, std::cregex_iterator>);
 static_assert(!std::indirectly_movable_storable<std::cregex_iterator, std::cregex_iterator>);
+static_assert(!std::indirectly_swappable<std::cregex_iterator, std::cregex_iterator>);

diff  --git a/libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp
index b1ed97a9173b7..a5c40e54c1817 100644
--- a/libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/re/re.iter/re.tokiter/iterator_concept_conformance.compile.pass.cpp
@@ -23,3 +23,4 @@ static_assert(std::sentinel_for<std::cregex_token_iterator, std::cregex_token_it
 static_assert(!std::sized_sentinel_for<std::cregex_token_iterator, std::cregex_token_iterator>);
 static_assert(!std::indirectly_movable<std::cregex_token_iterator, std::cregex_token_iterator>);
 static_assert(!std::indirectly_movable_storable<std::cregex_token_iterator, std::cregex_token_iterator>);
+static_assert(!std::indirectly_swappable<std::cregex_token_iterator, std::cregex_token_iterator>);

diff  --git a/libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp
index 6efb5ae836b5b..98b0cec9c7662 100644
--- a/libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.iterators/iterator_concept_conformance.compile.pass.cpp
@@ -40,6 +40,7 @@ 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_swappable<iterator, iterator>);
 
 static_assert(std::contiguous_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, value_type>);
@@ -59,3 +60,4 @@ 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_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp
index fb12fa84491a1..0dfce8ea8b0c6 100644
--- a/libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/strings/string.view/string.view.iterators/iterator_concept_conformance.compile.pass.cpp
@@ -33,6 +33,7 @@ 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, char*>);
 static_assert(std::indirectly_movable_storable<iterator, char*>);
+static_assert(!std::indirectly_swappable<iterator, iterator>);
 
 static_assert(std::contiguous_iterator<const_iterator>);
 static_assert(!std::indirectly_writable<const_iterator, char>);
@@ -44,3 +45,4 @@ static_assert(std::sized_sentinel_for<const_iterator, iterator>);
 static_assert(std::sized_sentinel_for<const_iterator, const_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, reverse_iterator>);
 static_assert(!std::sized_sentinel_for<const_iterator, const_reverse_iterator>);
+static_assert(!std::indirectly_swappable<const_iterator, const_iterator>);

diff  --git a/libcxx/test/std/utilities/memory/unique.ptr/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/utilities/memory/unique.ptr/iterator_concept_conformance.compile.pass.cpp
index 68c06bb8168ff..9a64d0f414cbf 100644
--- a/libcxx/test/std/utilities/memory/unique.ptr/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/utilities/memory/unique.ptr/iterator_concept_conformance.compile.pass.cpp
@@ -21,6 +21,7 @@ static_assert(std::indirectly_writable<std::unique_ptr<int>, int>);
 static_assert(!std::weakly_incrementable<std::unique_ptr<int> >);
 static_assert(std::indirectly_movable<std::unique_ptr<int>, std::unique_ptr<int>>);
 static_assert(std::indirectly_movable_storable<std::unique_ptr<int>, std::unique_ptr<int>>);
+static_assert(std::indirectly_swappable<std::unique_ptr<int>, std::unique_ptr<int> >);
 
 static_assert(!std::indirectly_readable<std::unique_ptr<void> >);
 static_assert(!std::indirectly_writable<std::unique_ptr<void>, void>);

diff  --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/iterator_concept_conformance.compile.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/iterator_concept_conformance.compile.pass.cpp
index 4fe7710f85ba4..df8df75aa315a 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/iterator_concept_conformance.compile.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/iterator_concept_conformance.compile.pass.cpp
@@ -21,6 +21,7 @@ static_assert(std::indirectly_writable<std::shared_ptr<int>, int>);
 static_assert(!std::weakly_incrementable<std::shared_ptr<int> >);
 static_assert(std::indirectly_movable<std::shared_ptr<int>, std::shared_ptr<int>>);
 static_assert(std::indirectly_movable_storable<std::shared_ptr<int>, std::shared_ptr<int>>);
+static_assert(std::indirectly_swappable<std::shared_ptr<int>, std::shared_ptr<int> >);
 
 static_assert(!std::indirectly_readable<std::shared_ptr<void> >);
 static_assert(!std::indirectly_writable<std::shared_ptr<void>, void>);


        


More information about the libcxx-commits mailing list