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 // UNSUPPORTED: libcpp-no-concepts 11 12 // template<class In, class Out> 13 // concept indirectly_movable; 14 15 #include <iterator> 16 17 #include "MoveOnly.h" 18 #include "test_macros.h" 19 20 // Can move between pointers. 21 static_assert( std::indirectly_movable<int*, int*>); 22 static_assert( std::indirectly_movable<const int*, int*>); 23 static_assert(!std::indirectly_movable<int*, const int*>); 24 static_assert( std::indirectly_movable<const int*, int*>); 25 26 // Can move from a pointer into an array but arrays aren't considered indirectly movable-from. 27 static_assert( std::indirectly_movable<int*, int[2]>); 28 static_assert(!std::indirectly_movable<int[2], int*>); 29 static_assert(!std::indirectly_movable<int[2], int[2]>); 30 static_assert(!std::indirectly_movable<int(&)[2], int(&)[2]>); 31 32 // Can't move between non-pointer types. 33 static_assert(!std::indirectly_movable<int*, int>); 34 static_assert(!std::indirectly_movable<int, int*>); 35 static_assert(!std::indirectly_movable<int, int>); 36 37 // Check some less common types. 38 static_assert(!std::indirectly_movable<void*, void*>); 39 static_assert(!std::indirectly_movable<int*, void*>); 40 static_assert(!std::indirectly_movable<int(), int()>); 41 static_assert(!std::indirectly_movable<int*, int()>); 42 static_assert(!std::indirectly_movable<void, void>); 43 44 // Can move move-only objects. 45 static_assert( std::indirectly_movable<MoveOnly*, MoveOnly*>); 46 static_assert(!std::indirectly_movable<MoveOnly*, const MoveOnly*>); 47 static_assert(!std::indirectly_movable<const MoveOnly*, const MoveOnly*>); 48 static_assert(!std::indirectly_movable<const MoveOnly*, MoveOnly*>); 49 50 template<class T> 51 struct PointerTo { 52 using value_type = T; 53 T& operator*() const; 54 }; 55 56 // Can copy through a dereferenceable class. 57 static_assert( std::indirectly_movable<int*, PointerTo<int>>); 58 static_assert(!std::indirectly_movable<int*, PointerTo<const int>>); 59 static_assert( std::indirectly_copyable<PointerTo<int>, PointerTo<int>>); 60 static_assert(!std::indirectly_copyable<PointerTo<int>, PointerTo<const int>>); 61 static_assert( std::indirectly_movable<MoveOnly*, PointerTo<MoveOnly>>); 62 static_assert( std::indirectly_movable<PointerTo<MoveOnly>, MoveOnly*>); 63 static_assert( std::indirectly_movable<PointerTo<MoveOnly>, PointerTo<MoveOnly>>); 64