<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jul 29, 2015 at 12:50 PM, Duncan P. N. Exon Smith <span dir="ltr"><<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.com</a>></span> wrote:<br><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 2015-Jul-29, at 09:25, Marshall Clow <<a href="mailto:mclow.lists@gmail.com">mclow.lists@gmail.com</a>> wrote:<br>
><br>
> Author: marshall<br>
> Date: Wed Jul 29 11:25:45 2015<br>
> New Revision: 243530<br>
><br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D243530-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=YvbFjhjoEqf5EHNo89Qif9TFUIEgp8yA4VPf3EipuHQ&s=0-1VxA5VhnfZPkbdZfl4vGwrmyIwBW8S5QGz2dsSZfE&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=243530&view=rev</a><br>
> Log:<br>
> Fix a self-move bug in inplace_merge. Thanks to Ted and Dexon for the report and the suggested fix.<br>
><br>
> Modified:<br>
>    libcxx/trunk/include/algorithm<br>
>    libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp<br>
>    libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp<br>
><br>
> Modified: libcxx/trunk/include/algorithm<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_libcxx_trunk_include_algorithm-3Frev-3D243530-26r1-3D243529-26r2-3D243530-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=YvbFjhjoEqf5EHNo89Qif9TFUIEgp8yA4VPf3EipuHQ&s=PFNXdBwhwuxqo22InFIctHQ_r7w2LilM_8fg-hqJu-0&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/algorithm?rev=243530&r1=243529&r2=243530&view=diff</a><br>
> ==============================================================================<br>
> --- libcxx/trunk/include/algorithm (original)<br>
> +++ libcxx/trunk/include/algorithm Wed Jul 29 11:25:45 2015<br>
> @@ -4361,6 +4361,34 @@ merge(_InputIterator1 __first1, _InputIt<br>
><br>
> // inplace_merge<br>
><br>
> +template <class _Compare, class _InputIterator1, class _InputIterator2,<br>
> +          class _OutputIterator><br>
> +void __half_inplace_merge(_InputIterator1 __first1, _InputIterator1 __last1,<br>
> +                          _InputIterator2 __first2, _InputIterator2 __last2,<br>
> +                          _OutputIterator __result, _Compare __comp)<br>
> +{<br>
> +    for (; __first1 != __last1; ++__result)<br>
> +    {<br>
> +        if (__first2 == __last2)<br>
> +        {<br>
> +            _VSTD::move(__first1, __last1, __result);<br>
> +            return;<br>
> +        }<br>
> +<br>
> +        if (__comp(*__first2, *__first1))<br>
> +        {<br>
> +            *__result = _VSTD::move(*__first2);<br>
> +            ++__first2;<br>
> +        }<br>
> +        else<br>
> +        {<br>
> +            *__result = _VSTD::move(*__first1);<br>
> +            ++__first1;<br>
> +        }<br>
> +    }<br>
> +    // __first2 through __last2 are already in the right spot.<br>
> +}<br>
> +<br>
> template <class _Compare, class _BidirectionalIterator><br>
> void<br>
> __buffered_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,<br>
> @@ -4376,11 +4404,7 @@ __buffered_inplace_merge(_BidirectionalI<br>
>         value_type* __p = __buff;<br>
>         for (_BidirectionalIterator __i = __first; __i != __middle; __d.__incr((value_type*)0), (void) ++__i, ++__p)<br>
>             ::new(__p) value_type(_VSTD::move(*__i));<br>
> -        __merge<_Compare>(move_iterator<value_type*>(__buff),<br>
> -                          move_iterator<value_type*>(__p),<br>
> -                          move_iterator<_BidirectionalIterator>(__middle),<br>
> -                          move_iterator<_BidirectionalIterator>(__last),<br>
> -                          __first, __comp);<br>
> +        __half_inplace_merge(__buff, __p, __middle, __last, __first, __comp);<br>
>     }<br>
>     else<br>
>     {<br>
> @@ -4389,9 +4413,9 @@ __buffered_inplace_merge(_BidirectionalI<br>
>             ::new(__p) value_type(_VSTD::move(*__i));<br>
>         typedef reverse_iterator<_BidirectionalIterator> _RBi;<br>
>         typedef reverse_iterator<value_type*> _Rv;<br>
> -        __merge(move_iterator<_RBi>(_RBi(__middle)), move_iterator<_RBi>(_RBi(__first)),<br>
> -                move_iterator<_Rv>(_Rv(__p)), move_iterator<_Rv>(_Rv(__buff)),<br>
> -                _RBi(__last), __negate<_Compare>(__comp));<br>
> +        __half_inplace_merge(_Rv(__p), _Rv(__buff),<br>
> +                             _RBi(__middle), _RBi(__first),<br>
> +                             _RBi(__last), __negate<_Compare>(__comp));<br>
>     }<br>
> }<br>
><br>
><br>
> Modified: libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_libcxx_trunk_test_std_algorithms_alg.sorting_alg.merge_inplace-5Fmerge.pass.cpp-3Frev-3D243530-26r1-3D243529-26r2-3D243530-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=YvbFjhjoEqf5EHNo89Qif9TFUIEgp8yA4VPf3EipuHQ&s=CwlVqZ7q77hxMz7ZkrsrUvjDhzXNX0PHC88T3MjuzTs&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp?rev=243530&r1=243529&r2=243530&view=diff</a><br>
> ==============================================================================<br>
> --- libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp (original)<br>
> +++ libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge.pass.cpp Wed Jul 29 11:25:45 2015<br>
> @@ -20,12 +20,35 @@<br>
><br>
> #include "test_iterators.h"<br>
><br>
> +#ifndef TEST_STD_VER >= 11<br>
<br>
</div></div>Should this be `#if`?<br></blockquote><div><br></div><div>Does clang have a warning for this?</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
> +struct S {<br>
> +     S() : i_(0) {}<br>
> +     S(int i) : i_(i) {}<br>
> +<br>
> +     S(const S&  rhs) : i_(rhs.i_) {}<br>
> +     S(      S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }<br>
> +<br>
> +     S& operator =(const S&  rhs) { i_ = rhs.i_;              return *this; }<br>
> +     S& operator =(      S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); return *this; }<br>
> +     S& operator =(int i)         { i_ = i;                   return *this; }<br>
> +<br>
> +     bool operator  <(const S&  rhs) const { return i_ < rhs.i_; }<br>
> +     bool operator ==(const S&  rhs) const { return i_ == rhs.i_; }<br>
> +     bool operator ==(int i)         const { return i_ == i; }<br>
> +<br>
> +     void set(int i) { i_ = i; }<br>
> +<br>
> +     int i_;<br>
> +     };<br>
> +#endif<br>
> +<br>
> template <class Iter><br>
> void<br>
> test_one(unsigned N, unsigned M)<br>
> {<br>
> +    typedef typename std::iterator_traits<Iter>::value_type value_type;<br>
>     assert(M <= N);<br>
> -    int* ia = new int[N];<br>
> +    value_type* ia = new value_type[N];<br>
>     for (unsigned i = 0; i < N; ++i)<br>
>         ia[i] = i;<br>
>     std::random_shuffle(ia, ia+N);<br>
> @@ -76,4 +99,10 @@ int main()<br>
>     test<bidirectional_iterator<int*> >();<br>
>     test<random_access_iterator<int*> >();<br>
>     test<int*>();<br>
> +<br>
> +#ifndef TEST_STD_VER >= 11<br>
<br>
</div></div>#if?<br>
<div><div class="h5"><br>
> +    test<bidirectional_iterator<S*> >();<br>
> +    test<random_access_iterator<S*> >();<br>
> +    test<S*>();<br>
> +#endif  // TEST_STD_VER >= 11<br>
> }<br>
><br>
> Modified: libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp<br>
> URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_libcxx_trunk_test_std_algorithms_alg.sorting_alg.merge_inplace-5Fmerge-5Fcomp.pass.cpp-3Frev-3D243530-26r1-3D243529-26r2-3D243530-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=YvbFjhjoEqf5EHNo89Qif9TFUIEgp8yA4VPf3EipuHQ&s=zpqNvFev1PLZtvahpAu9qVgd-iu0-BOCJxGcOOB03nA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp?rev=243530&r1=243529&r2=243530&view=diff</a><br>
> ==============================================================================<br>
> --- libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp (original)<br>
> +++ libcxx/trunk/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp Wed Jul 29 11:25:45 2015<br>
> @@ -18,7 +18,10 @@<br>
> #include <algorithm><br>
> #include <functional><br>
> #include <cassert><br>
> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES<br>
> +<br>
> +#include "test_macros.h"<br>
> +<br>
> +#ifndef TEST_STD_VER >= 11<br>
> #include <memory><br>
><br>
> struct indirect_less<br>
> @@ -28,7 +31,29 @@ struct indirect_less<br>
>         {return *x < *y;}<br>
> };<br>
><br>
> -#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES<br>
> +struct S {<br>
> +     S() : i_(0) {}<br>
> +     S(int i) : i_(i) {}<br>
> +<br>
> +     S(const S&  rhs) : i_(rhs.i_) {}<br>
> +     S(      S&& rhs) : i_(rhs.i_) { rhs.i_ = -1; }<br>
> +<br>
> +     S& operator =(const S&  rhs) { i_ = rhs.i_;              return *this; }<br>
> +     S& operator =(      S&& rhs) { i_ = rhs.i_; rhs.i_ = -2; assert(this != &rhs); return *this; }<br>
> +     S& operator =(int i)         { i_ = i;                   return *this; }<br>
> +<br>
> +     bool operator  <(const S&  rhs) const { return i_ < rhs.i_; }<br>
> +     bool operator  >(const S&  rhs) const { return i_ > rhs.i_; }<br>
> +     bool operator ==(const S&  rhs) const { return i_ == rhs.i_; }<br>
> +     bool operator ==(int i)         const { return i_ == i; }<br>
> +<br>
> +     void set(int i) { i_ = i; }<br>
> +<br>
> +     int i_;<br>
> +     };<br>
> +<br>
> +<br>
> +#endif  // TEST_STD_VER >= 11<br>
><br>
> #include "test_iterators.h"<br>
> #include "counting_predicates.hpp"<br>
> @@ -38,19 +63,20 @@ void<br>
> test_one(unsigned N, unsigned M)<br>
> {<br>
>     assert(M <= N);<br>
> -    int* ia = new int[N];<br>
> +    typedef typename std::iterator_traits<Iter>::value_type value_type;<br>
> +    value_type* ia = new value_type[N];<br>
>     for (unsigned i = 0; i < N; ++i)<br>
>         ia[i] = i;<br>
>     std::random_shuffle(ia, ia+N);<br>
> -    std::sort(ia, ia+M, std::greater<int>());<br>
> -    std::sort(ia+M, ia+N, std::greater<int>());<br>
> -    binary_counting_predicate<std::greater<int>, int, int> pred((std::greater<int>()));<br>
> +    std::sort(ia, ia+M, std::greater<value_type>());<br>
> +    std::sort(ia+M, ia+N, std::greater<value_type>());<br>
> +    binary_counting_predicate<std::greater<value_type>, value_type, value_type> pred((std::greater<value_type>()));<br>
>     std::inplace_merge(Iter(ia), Iter(ia+M), Iter(ia+N), std::ref(pred));<br>
>     if(N > 0)<br>
>     {<br>
>         assert(ia[0] == N-1);<br>
>         assert(ia[N-1] == 0);<br>
> -        assert(std::is_sorted(ia, ia+N, std::greater<int>()));<br>
> +        assert(std::is_sorted(ia, ia+N, std::greater<value_type>()));<br>
>         assert(pred.count() <= (N-1));<br>
>     }<br>
>     delete [] ia;<br>
> @@ -93,7 +119,11 @@ int main()<br>
>     test<random_access_iterator<int*> >();<br>
>     test<int*>();<br>
><br>
> -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES<br>
> +#ifndef TEST_STD_VER >= 11<br>
<br>
</div></div>#if?<br>
<div class="HOEnZb"><div class="h5"><br>
> +    test<bidirectional_iterator<S*> >();<br>
> +    test<random_access_iterator<S*> >();<br>
> +    test<S*>();<br>
> +<br>
>     {<br>
>     unsigned N = 100;<br>
>     unsigned M = 50;<br>
> @@ -112,5 +142,5 @@ int main()<br>
>     }<br>
>     delete [] ia;<br>
>     }<br>
> -#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES<br>
> +#endif  // TEST_STD_VER >= 11<br>
> }<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div></div>