<div dir="ltr">On Wed, Nov 6, 2013 at 11:29 AM, Howard Hinnant <span dir="ltr"><<a href="mailto:hhinnant@apple.com" target="_blank">hhinnant@apple.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><br>
On Nov 6, 2013, at 2:18 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
<br>
> On Wed, Nov 6, 2013 at 9:45 AM, Howard Hinnant <<a href="mailto:hhinnant@apple.com">hhinnant@apple.com</a>> wrote:<br>
> Author: hhinnant<br>
> Date: Wed Nov  6 11:45:43 2013<br>
> New Revision: 194154<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=194154&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=194154&view=rev</a><br>
> Log:<br>
> Fix several tuple bugs that were exposed by clang's implementation of CWG 1402.  This fixes <a href="http://llvm.org/bugs/show_bug.cgi?id=17798" target="_blank">http://llvm.org/bugs/show_bug.cgi?id=17798</a>.<br>

><br>
> Modified:<br>
>     libcxx/trunk/include/tuple<br>
><br>
> Modified: libcxx/trunk/include/tuple<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=194154&r1=194153&r2=194154&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=194154&r1=194153&r2=194154&view=diff</a><br>

> ==============================================================================<br>
> --- libcxx/trunk/include/tuple (original)<br>
> +++ libcxx/trunk/include/tuple Wed Nov  6 11:45:43 2013<br>
> @@ -270,7 +270,7 @@ public:<br>
>      _LIBCPP_INLINE_VISIBILITY<br>
>      _LIBCPP_CONSTEXPR_AFTER_CXX11<br>
>      __tuple_leaf(__tuple_leaf&& __t) _NOEXCEPT_(is_nothrow_move_constructible<_Hp>::value)<br>
> -        : value(_VSTD::move(__t.get()))<br>
> +        : value(_VSTD::forward<_Hp>(__t.get()))<br>
>          {}<br>
><br>
>      template <class _Tp><br>
> @@ -457,13 +457,24 @@ struct __tuple_impl<__tuple_indices<_Ind<br>
>              return *this;<br>
>          }<br>
><br>
> -        _LIBCPP_INLINE_VISIBILITY<br>
> -        __tuple_impl&<br>
> -        operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))<br>
> -        {<br>
> -            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);<br>
> -            return *this;<br>
> -        }<br>
> +    __tuple_impl(const __tuple_impl&) = default;<br>
> +    __tuple_impl(__tuple_impl&&) = default;<br>
> +<br>
> +    _LIBCPP_INLINE_VISIBILITY<br>
> +    __tuple_impl&<br>
> +    operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))<br>
> +    {<br>
> +        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);<br>
> +        return *this;<br>
> +    }<br>
> +<br>
> +    _LIBCPP_INLINE_VISIBILITY<br>
> +    __tuple_impl&<br>
> +    operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))<br>
> +    {<br>
> +        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);<br>
> +        return *this;<br>
> +    }<br>
><br>
> Hmm, could you give __tuple_leaf a copy / move assignment operator and default these too?<br>
<br>
</div></div>Perhaps.  I'm sure I explored that issue when I wrote this years ago.  But back then I did not have nice things like defaulted special functions.  And it is quite possible I would come to a different conclusion if I were to re-explore the design today.<br>

<br>
I did not do so today because of time constraints.<br>
<div class="im"><br>
> Also, is it intentional that the tuple elements are assigned in an indeterminate order?<br>
<br>
</div>That is certainly a disadvantage of the current design, though a conforming disadvantage.  Some implementations of tuple (not libc++) will even store the members in reverse order.</blockquote><div><br></div><div>FWIW, you can avoid this with a technique like:</div>
<div><br></div><div>struct __swallow {</div><div>  template<typename...Ts> __swallow(Ts &&) {}</div><div>};</div><div><br></div><div>and then use __swallow{...} instead of __swallow(...). (Braced initialization gives you guaranteed left-to-right ordering.)</div>
</div></div></div>