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