[libcxx] r194154 - Fix several tuple bugs that were exposed by clang's implementation of CWG 1402. This fixes http://llvm.org/bugs/show_bug.cgi?id=17798.

Richard Smith richard at metafoo.co.uk
Wed Nov 6 11:50:31 PST 2013


On Wed, Nov 6, 2013 at 11:29 AM, Howard Hinnant <hhinnant at apple.com> wrote:

>
> On Nov 6, 2013, at 2:18 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> > On Wed, Nov 6, 2013 at 9:45 AM, Howard Hinnant <hhinnant at apple.com>
> wrote:
> > Author: hhinnant
> > Date: Wed Nov  6 11:45:43 2013
> > New Revision: 194154
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=194154&view=rev
> > Log:
> > Fix several tuple bugs that were exposed by clang's implementation of
> CWG 1402.  This fixes http://llvm.org/bugs/show_bug.cgi?id=17798.
> >
> > Modified:
> >     libcxx/trunk/include/tuple
> >
> > Modified: libcxx/trunk/include/tuple
> > URL:
> http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=194154&r1=194153&r2=194154&view=diff
> >
> ==============================================================================
> > --- libcxx/trunk/include/tuple (original)
> > +++ libcxx/trunk/include/tuple Wed Nov  6 11:45:43 2013
> > @@ -270,7 +270,7 @@ public:
> >      _LIBCPP_INLINE_VISIBILITY
> >      _LIBCPP_CONSTEXPR_AFTER_CXX11
> >      __tuple_leaf(__tuple_leaf&& __t)
> _NOEXCEPT_(is_nothrow_move_constructible<_Hp>::value)
> > -        : value(_VSTD::move(__t.get()))
> > +        : value(_VSTD::forward<_Hp>(__t.get()))
> >          {}
> >
> >      template <class _Tp>
> > @@ -457,13 +457,24 @@ struct __tuple_impl<__tuple_indices<_Ind
> >              return *this;
> >          }
> >
> > -        _LIBCPP_INLINE_VISIBILITY
> > -        __tuple_impl&
> > -        operator=(const __tuple_impl& __t)
> _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
> > -        {
> > -            __swallow(__tuple_leaf<_Indx,
> _Tp>::operator=(static_cast<const __tuple_leaf<_Indx,
> _Tp>&>(__t).get())...);
> > -            return *this;
> > -        }
> > +    __tuple_impl(const __tuple_impl&) = default;
> > +    __tuple_impl(__tuple_impl&&) = default;
> > +
> > +    _LIBCPP_INLINE_VISIBILITY
> > +    __tuple_impl&
> > +    operator=(const __tuple_impl& __t)
> _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
> > +    {
> > +        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const
> __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
> > +        return *this;
> > +    }
> > +
> > +    _LIBCPP_INLINE_VISIBILITY
> > +    __tuple_impl&
> > +    operator=(__tuple_impl&& __t)
> _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
> > +    {
> > +        __swallow(__tuple_leaf<_Indx,
> _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx,
> _Tp>&>(__t).get()))...);
> > +        return *this;
> > +    }
> >
> > Hmm, could you give __tuple_leaf a copy / move assignment operator and
> default these too?
>
> 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.
>
> I did not do so today because of time constraints.
>
> > Also, is it intentional that the tuple elements are assigned in an
> indeterminate order?
>
> 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.


FWIW, you can avoid this with a technique like:

struct __swallow {
  template<typename...Ts> __swallow(Ts &&) {}
};

and then use __swallow{...} instead of __swallow(...). (Braced
initialization gives you guaranteed left-to-right ordering.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131106/25989689/attachment.html>


More information about the cfe-commits mailing list