1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // template<class In, class Out>
12 // concept indirectly_copyable;
17 #include "test_macros.h"
22 CopyOnly(CopyOnly
const&) = default;
23 CopyOnly
& operator=(CopyOnly
const&) = default;
25 CopyOnly(CopyOnly
&&) = delete;
26 CopyOnly
& operator=(CopyOnly
&&) = delete;
29 // Can copy the underlying objects between pointers.
30 static_assert( std::indirectly_copyable
<int*, int*>);
31 static_assert( std::indirectly_copyable
<const int*, int *>);
33 // Can't copy if the output pointer is const.
34 static_assert(!std::indirectly_copyable
<int*, const int *>);
35 static_assert(!std::indirectly_copyable
<const int*, const int *>);
37 // Can copy from a pointer into an array but arrays aren't considered indirectly copyable-from.
38 static_assert( std::indirectly_copyable
<int*, int[2]>);
39 static_assert(!std::indirectly_copyable
<int[2], int*>);
40 static_assert(!std::indirectly_copyable
<int[2], int[2]>);
41 static_assert(!std::indirectly_copyable
<int(&)[2], int(&)[2]>);
43 // Can't copy between non-pointer types.
44 static_assert(!std::indirectly_copyable
<int*, int>);
45 static_assert(!std::indirectly_copyable
<int, int*>);
46 static_assert(!std::indirectly_copyable
<int, int>);
48 // Check some less common types.
49 static_assert(!std::indirectly_movable
<void*, void*>);
50 static_assert(!std::indirectly_movable
<int*, void*>);
51 static_assert(!std::indirectly_movable
<int(), int()>);
52 static_assert(!std::indirectly_movable
<int*, int()>);
53 static_assert(!std::indirectly_movable
<void, void>);
55 // Can't copy move-only objects.
56 static_assert(!std::indirectly_copyable
<MoveOnly
*, MoveOnly
*>);
57 static_assert(!std::indirectly_copyable
<MoveOnly
*, const MoveOnly
*>);
58 static_assert(!std::indirectly_copyable
<const MoveOnly
*, MoveOnly
*>);
59 static_assert(!std::indirectly_copyable
<const MoveOnly
*, const MoveOnly
*>);
61 // Can copy copy-only objects.
62 static_assert( std::indirectly_copyable
<CopyOnly
*, CopyOnly
*>);
63 static_assert(!std::indirectly_copyable
<CopyOnly
*, const CopyOnly
*>);
64 static_assert( std::indirectly_copyable
<const CopyOnly
*, CopyOnly
*>);
65 static_assert(!std::indirectly_copyable
<const CopyOnly
*, const CopyOnly
*>);
73 // Can copy through a dereferenceable class.
74 static_assert( std::indirectly_copyable
<int*, PointerTo
<int>>);
75 static_assert(!std::indirectly_copyable
<int*, PointerTo
<const int>>);
76 static_assert( std::indirectly_copyable
<PointerTo
<int>, PointerTo
<int>>);
77 static_assert(!std::indirectly_copyable
<PointerTo
<int>, PointerTo
<const int>>);
78 static_assert( std::indirectly_copyable
<CopyOnly
*, PointerTo
<CopyOnly
>>);
79 static_assert( std::indirectly_copyable
<PointerTo
<CopyOnly
>, CopyOnly
*>);
80 static_assert( std::indirectly_copyable
<PointerTo
<CopyOnly
>, PointerTo
<CopyOnly
>>);