1*8f1d8785SKonstantin Varlamov //===----------------------------------------------------------------------===//
2*8f1d8785SKonstantin Varlamov //
3*8f1d8785SKonstantin Varlamov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*8f1d8785SKonstantin Varlamov // See https://llvm.org/LICENSE.txt for license information.
5*8f1d8785SKonstantin Varlamov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*8f1d8785SKonstantin Varlamov //
7*8f1d8785SKonstantin Varlamov //===----------------------------------------------------------------------===//
8*8f1d8785SKonstantin Varlamov 
9*8f1d8785SKonstantin Varlamov // UNSUPPORTED: c++03, c++11, c++14, c++17
10*8f1d8785SKonstantin Varlamov 
11*8f1d8785SKonstantin Varlamov // template<class I>
12*8f1d8785SKonstantin Varlamov //   concept permutable = see below; // Since C++20
13*8f1d8785SKonstantin Varlamov 
14*8f1d8785SKonstantin Varlamov #include <iterator>
15*8f1d8785SKonstantin Varlamov 
16*8f1d8785SKonstantin Varlamov #include "test_iterators.h"
17*8f1d8785SKonstantin Varlamov 
18*8f1d8785SKonstantin Varlamov using AllConstraintsSatisfied = forward_iterator<int*>;
19*8f1d8785SKonstantin Varlamov static_assert( std::forward_iterator<AllConstraintsSatisfied>);
20*8f1d8785SKonstantin Varlamov static_assert( std::indirectly_movable_storable<AllConstraintsSatisfied, AllConstraintsSatisfied>);
21*8f1d8785SKonstantin Varlamov static_assert( std::indirectly_swappable<AllConstraintsSatisfied>);
22*8f1d8785SKonstantin Varlamov static_assert( std::permutable<AllConstraintsSatisfied>);
23*8f1d8785SKonstantin Varlamov 
24*8f1d8785SKonstantin Varlamov using NotAForwardIterator = cpp20_input_iterator<int*>;
25*8f1d8785SKonstantin Varlamov static_assert(!std::forward_iterator<NotAForwardIterator>);
26*8f1d8785SKonstantin Varlamov static_assert( std::indirectly_movable_storable<NotAForwardIterator, NotAForwardIterator>);
27*8f1d8785SKonstantin Varlamov static_assert( std::indirectly_swappable<NotAForwardIterator>);
28*8f1d8785SKonstantin Varlamov static_assert(!std::permutable<NotAForwardIterator>);
29*8f1d8785SKonstantin Varlamov 
30*8f1d8785SKonstantin Varlamov struct NonCopyable {
31*8f1d8785SKonstantin Varlamov   NonCopyable(const NonCopyable&) = delete;
32*8f1d8785SKonstantin Varlamov   NonCopyable& operator=(const NonCopyable&) = delete;
33*8f1d8785SKonstantin Varlamov   friend void swap(NonCopyable&, NonCopyable&);
34*8f1d8785SKonstantin Varlamov };
35*8f1d8785SKonstantin Varlamov using NotIMS = forward_iterator<NonCopyable*>;
36*8f1d8785SKonstantin Varlamov 
37*8f1d8785SKonstantin Varlamov static_assert( std::forward_iterator<NotIMS>);
38*8f1d8785SKonstantin Varlamov static_assert(!std::indirectly_movable_storable<NotIMS, NotIMS>);
39*8f1d8785SKonstantin Varlamov static_assert( std::indirectly_swappable<NotIMS>);
40*8f1d8785SKonstantin Varlamov static_assert(!std::permutable<NotIMS>);
41*8f1d8785SKonstantin Varlamov 
42*8f1d8785SKonstantin Varlamov // Note: it is impossible for an iterator to satisfy `indirectly_movable_storable` but not `indirectly_swappable`:
43*8f1d8785SKonstantin Varlamov // `indirectly_swappable` requires both iterators to be `indirectly_readable` and for `ranges::iter_swap` to be
44*8f1d8785SKonstantin Varlamov // well-formed for both iterators. `indirectly_movable_storable` also requires the iterator to be `indirectly_readable`.
45*8f1d8785SKonstantin Varlamov // `ranges::iter_swap` is always defined for `indirectly_movable_storable` iterators.
46