1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17
// template<class LHS, class RHS>
// concept assignable_from =
// std::is_lvalue_reference_v<LHS> &&
// std::common_reference_with<
// const std::remove_reference_t<LHS>&,
// const std::remove_reference_t<RHS>&> &&
// requires (LHS lhs, RHS&& rhs) {
// { lhs = std::forward<RHS>(rhs) } -> std::same_as<LHS>;
// };
#include <concepts>
#include <type_traits>
#include "MoveOnly.h"
struct NoCommonRef {
NoCommonRef& operator=(const int&);
};
static_assert(std::is_assignable_v<NoCommonRef&, const int&>);
static_assert(!std::assignable_from<NoCommonRef&, const int&>); // no common reference type
struct Base {};
struct Derived : Base {};
static_assert(!std::assignable_from<Base*, Derived*>);
static_assert( std::assignable_from<Base*&, Derived*>);
static_assert( std::assignable_from<Base*&, Derived*&>);
static_assert( std::assignable_from<Base*&, Derived*&&>);
static_assert( std::assignable_from<Base*&, Derived* const>);
static_assert( std::assignable_from<Base*&, Derived* const&>);
static_assert( std::assignable_from<Base*&, Derived* const&&>);
static_assert(!std::assignable_from<Base*&, const Derived*>);
static_assert(!std::assignable_from<Base*&, const Derived*&>);
static_assert(!std::assignable_from<Base*&, const Derived*&&>);
static_assert(!std::assignable_from<Base*&, const Derived* const>);
static_assert(!std::assignable_from<Base*&, const Derived* const&>);
static_assert(!std::assignable_from<Base*&, const Derived* const&&>);
static_assert( std::assignable_from<const Base*&, Derived*>);
static_assert( std::assignable_from<const Base*&, Derived*&>);
static_assert( std::assignable_from<const Base*&, Derived*&&>);
static_assert( std::assignable_from<const Base*&, Derived* const>);
static_assert( std::assignable_from<const Base*&, Derived* const&>);
static_assert( std::assignable_from<const Base*&, Derived* const&&>);
static_assert( std::assignable_from<const Base*&, const Derived*>);
static_assert( std::assignable_from<const Base*&, const Derived*&>);
static_assert( std::assignable_from<const Base*&, const Derived*&&>);
static_assert( std::assignable_from<const Base*&, const Derived* const>);
static_assert( std::assignable_from<const Base*&, const Derived* const&>);
static_assert( std::assignable_from<const Base*&, const Derived* const&&>);
struct VoidResultType {
void operator=(const VoidResultType&);
};
static_assert(std::is_assignable_v<VoidResultType&, const VoidResultType&>);
static_assert(!std::assignable_from<VoidResultType&, const VoidResultType&>);
struct ValueResultType {
ValueResultType operator=(const ValueResultType&);
};
static_assert(std::is_assignable_v<ValueResultType&, const ValueResultType&>);
static_assert(!std::assignable_from<ValueResultType&, const ValueResultType&>);
struct Locale {
const Locale& operator=(const Locale&);
};
static_assert(std::is_assignable_v<Locale&, const Locale&>);
static_assert(!std::assignable_from<Locale&, const Locale&>);
struct Tuple {
Tuple& operator=(const Tuple&);
const Tuple& operator=(const Tuple&) const;
};
static_assert(!std::assignable_from<Tuple, const Tuple&>);
static_assert( std::assignable_from<Tuple&, const Tuple&>);
static_assert(!std::assignable_from<Tuple&&, const Tuple&>);
static_assert(!std::assignable_from<const Tuple, const Tuple&>);
static_assert( std::assignable_from<const Tuple&, const Tuple&>);
static_assert(!std::assignable_from<const Tuple&&, const Tuple&>);
// Finally, check a few simple cases.
static_assert( std::assignable_from<int&, int>);
static_assert( std::assignable_from<int&, int&>);
static_assert( std::assignable_from<int&, int&&>);
static_assert(!std::assignable_from<const int&, int>);
static_assert(!std::assignable_from<const int&, int&>);
static_assert(!std::assignable_from<const int&, int&&>);
static_assert( std::assignable_from<volatile int&, int>);
static_assert( std::assignable_from<volatile int&, int&>);
static_assert( std::assignable_from<volatile int&, int&&>);
static_assert(!std::assignable_from<int(&)[10], int>);
static_assert(!std::assignable_from<int(&)[10], int(&)[10]>);
static_assert( std::assignable_from<MoveOnly&, MoveOnly>);
static_assert(!std::assignable_from<MoveOnly&, MoveOnly&>);
static_assert( std::assignable_from<MoveOnly&, MoveOnly&&>);
static_assert(!std::assignable_from<void, int>);
static_assert(!std::assignable_from<void, void>);
|