[libc++] Require the exact assignment expression to be trivial in __uninitialized_allocator_copy_impl (#196648)
Fixes https://github.com/llvm/llvm-project/issues/196645
`__uninitialized_allocator_copy_impl` has an optimization that replaces
`allocator_traits::construct` with `std::copy` for raw pointer ranges
when the element type is trivially copy constructible and trivially copy
assignable.
The copy-assignment trait only checks whether assignment from `const T&`
is trivial. That is weaker than the expression used by `std::copy`,
which evaluates `*out = *in`. If overload resolution selects a different
non-trivial assignment operator for that expression, `std::copy` can
call that operator on uninitialized storage.
Check `is_trivially_assignable<_Out&, _In&>` instead. This matches the
assignment expression used by `std::copy`, preserves the optimized path
when that assignment is actually trivial, and avoids making non-const
raw pointer callers select the generic `allocator_traits::construct`
overload due to a qualification conversion.
Add a vector copy-constructor regression test with a type whose
defaulted copy assignment is trivial but whose templated assignment
operator is selected for non-const lvalue sources.