//===----------------------------------------------------------------------===// // // 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 // UNSUPPORTED: libcpp-no-concepts // template // concept assignable_from; #include #include #include #include #include #include #include #include #include #include #include #ifndef _LIBCPP_HAS_NO_THREADS # include #endif #include "../support/allocators.h" // Note: is_lvalue_reference is checked in all ModelsAssignableFrom calls. template constexpr void NeverAssignableFrom() { static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); } template constexpr bool CheckAssignableFromRvalues() { NeverAssignableFrom(); constexpr bool Result = std::assignable_from; static_assert(std::assignable_from == Result); return Result; } template constexpr bool CheckAssignableFromLvalues() { NeverAssignableFrom(); constexpr bool Result = std::assignable_from; static_assert(std::assignable_from == Result); static_assert(std::assignable_from == Result); return Result; } template constexpr bool CheckAssignableFromLvaluesAndRvalues() { return CheckAssignableFromLvalues() && CheckAssignableFromRvalues(); } namespace BuiltinTypes { static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(!CheckAssignableFromLvaluesAndRvalues()); static_assert(!CheckAssignableFromLvaluesAndRvalues()); static_assert( !CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert( !CheckAssignableFromLvaluesAndRvalues()); static_assert( !CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert( !CheckAssignableFromLvaluesAndRvalues()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert(!CheckAssignableFromLvaluesAndRvalues()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert( !CheckAssignableFromLvaluesAndRvalues()); struct S {}; static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues< int (S::*)() const, int (S::*)() const noexcept>()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues< int (S::*)() volatile, int (S::*)() volatile noexcept>()); static_assert(CheckAssignableFromLvaluesAndRvalues< int (S::*)() const volatile, int (S::*)() const volatile>()); static_assert( CheckAssignableFromLvaluesAndRvalues< int (S::*)() const volatile, int (S::*)() const volatile noexcept>()); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); } // namespace BuiltinTypes namespace TypesFitForPurpose { struct T1 {}; struct NoCommonReference {}; static_assert(!std::common_reference_with); static_assert(!std::assignable_from); struct AssignmentReturnsNonReference { AssignmentReturnsNonReference operator=(T1); operator T1() const; }; static_assert(std::common_reference_with); static_assert(!std::assignable_from); struct NonCVAssignmentOnly { NonCVAssignmentOnly& operator=(T1); operator T1() const; }; static_assert( std::common_reference_with); static_assert(std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); struct NonCVAssignmentOnlyConstQualified { NonCVAssignmentOnlyConstQualified& operator=(T1) const; operator T1() const; }; static_assert(std::common_reference_with< const T1&, const NonCVAssignmentOnlyConstQualified&>); static_assert(std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from< const volatile NonCVAssignmentOnlyConstQualified&, T1>); struct NonCVAssignmentVolatileQualified { NonCVAssignmentVolatileQualified& operator=(T1) volatile; operator T1() const volatile; }; static_assert(std::common_reference_with< const T1&, const NonCVAssignmentVolatileQualified&>); static_assert(std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from< const volatile NonCVAssignmentVolatileQualified&, T1>); struct NonCVAssignmentOnlyCVQualified { NonCVAssignmentOnlyCVQualified& operator=(T1) const volatile; operator T1() const volatile; }; static_assert(std::common_reference_with< const T1&, const NonCVAssignmentOnlyCVQualified&>); static_assert(std::assignable_from); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); struct ConstAssignmentOnly { const ConstAssignmentOnly& operator=(T1) const; operator T1() const; }; static_assert( std::common_reference_with); static_assert(std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); struct VolatileAssignmentOnly { volatile VolatileAssignmentOnly& operator=(T1) volatile; operator T1() const volatile; }; static_assert( std::common_reference_with); static_assert(!std::assignable_from); static_assert(std::assignable_from); struct CVAssignmentOnly { const volatile CVAssignmentOnly& operator=(T1) const volatile; operator T1() const volatile; }; static_assert(std::common_reference_with); static_assert(std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); struct LvalueRefQualifiedWithRvalueT1Only { LvalueRefQualifiedWithRvalueT1Only& operator=(T1&&) &; const LvalueRefQualifiedWithRvalueT1Only& operator=(T1&&) const&; volatile LvalueRefQualifiedWithRvalueT1Only& operator=(T1&&) volatile&; const volatile LvalueRefQualifiedWithRvalueT1Only& operator=(T1&&) const volatile&; operator T1() const volatile; }; static_assert(std::common_reference_with< const T1&, const LvalueRefQualifiedWithRvalueT1Only&>); static_assert(std::assignable_from); static_assert( std::assignable_from); static_assert( std::assignable_from); static_assert(std::assignable_from< const volatile LvalueRefQualifiedWithRvalueT1Only&, T1&&>); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from< const volatile LvalueRefQualifiedWithRvalueT1Only&, T1&>); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from< volatile LvalueRefQualifiedWithRvalueT1Only&, const T1&>); static_assert(!std::assignable_from< const volatile LvalueRefQualifiedWithRvalueT1Only&, const T1&>); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from< volatile LvalueRefQualifiedWithRvalueT1Only&, volatile T1&>); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from< volatile LvalueRefQualifiedWithRvalueT1Only&, const T1&&>); static_assert(!std::assignable_from< const volatile LvalueRefQualifiedWithRvalueT1Only&, const T1&&>); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from< volatile LvalueRefQualifiedWithRvalueT1Only&, volatile T1&&>); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); struct NoLvalueRefAssignment { NoLvalueRefAssignment& operator=(T1) &&; const NoLvalueRefAssignment& operator=(T1) const&&; volatile NoLvalueRefAssignment& operator=(T1) volatile&&; const volatile NoLvalueRefAssignment& operator=(T1) const volatile&&; operator T1() const volatile; }; static_assert( std::common_reference_with); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from); static_assert( !std::assignable_from); static_assert( !std::assignable_from); static_assert(!std::assignable_from); } // namespace TypesFitForPurpose namespace StandardTypes { static_assert( CheckAssignableFromLvaluesAndRvalues, std::deque >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, std::deque >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::deque, std::deque > >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, std::vector >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, int>()); static_assert(CheckAssignableFromLvaluesAndRvalues, std::forward_list >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::forward_list, std::forward_list >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::forward_list, std::forward_list > >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, std::vector >()); static_assert( !CheckAssignableFromLvaluesAndRvalues, int>()); static_assert( CheckAssignableFromLvaluesAndRvalues, std::list >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, std::list >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::list, std::list > >()); static_assert( !CheckAssignableFromLvaluesAndRvalues, std::vector >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, int>()); static_assert(CheckAssignableFromLvaluesAndRvalues, std::map >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::map, std::map >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::map, std::map > > >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::map, std::unordered_map >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, std::pair >()); #ifndef _LIBCPP_HAS_NO_THREADS static_assert(!CheckAssignableFromRvalues()); static_assert(!CheckAssignableFromLvalues()); #endif static_assert(CheckAssignableFromLvaluesAndRvalues, int>()); static_assert( CheckAssignableFromLvaluesAndRvalues, double>()); static_assert(CheckAssignableFromLvaluesAndRvalues, std::optional >()); static_assert( !CheckAssignableFromLvaluesAndRvalues >()); static_assert( !CheckAssignableFromLvaluesAndRvalues >()); static_assert( !std::common_reference_with, std::optional >); static_assert( !CheckAssignableFromRvalues, std::optional >()); static_assert( !CheckAssignableFromLvalues, std::optional >()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::string, std::basic_string >()); static_assert( !CheckAssignableFromLvaluesAndRvalues >()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert(CheckAssignableFromLvaluesAndRvalues()); static_assert( CheckAssignableFromLvaluesAndRvalues()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::string_view, std::basic_string_view >()); static_assert( CheckAssignableFromRvalues, std::unique_ptr >()); static_assert( !CheckAssignableFromLvalues, std::unique_ptr >()); static_assert( CheckAssignableFromLvaluesAndRvalues, std::unordered_map >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::unordered_map, std::unordered_map >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::unordered_map, std::unordered_map > > >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::unordered_map, std::map >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::unordered_map, std::pair >()); static_assert(CheckAssignableFromLvaluesAndRvalues, std::vector >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, std::deque >()); static_assert(!CheckAssignableFromLvaluesAndRvalues< std::vector, std::vector > >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, std::deque >()); static_assert(!CheckAssignableFromLvaluesAndRvalues, int>()); } // namespace StandardTypes int main(int, char**) { return 0; }