@Hans While working on the std::tuple bug I found this bug in std::pair. Since we are already doing another RC I would like to merge this fix.
@Marshall Sound OK to you? On Sun, Aug 28, 2016 at 7:09 PM, Eric Fiselier via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: ericwf > Date: Sun Aug 28 20:09:47 2016 > New Revision: 279953 > > URL: http://llvm.org/viewvc/llvm-project?rev=279953&view=rev > Log: > Fix pair::operator=(TupleLike&&). > > This assignment operator was previously broken since the SFINAE always > resulted > in substitution failure. This caused assignments to turn into > copy construction + assignment. > > Added: > libcxx/trunk/test/std/utilities/utility/pairs/pairs. > pair/assign_tuple.pass.cpp > Modified: > libcxx/trunk/include/utility > > Modified: libcxx/trunk/include/utility > URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/ > utility?rev=279953&r1=279952&r2=279953&view=diff > ============================================================ > ================== > --- libcxx/trunk/include/utility (original) > +++ libcxx/trunk/include/utility Sun Aug 28 20:09:47 2016 > @@ -515,7 +515,7 @@ struct _LIBCPP_TYPE_VIS_ONLY pair > } > > template <class _Tuple, _EnableB< > - _CheckTLC<_Tuple>::template __enable_assign() > + _CheckTLC<_Tuple>::template __enable_assign<_Tuple>() > > = false> > _LIBCPP_INLINE_VISIBILITY > pair& operator=(_Tuple&& __p) { > > Added: libcxx/trunk/test/std/utilities/utility/pairs/pairs. > pair/assign_tuple.pass.cpp > URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/ > utilities/utility/pairs/pairs.pair/assign_tuple.pass.cpp? > rev=279953&view=auto > ============================================================ > ================== > --- > libcxx/trunk/test/std/utilities/utility/pairs/pairs.pair/assign_tuple.pass.cpp > (added) > +++ > libcxx/trunk/test/std/utilities/utility/pairs/pairs.pair/assign_tuple.pass.cpp > Sun Aug 28 20:09:47 2016 > @@ -0,0 +1,135 @@ > +//===------------------------------------------------------ > ----------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is dual licensed under the MIT and the University of > Illinois Open > +// Source Licenses. See LICENSE.TXT for details. > +// > +//===------------------------------------------------------ > ----------------===// > + > +// UNSUPPORTED: c++98, c++03 > + > +// <utility> > + > +// template <class T1, class T2> struct pair > + > +// template<class U, class V> pair& operator=(tuple<U, V>&& p); > + > +#include <utility> > +#include <tuple> > +#include <array> > +#include <memory> > +#include <cassert> > + > +struct CountingType { > + static int constructed; > + static int copy_constructed; > + static int move_constructed; > + static int assigned; > + static int copy_assigned; > + static int move_assigned; > + static void reset() { > + constructed = copy_constructed = move_constructed = 0; > + assigned = copy_assigned = move_assigned = 0; > + } > + CountingType() : value(0) { ++constructed; } > + CountingType(int v) : value(v) { ++constructed; } > + CountingType(CountingType const& o) : value(o.value) { ++constructed; > ++copy_constructed; } > + CountingType(CountingType&& o) : value(o.value) { ++constructed; > ++move_constructed; o.value = -1;} > + > + CountingType& operator=(CountingType const& o) { > + ++assigned; > + ++copy_assigned; > + value = o.value; > + return *this; > + } > + CountingType& operator=(CountingType&& o) { > + ++assigned; > + ++move_assigned; > + value = o.value; > + o.value = -1; > + return *this; > + } > + int value; > +}; > +int CountingType::constructed; > +int CountingType::copy_constructed; > +int CountingType::move_constructed; > +int CountingType::assigned; > +int CountingType::copy_assigned; > +int CountingType::move_assigned; > + > +int main() > +{ > + using C = CountingType; > + { > + using P = std::pair<int, C>; > + using T = std::tuple<int, C>; > + T t(42, C{42}); > + P p(101, C{101}); > + C::reset(); > + p = t; > + assert(C::constructed == 0); > + assert(C::assigned == 1); > + assert(C::copy_assigned == 1); > + assert(C::move_assigned == 0); > + assert(p.first == 42); > + assert(p.second.value == 42); > + } > + { > + using P = std::pair<int, C>; > + using T = std::tuple<int, C>; > + T t(42, -42); > + P p(101, 101); > + C::reset(); > + p = std::move(t); > + assert(C::constructed == 0); > + assert(C::assigned == 1); > + assert(C::copy_assigned == 0); > + assert(C::move_assigned == 1); > + assert(p.first == 42); > + assert(p.second.value == -42); > + } > + { > + using P = std::pair<C, C>; > + using T = std::array<C, 2>; > + T t = {42, -42}; > + P p{101, 101}; > + C::reset(); > + p = t; > + assert(C::constructed == 0); > + assert(C::assigned == 2); > + assert(C::copy_assigned == 2); > + assert(C::move_assigned == 0); > + assert(p.first.value == 42); > + assert(p.second.value == -42); > + } > + { > + using P = std::pair<C, C>; > + using T = std::array<C, 2>; > + T t = {42, -42}; > + P p{101, 101}; > + C::reset(); > + p = t; > + assert(C::constructed == 0); > + assert(C::assigned == 2); > + assert(C::copy_assigned == 2); > + assert(C::move_assigned == 0); > + assert(p.first.value == 42); > + assert(p.second.value == -42); > + } > + { > + using P = std::pair<C, C>; > + using T = std::array<C, 2>; > + T t = {42, -42}; > + P p{101, 101}; > + C::reset(); > + p = std::move(t); > + assert(C::constructed == 0); > + assert(C::assigned == 2); > + assert(C::copy_assigned == 0); > + assert(C::move_assigned == 2); > + assert(p.first.value == 42); > + assert(p.second.value == -42); > + } > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits