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 LHS, class RHS> 12 // concept assignable_from = 13 // std::is_lvalue_reference_v<LHS> && 14 // std::common_reference_with< 15 // const std::remove_reference_t<LHS>&, 16 // const std::remove_reference_t<RHS>&> && 17 // requires (LHS lhs, RHS&& rhs) { 18 // { lhs = std::forward<RHS>(rhs) } -> std::same_as<LHS>; 19 // }; 20 21 #include <concepts> 22 #include <type_traits> 23 24 #include "MoveOnly.h" 25 26 struct NoCommonRef { 27 NoCommonRef& operator=(const int&); 28 }; 29 static_assert(std::is_assignable_v<NoCommonRef&, const int&>); 30 static_assert(!std::assignable_from<NoCommonRef&, const int&>); // no common reference type 31 32 struct Base {}; 33 struct Derived : Base {}; 34 static_assert(!std::assignable_from<Base*, Derived*>); 35 static_assert( std::assignable_from<Base*&, Derived*>); 36 static_assert( std::assignable_from<Base*&, Derived*&>); 37 static_assert( std::assignable_from<Base*&, Derived*&&>); 38 static_assert( std::assignable_from<Base*&, Derived* const>); 39 static_assert( std::assignable_from<Base*&, Derived* const&>); 40 static_assert( std::assignable_from<Base*&, Derived* const&&>); 41 static_assert(!std::assignable_from<Base*&, const Derived*>); 42 static_assert(!std::assignable_from<Base*&, const Derived*&>); 43 static_assert(!std::assignable_from<Base*&, const Derived*&&>); 44 static_assert(!std::assignable_from<Base*&, const Derived* const>); 45 static_assert(!std::assignable_from<Base*&, const Derived* const&>); 46 static_assert(!std::assignable_from<Base*&, const Derived* const&&>); 47 static_assert( std::assignable_from<const Base*&, Derived*>); 48 static_assert( std::assignable_from<const Base*&, Derived*&>); 49 static_assert( std::assignable_from<const Base*&, Derived*&&>); 50 static_assert( std::assignable_from<const Base*&, Derived* const>); 51 static_assert( std::assignable_from<const Base*&, Derived* const&>); 52 static_assert( std::assignable_from<const Base*&, Derived* const&&>); 53 static_assert( std::assignable_from<const Base*&, const Derived*>); 54 static_assert( std::assignable_from<const Base*&, const Derived*&>); 55 static_assert( std::assignable_from<const Base*&, const Derived*&&>); 56 static_assert( std::assignable_from<const Base*&, const Derived* const>); 57 static_assert( std::assignable_from<const Base*&, const Derived* const&>); 58 static_assert( std::assignable_from<const Base*&, const Derived* const&&>); 59 60 struct VoidResultType { 61 void operator=(const VoidResultType&); 62 }; 63 static_assert(std::is_assignable_v<VoidResultType&, const VoidResultType&>); 64 static_assert(!std::assignable_from<VoidResultType&, const VoidResultType&>); 65 66 struct ValueResultType { 67 ValueResultType operator=(const ValueResultType&); 68 }; 69 static_assert(std::is_assignable_v<ValueResultType&, const ValueResultType&>); 70 static_assert(!std::assignable_from<ValueResultType&, const ValueResultType&>); 71 72 struct Locale { 73 const Locale& operator=(const Locale&); 74 }; 75 static_assert(std::is_assignable_v<Locale&, const Locale&>); 76 static_assert(!std::assignable_from<Locale&, const Locale&>); 77 78 struct Tuple { 79 Tuple& operator=(const Tuple&); 80 const Tuple& operator=(const Tuple&) const; 81 }; 82 static_assert(!std::assignable_from<Tuple, const Tuple&>); 83 static_assert( std::assignable_from<Tuple&, const Tuple&>); 84 static_assert(!std::assignable_from<Tuple&&, const Tuple&>); 85 static_assert(!std::assignable_from<const Tuple, const Tuple&>); 86 static_assert( std::assignable_from<const Tuple&, const Tuple&>); 87 static_assert(!std::assignable_from<const Tuple&&, const Tuple&>); 88 89 // Finally, check a few simple cases. 90 static_assert( std::assignable_from<int&, int>); 91 static_assert( std::assignable_from<int&, int&>); 92 static_assert( std::assignable_from<int&, int&&>); 93 static_assert(!std::assignable_from<const int&, int>); 94 static_assert(!std::assignable_from<const int&, int&>); 95 static_assert(!std::assignable_from<const int&, int&&>); 96 static_assert( std::assignable_from<volatile int&, int>); 97 static_assert( std::assignable_from<volatile int&, int&>); 98 static_assert( std::assignable_from<volatile int&, int&&>); 99 static_assert(!std::assignable_from<int(&)[10], int>); 100 static_assert(!std::assignable_from<int(&)[10], int(&)[10]>); 101 static_assert( std::assignable_from<MoveOnly&, MoveOnly>); 102 static_assert(!std::assignable_from<MoveOnly&, MoveOnly&>); 103 static_assert( std::assignable_from<MoveOnly&, MoveOnly&&>); 104 static_assert(!std::assignable_from<void, int>); 105 static_assert(!std::assignable_from<void, void>); 106