second = __p.second;
return *this;
}
+
+ // Extension: This is provided in C++03 because it allows properly handling the
+ // assignment to a pair containing references, which would be a hard
+ // error otherwise.
+ template <class _U1, class _U2, class = __enable_if_t<
+ is_assignable<first_type&, _U1 const&>::value &&
+ is_assignable<second_type&, _U2 const&>::value
+ > >
+ _LIBCPP_HIDE_FROM_ABI
+ pair& operator=(pair<_U1, _U2> const& __p) {
+ first = __p.first;
+ second = __p.second;
+ return *this;
+ }
#else
struct _CheckArgs {
template <int&...>
struct Incomplete;
extern Incomplete inc_obj;
+struct ConstructibleFromInt {
+ ConstructibleFromInt() : value(-1) { }
+ explicit ConstructibleFromInt(int v) : value(v) { }
+ int value;
+};
+
int main(int, char**)
{
{
- // Test that we don't constrain the assignment operator in C++03 mode.
- // Since we don't have access control SFINAE having pair evaluate SFINAE
- // may cause a hard error.
- typedef std::pair<int, NonAssignable> P;
- static_assert(std::is_copy_assignable<P>::value, "");
+ // Test that we don't constrain the assignment operator in C++03 mode.
+ // Since we don't have access control SFINAE having pair evaluate SFINAE
+ // may cause a hard error.
+ typedef std::pair<int, NonAssignable> P;
+ static_assert(std::is_copy_assignable<P>::value, "");
+ }
+ {
+ typedef std::pair<int, Incomplete&> P;
+ static_assert(std::is_copy_assignable<P>::value, "");
+ P p(42, inc_obj);
+ assert(&p.second == &inc_obj);
}
{
- typedef std::pair<int, Incomplete&> P;
- static_assert(std::is_copy_assignable<P>::value, "");
- P p(42, inc_obj);
- assert(&p.second == &inc_obj);
+ // The type is constructible from int, but not assignable from int.
+ // This ensures that operator=(pair const&) can be used in conjunction with
+ // pair(pair<U, V> const&) to mimic operator=(pair<U, V> const&) in C++03.
+ // This is weird but valid in C++03.
+ std::pair<ConstructibleFromInt, char> p;
+ std::pair<int, char> from(11, 'x');
+ p = from;
+ assert(p.first.value == 11);
+ assert(p.second == 'x');
}
return 0;