[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