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