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. 20 static_assert( std::indirectly_movable<int*, int*>); 21 static_assert( std::indirectly_movable<const int*, int*>); 22 static_assert(!std::indirectly_movable<int*, const int*>); 23 static_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. 26 static_assert( std::indirectly_movable<int*, int[2]>); 27 static_assert(!std::indirectly_movable<int[2], int*>); 28 static_assert(!std::indirectly_movable<int[2], int[2]>); 29 static_assert(!std::indirectly_movable<int(&)[2], int(&)[2]>); 30 31 // Can't move between non-pointer types. 32 static_assert(!std::indirectly_movable<int*, int>); 33 static_assert(!std::indirectly_movable<int, int*>); 34 static_assert(!std::indirectly_movable<int, int>); 35 36 // Check some less common types. 37 static_assert(!std::indirectly_movable<void*, void*>); 38 static_assert(!std::indirectly_movable<int*, void*>); 39 static_assert(!std::indirectly_movable<int(), int()>); 40 static_assert(!std::indirectly_movable<int*, int()>); 41 static_assert(!std::indirectly_movable<void, void>); 42 43 // Can move move-only objects. 44 static_assert( std::indirectly_movable<MoveOnly*, MoveOnly*>); 45 static_assert(!std::indirectly_movable<MoveOnly*, const MoveOnly*>); 46 static_assert(!std::indirectly_movable<const MoveOnly*, const MoveOnly*>); 47 static_assert(!std::indirectly_movable<const MoveOnly*, MoveOnly*>); 48 49 template<class T> 50 struct PointerTo { 51 using value_type = T; 52 T& operator*() const; 53 }; 54 55 // Can copy through a dereferenceable class. 56 static_assert( std::indirectly_movable<int*, PointerTo<int>>); 57 static_assert(!std::indirectly_movable<int*, PointerTo<const int>>); 58 static_assert( std::indirectly_copyable<PointerTo<int>, PointerTo<int>>); 59 static_assert(!std::indirectly_copyable<PointerTo<int>, PointerTo<const int>>); 60 static_assert( std::indirectly_movable<MoveOnly*, PointerTo<MoveOnly>>); 61 static_assert( std::indirectly_movable<PointerTo<MoveOnly>, MoveOnly*>); 62 static_assert( std::indirectly_movable<PointerTo<MoveOnly>, PointerTo<MoveOnly>>); 63