1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// UNSUPPORTED: c++03, c++11, c++14, c++17
10
11// template<class In, class Out>
12// concept indirectly_movable;
13
14#include <iterator>
15
16#include "MoveOnly.h"
17#include "test_macros.h"
18
19// Can move between pointers.
20static_assert( std::indirectly_movable<int*, int*>);
21static_assert( std::indirectly_movable<const int*, int*>);
22static_assert(!std::indirectly_movable<int*, const int*>);
23static_assert( std::indirectly_movable<const int*, int*>);
24
25// Can move from a pointer into an array but arrays aren't considered indirectly movable-from.
26static_assert( std::indirectly_movable<int*, int[2]>);
27static_assert(!std::indirectly_movable<int[2], int*>);
28static_assert(!std::indirectly_movable<int[2], int[2]>);
29static_assert(!std::indirectly_movable<int(&)[2], int(&)[2]>);
30
31// Can't move between non-pointer types.
32static_assert(!std::indirectly_movable<int*, int>);
33static_assert(!std::indirectly_movable<int, int*>);
34static_assert(!std::indirectly_movable<int, int>);
35
36// Check some less common types.
37static_assert(!std::indirectly_movable<void*, void*>);
38static_assert(!std::indirectly_movable<int*, void*>);
39static_assert(!std::indirectly_movable<int(), int()>);
40static_assert(!std::indirectly_movable<int*, int()>);
41static_assert(!std::indirectly_movable<void, void>);
42
43// Can move move-only objects.
44static_assert( std::indirectly_movable<MoveOnly*, MoveOnly*>);
45static_assert(!std::indirectly_movable<MoveOnly*, const MoveOnly*>);
46static_assert(!std::indirectly_movable<const MoveOnly*, const MoveOnly*>);
47static_assert(!std::indirectly_movable<const MoveOnly*, MoveOnly*>);
48
49template<class T>
50struct PointerTo {
51 using value_type = T;
52 T& operator*() const;
53};
54
55// Can copy through a dereferenceable class.
56static_assert( std::indirectly_movable<int*, PointerTo<int>>);
57static_assert(!std::indirectly_movable<int*, PointerTo<const int>>);
58static_assert( std::indirectly_copyable<PointerTo<int>, PointerTo<int>>);
59static_assert(!std::indirectly_copyable<PointerTo<int>, PointerTo<const int>>);
60static_assert( std::indirectly_movable<MoveOnly*, PointerTo<MoveOnly>>);
61static_assert( std::indirectly_movable<PointerTo<MoveOnly>, MoveOnly*>);
62static_assert( std::indirectly_movable<PointerTo<MoveOnly>, PointerTo<MoveOnly>>);
63

source code of libcxx/test/std/iterators/iterator.requirements/alg.req.ind.move/indirectly_movable.compile.pass.cpp