124dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===// 224dd2d2fSChristopher Di Bella // 324dd2d2fSChristopher Di Bella // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 424dd2d2fSChristopher Di Bella // See https://llvm.org/LICENSE.txt for license information. 524dd2d2fSChristopher Di Bella // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 624dd2d2fSChristopher Di Bella // 724dd2d2fSChristopher Di Bella //===----------------------------------------------------------------------===// 824dd2d2fSChristopher Di Bella 924dd2d2fSChristopher Di Bella // UNSUPPORTED: c++03, c++11, c++14, c++17 1024dd2d2fSChristopher Di Bella 11*d96a5042SArthur O'Dwyer // template<class LHS, class RHS> 12*d96a5042SArthur O'Dwyer // concept assignable_from = 13*d96a5042SArthur O'Dwyer // std::is_lvalue_reference_v<LHS> && 14*d96a5042SArthur O'Dwyer // std::common_reference_with< 15*d96a5042SArthur O'Dwyer // const std::remove_reference_t<LHS>&, 16*d96a5042SArthur O'Dwyer // const std::remove_reference_t<RHS>&> && 17*d96a5042SArthur O'Dwyer // requires (LHS lhs, RHS&& rhs) { 18*d96a5042SArthur O'Dwyer // { lhs = std::forward<RHS>(rhs) } -> std::same_as<LHS>; 19*d96a5042SArthur O'Dwyer // }; 2024dd2d2fSChristopher Di Bella 2124dd2d2fSChristopher Di Bella #include <concepts> 22*d96a5042SArthur O'Dwyer #include <type_traits> 2324dd2d2fSChristopher Di Bella 24*d96a5042SArthur O'Dwyer #include "MoveOnly.h" 2524dd2d2fSChristopher Di Bella 26*d96a5042SArthur O'Dwyer struct NoCommonRef { 27*d96a5042SArthur O'Dwyer NoCommonRef& operator=(const int&); 28*d96a5042SArthur O'Dwyer }; 29*d96a5042SArthur O'Dwyer static_assert(std::is_assignable_v<NoCommonRef&, const int&>); 30*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<NoCommonRef&, const int&>); // no common reference type 31e1ce3dabSLouis Dionne 32*d96a5042SArthur O'Dwyer struct Base {}; 33*d96a5042SArthur O'Dwyer struct Derived : Base {}; 34*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Base*, Derived*>); 35*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<Base*&, Derived*>); 36*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<Base*&, Derived*&>); 37*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<Base*&, Derived*&&>); 38*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<Base*&, Derived* const>); 39*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<Base*&, Derived* const&>); 40*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<Base*&, Derived* const&&>); 41*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Base*&, const Derived*>); 42*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Base*&, const Derived*&>); 43*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Base*&, const Derived*&&>); 44*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Base*&, const Derived* const>); 45*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Base*&, const Derived* const&>); 46*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Base*&, const Derived* const&&>); 47*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, Derived*>); 48*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, Derived*&>); 49*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, Derived*&&>); 50*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, Derived* const>); 51*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, Derived* const&>); 52*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, Derived* const&&>); 53*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, const Derived*>); 54*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, const Derived*&>); 55*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, const Derived*&&>); 56*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, const Derived* const>); 57*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, const Derived* const&>); 58*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Base*&, const Derived* const&&>); 5924dd2d2fSChristopher Di Bella 60*d96a5042SArthur O'Dwyer struct VoidResultType { 61*d96a5042SArthur O'Dwyer void operator=(const VoidResultType&); 62*d96a5042SArthur O'Dwyer }; 63*d96a5042SArthur O'Dwyer static_assert(std::is_assignable_v<VoidResultType&, const VoidResultType&>); 64*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<VoidResultType&, const VoidResultType&>); 6524dd2d2fSChristopher Di Bella 66*d96a5042SArthur O'Dwyer struct ValueResultType { 67*d96a5042SArthur O'Dwyer ValueResultType operator=(const ValueResultType&); 68*d96a5042SArthur O'Dwyer }; 69*d96a5042SArthur O'Dwyer static_assert(std::is_assignable_v<ValueResultType&, const ValueResultType&>); 70*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<ValueResultType&, const ValueResultType&>); 7124dd2d2fSChristopher Di Bella 72*d96a5042SArthur O'Dwyer struct Locale { 73*d96a5042SArthur O'Dwyer const Locale& operator=(const Locale&); 74*d96a5042SArthur O'Dwyer }; 75*d96a5042SArthur O'Dwyer static_assert(std::is_assignable_v<Locale&, const Locale&>); 76*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Locale&, const Locale&>); 7724dd2d2fSChristopher Di Bella 78*d96a5042SArthur O'Dwyer struct Tuple { 79*d96a5042SArthur O'Dwyer Tuple& operator=(const Tuple&); 80*d96a5042SArthur O'Dwyer const Tuple& operator=(const Tuple&) const; 81*d96a5042SArthur O'Dwyer }; 82*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Tuple, const Tuple&>); 83*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<Tuple&, const Tuple&>); 84*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<Tuple&&, const Tuple&>); 85*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<const Tuple, const Tuple&>); 86*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<const Tuple&, const Tuple&>); 87*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<const Tuple&&, const Tuple&>); 8824dd2d2fSChristopher Di Bella 89*d96a5042SArthur O'Dwyer // Finally, check a few simple cases. 90*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<int&, int>); 91*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<int&, int&>); 92*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<int&, int&&>); 93*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<const int&, int>); 94*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<const int&, int&>); 95*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<const int&, int&&>); 96*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<volatile int&, int>); 97*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<volatile int&, int&>); 98*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<volatile int&, int&&>); 99*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<int(&)[10], int>); 100*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<int(&)[10], int(&)[10]>); 101*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<MoveOnly&, MoveOnly>); 102*d96a5042SArthur O'Dwyer static_assert(!std::assignable_from<MoveOnly&, MoveOnly&>); 103*d96a5042SArthur O'Dwyer static_assert( std::assignable_from<MoveOnly&, MoveOnly&&>); 10424dd2d2fSChristopher Di Bella static_assert(!std::assignable_from<void, int>); 10524dd2d2fSChristopher Di Bella static_assert(!std::assignable_from<void, void>); 106