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