template<typename T, bool B> struct trivially_assignable_check {
static_assert(B == __has_trivial_assign(T), "");
static_assert(B == __is_trivially_assignable(T&, T), "");
static_assert(B == __is_trivially_assignable(T&, const T &), "");
static_assert(B == __is_trivially_assignable(T&, T &&), "");
static_assert(B == __is_trivially_assignable(T&&, T), "");
static_assert(B == __is_trivially_assignable(T&&, const T &), "");
static_assert(B == __is_trivially_assignable(T&&, T &&), "");
typedef void type;
};
template<typename T> using trivially_assignable =
typename trivially_assignable_check<T, true>::type;
template<typename T> using not_trivially_assignable =
typename trivially_assignable_check<T, false>::type;
struct Trivial {};
using _ = trivially_assignable<Trivial>;
struct UserProvided {
UserProvided &operator=(const UserProvided &);
};
using _ = not_trivially_assignable<UserProvided>;
struct NonConstCopy {
NonConstCopy &operator=(NonConstCopy &) = default;
};
#if defined(CLANG_ABI_COMPAT) && CLANG_ABI_COMPAT <= 14
using _ = not_trivially_assignable<NonConstCopy>;
#else
static_assert(__has_trivial_assign(NonConstCopy), "");
static_assert(__is_trivially_assignable(NonConstCopy &, NonConstCopy &), "");
static_assert(!__is_trivially_assignable(NonConstCopy &, const NonConstCopy &), "");
static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy), "");
static_assert(!__is_trivially_assignable(NonConstCopy &, NonConstCopy &&), "");
static_assert(__is_trivially_assignable(NonConstCopy &&, NonConstCopy &), "");
static_assert(!__is_trivially_assignable(NonConstCopy &&, const NonConstCopy &), "");
static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy), "");
static_assert(!__is_trivially_assignable(NonConstCopy &&, NonConstCopy &&), "");
struct DefaultedSpecialMembers {
DefaultedSpecialMembers &operator=(const DefaultedSpecialMembers &) = default;
DefaultedSpecialMembers &operator=(DefaultedSpecialMembers &) = default;
DefaultedSpecialMembers &operator=(DefaultedSpecialMembers &&) = default;
};
using _ = trivially_assignable<DefaultedSpecialMembers>;
#endif
struct VFn {
virtual void f();
};
using _ = not_trivially_assignable<VFn>;
struct VBase : virtual Trivial {};
using _ = not_trivially_assignable<VBase>;
struct TemplateCtor {
template<typename T> TemplateCtor operator=(T &);
};
using _ = trivially_assignable<TemplateCtor>;
struct TemplateCtorMember {
TemplateCtor tc;
};
using _ = trivially_assignable<TemplateCtorMember>;
struct MutableTemplateCtorMember {
mutable TemplateCtor mtc;
};
static_assert(!__is_trivially_assignable(MutableTemplateCtorMember, const MutableTemplateCtorMember &), "");
static_assert(__is_trivially_assignable(MutableTemplateCtorMember, MutableTemplateCtorMember &&), "");
struct TNT {
TNT &operator=(const TNT &) = default; TNT &operator=(TNT &);
TNT &operator=(TNT &&) = default; TNT &operator=(const TNT &&); };
static_assert(!__has_trivial_assign(TNT), "lie deliberately for gcc compatibility");
static_assert(__is_trivially_assignable(TNT, TNT), "");
static_assert(!__is_trivially_assignable(TNT, TNT &), "");
static_assert(__is_trivially_assignable(TNT, const TNT &), "");
static_assert(!__is_trivially_assignable(TNT, volatile TNT &), "");
static_assert(__is_trivially_assignable(TNT, TNT &&), "");
static_assert(!__is_trivially_assignable(TNT, const TNT &&), "");
static_assert(!__is_trivially_assignable(TNT, volatile TNT &&), "");
struct DerivedFromTNT : TNT {};
static_assert(__has_trivial_assign(DerivedFromTNT), "");
static_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT), "");
static_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT &), "");
static_assert(__is_trivially_assignable(DerivedFromTNT, const DerivedFromTNT &), "");
static_assert(!__is_trivially_assignable(DerivedFromTNT, volatile DerivedFromTNT &), "");
static_assert(__is_trivially_assignable(DerivedFromTNT, DerivedFromTNT &&), "");
static_assert(__is_trivially_assignable(DerivedFromTNT, const DerivedFromTNT &&), "");
static_assert(!__is_trivially_assignable(DerivedFromTNT, volatile DerivedFromTNT &&), "");
struct TNTMember {
TNT tnt;
};
static_assert(__has_trivial_assign(TNTMember), "");
static_assert(__is_trivially_assignable(TNTMember, TNTMember), "");
static_assert(__is_trivially_assignable(TNTMember, TNTMember &), "");
static_assert(__is_trivially_assignable(TNTMember, const TNTMember &), "");
static_assert(!__is_trivially_assignable(TNTMember, volatile TNTMember &), "");
static_assert(__is_trivially_assignable(TNTMember, TNTMember &&), "");
static_assert(__is_trivially_assignable(TNTMember, const TNTMember &&), "");
static_assert(!__is_trivially_assignable(TNTMember, volatile TNTMember &&), "");
struct NCCTNT : NonConstCopy, TNT {};
static_assert(!__has_trivial_assign(NCCTNT), "");
static_assert(!__is_trivially_assignable(NCCTNT, NCCTNT), "");
static_assert(!__is_trivially_assignable(NCCTNT, NCCTNT &), "");
static_assert(!__is_trivially_assignable(NCCTNT, const NCCTNT &), "");
static_assert(!__is_trivially_assignable(NCCTNT, volatile NCCTNT &), "");
static_assert(!__is_trivially_assignable(NCCTNT, NCCTNT &&), "");
static_assert(!__is_trivially_assignable(NCCTNT, const NCCTNT &&), "");
static_assert(!__is_trivially_assignable(NCCTNT, volatile NCCTNT &&), "");
struct MultipleTrivial {
MultipleTrivial &operator=(const MultipleTrivial &) & = default;
MultipleTrivial &operator=(const MultipleTrivial &) && = default;
MultipleTrivial &operator=(MultipleTrivial &&) & = default;
MultipleTrivial &operator=(MultipleTrivial &&) && = default;
};
using _ = trivially_assignable<MultipleTrivial>;
struct RefQualifier {
RefQualifier &operator=(const RefQualifier &) & = default;
RefQualifier &operator=(const RefQualifier &) &&;
RefQualifier &operator=(RefQualifier &&) &;
RefQualifier &operator=(RefQualifier &&) && = default;
};
struct DerivedFromRefQualifier : RefQualifier {
DerivedFromRefQualifier &operator=(const DerivedFromRefQualifier &) & = default;
DerivedFromRefQualifier &operator=(const DerivedFromRefQualifier &) && = default;
DerivedFromRefQualifier &operator=(DerivedFromRefQualifier &&) & = default;
DerivedFromRefQualifier &operator=(DerivedFromRefQualifier &&) && = default;
};
static_assert(__is_trivially_assignable(DerivedFromRefQualifier&, const DerivedFromRefQualifier&), "");
static_assert(__is_trivially_assignable(DerivedFromRefQualifier&&, const DerivedFromRefQualifier&), "");
static_assert(!__is_trivially_assignable(DerivedFromRefQualifier&, DerivedFromRefQualifier&&), "");
static_assert(!__is_trivially_assignable(DerivedFromRefQualifier&&, DerivedFromRefQualifier&&), "");
struct TemplateAssignNoMove {
TemplateAssignNoMove &operator=(const TemplateAssignNoMove &) = default;
template<typename T> TemplateAssignNoMove &operator=(T &&);
};
static_assert(__is_trivially_assignable(TemplateAssignNoMove, const TemplateAssignNoMove &), "");
static_assert(!__is_trivially_assignable(TemplateAssignNoMove, TemplateAssignNoMove &&), "");
struct UseTemplateAssignNoMove {
TemplateAssignNoMove tanm;
};
static_assert(__is_trivially_assignable(UseTemplateAssignNoMove, const UseTemplateAssignNoMove &), "");
static_assert(!__is_trivially_assignable(UseTemplateAssignNoMove, UseTemplateAssignNoMove &&), "");
struct TemplateAssignNoMoveSFINAE {
TemplateAssignNoMoveSFINAE &operator=(const TemplateAssignNoMoveSFINAE &) = default;
template<typename T, typename U = typename T::error> TemplateAssignNoMoveSFINAE &operator=(T &&);
};
static_assert(__is_trivially_assignable(TemplateAssignNoMoveSFINAE, const TemplateAssignNoMoveSFINAE &), "");
static_assert(__is_trivially_assignable(TemplateAssignNoMoveSFINAE, TemplateAssignNoMoveSFINAE &&), "");
struct UseTemplateAssignNoMoveSFINAE {
TemplateAssignNoMoveSFINAE tanm;
};
static_assert(__is_trivially_assignable(UseTemplateAssignNoMoveSFINAE, const UseTemplateAssignNoMoveSFINAE &), "");
static_assert(__is_trivially_assignable(UseTemplateAssignNoMoveSFINAE, UseTemplateAssignNoMoveSFINAE &&), "");
namespace TrivialityDependsOnImplicitDeletion {
struct PrivateMove {
PrivateMove &operator=(const PrivateMove &) = default;
private:
PrivateMove &operator=(PrivateMove &&);
friend class Access;
};
static_assert(__is_trivially_assignable(PrivateMove, const PrivateMove &), "");
static_assert(!__is_trivially_assignable(PrivateMove, PrivateMove &&), "");
struct NoAccess {
PrivateMove pm;
};
static_assert(__is_trivially_assignable(NoAccess, const NoAccess &), "");
static_assert(__is_trivially_assignable(NoAccess, NoAccess &&), "");
struct TopNoAccess : NoAccess {};
static_assert(__is_trivially_assignable(TopNoAccess, const TopNoAccess &), "");
static_assert(__is_trivially_assignable(TopNoAccess, TopNoAccess &&), "");
struct Access {
PrivateMove pm;
};
static_assert(__is_trivially_assignable(Access, const Access &), "");
static_assert(!__is_trivially_assignable(Access, Access &&), "");
struct TopAccess : Access {};
static_assert(__is_trivially_assignable(TopAccess, const TopAccess &), "");
static_assert(!__is_trivially_assignable(TopAccess, TopAccess &&), "");
}