81 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 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