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_copyable;
13
14#include <iterator>
15
16#include "MoveOnly.h"
17#include "test_macros.h"
18
19struct CopyOnly {
20 CopyOnly() = default;
21
22 CopyOnly(CopyOnly const&) = default;
23 CopyOnly& operator=(CopyOnly const&) = default;
24
25 CopyOnly(CopyOnly&&) = delete;
26 CopyOnly& operator=(CopyOnly&&) = delete;
27};
28
29// Can copy the underlying objects between pointers.
30static_assert( std::indirectly_copyable<int*, int*>);
31static_assert( std::indirectly_copyable<const int*, int *>);
32
33// Can't copy if the output pointer is const.
34static_assert(!std::indirectly_copyable<int*, const int *>);
35static_assert(!std::indirectly_copyable<const int*, const int *>);
36
37// Can copy from a pointer into an array but arrays aren't considered indirectly copyable-from.
38static_assert( std::indirectly_copyable<int*, int[2]>);
39static_assert(!std::indirectly_copyable<int[2], int*>);
40static_assert(!std::indirectly_copyable<int[2], int[2]>);
41static_assert(!std::indirectly_copyable<int(&)[2], int(&)[2]>);
42
43// Can't copy between non-pointer types.
44static_assert(!std::indirectly_copyable<int*, int>);
45static_assert(!std::indirectly_copyable<int, int*>);
46static_assert(!std::indirectly_copyable<int, int>);
47
48// Check some less common types.
49static_assert(!std::indirectly_movable<void*, void*>);
50static_assert(!std::indirectly_movable<int*, void*>);
51static_assert(!std::indirectly_movable<int(), int()>);
52static_assert(!std::indirectly_movable<int*, int()>);
53static_assert(!std::indirectly_movable<void, void>);
54
55// Can't copy move-only objects.
56static_assert(!std::indirectly_copyable<MoveOnly*, MoveOnly*>);
57static_assert(!std::indirectly_copyable<MoveOnly*, const MoveOnly*>);
58static_assert(!std::indirectly_copyable<const MoveOnly*, MoveOnly*>);
59static_assert(!std::indirectly_copyable<const MoveOnly*, const MoveOnly*>);
60
61// Can copy copy-only objects.
62static_assert( std::indirectly_copyable<CopyOnly*, CopyOnly*>);
63static_assert(!std::indirectly_copyable<CopyOnly*, const CopyOnly*>);
64static_assert( std::indirectly_copyable<const CopyOnly*, CopyOnly*>);
65static_assert(!std::indirectly_copyable<const CopyOnly*, const CopyOnly*>);
66
67template<class T>
68struct PointerTo {
69 using value_type = T;
70 T& operator*() const;
71};
72
73// Can copy through a dereferenceable class.
74static_assert( std::indirectly_copyable<int*, PointerTo<int>>);
75static_assert(!std::indirectly_copyable<int*, PointerTo<const int>>);
76static_assert( std::indirectly_copyable<PointerTo<int>, PointerTo<int>>);
77static_assert(!std::indirectly_copyable<PointerTo<int>, PointerTo<const int>>);
78static_assert( std::indirectly_copyable<CopyOnly*, PointerTo<CopyOnly>>);
79static_assert( std::indirectly_copyable<PointerTo<CopyOnly>, CopyOnly*>);
80static_assert( std::indirectly_copyable<PointerTo<CopyOnly>, PointerTo<CopyOnly>>);
81

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