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

source code of libcxx/test/std/concepts/concepts.lang/concept.assignable/assignable_from.compile.pass.cpp