[libcxx] r279953 - Fix pair::operator=(TupleLike&&).

Eric Fiselier via cfe-commits cfe-commits at lists.llvm.org
Sun Aug 28 18:19:38 PDT 2016


@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 at 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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160828/3744dcdd/attachment-0001.html>


More information about the cfe-commits mailing list