This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch] C++14: N3671 Making non-modifying sequence operations more robust


On 10 June 2013 23:08, Chris Jefferson wrote:
> On 08/06/13 17:13, Jonathan Wakely wrote:
>>
>> Another C++14 feature.
>>
>>          * include/bits/stl_algo.h (is_permutation): Add overloads from
>> N3671.
>>          * include/bits/stl_algobase.h (equal, mismatch): Likewise.
>>          * testsuite/25_algorithms/equal/1.cc: Remove duplicate test case.
>>          * testsuite/25_algorithms/equal/2.cc: New.
>>          * testsuite/25_algorithms/equal/check_type2.cc: New.
>>          * testsuite/25_algorithms/is_permutationqual/2.cc: New.
>>          * testsuite/25_algorithms/is_permutationqual/check_type2.cc: New.
>>          * testsuite/25_algorithms/mismatch/2.cc: New.
>>          * testsuite/25_algorithms/mismatch/check_type2.cc: New.
>>          * testsuite/util/testsuite_iterators.h: Fix spelling.
>>
>> Tested x86_64-linux, committed to trunk.
>
> Small tweak, in (for example):
>
> +  template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
> +    inline bool
> +    equal(_IIter1 __first1, _IIter1 __last1,
> +      _IIter2 __first2, _IIter2 __last2, _BinaryPredicate __binary_pred)
> +    {
> +      // concept requirements
> + __glibcxx_function_requires(_InputIteratorConcept<_IIter1>)
> + __glibcxx_function_requires(_InputIteratorConcept<_IIter2>)
> +      __glibcxx_requires_valid_range(__first1, __last1);
> +      __glibcxx_requires_valid_range(__first2, __last2);
> +
> +      using _Cat1 = typename iterator_traits<_IIter1>::iterator_category;
> +      using _Cat2 = typename iterator_traits<_IIter2>::iterator_category;
> +      using _IIter1_is_RA = is_same<_Cat1, random_access_iterator_tag>;
> +      using _IIter2_is_RA = is_same<_Cat2, random_access_iterator_tag>;
> +      constexpr bool __ra_iters = _IIter1_is_RA() && _IIter1_is_RA();
> +      if (__ra_iters)
> +    {
> +      auto __d1 = std::distance(__first1, __last1);
> +      auto __d2 = std::distance(__first2, __last2);
> +      if (__d1 != __d2)
> +        return false;
> +    }
> +
> +      for (; __first1 != __last1 && __first2 != __last2; ++__first1,
> ++__first2)
> +    if (!bool(__binary_pred(*__first1, *__first2)))
> +      return false;
> +      return __ra_iters || (__first1 == __last1 && __first2 == __last2);
> +    }
>
> After we are in the 'if(__ra_iters)' case, and checked that __d1==__d2,
> could dispatch to old-fashioned equal(__first1, __last1, __first2,
> __binary_pred). This has the advantage that it saves repeatedly checking
> __first2 != __last2 unnessasairly, and I suspect only having one loop
> condition to check will give the compiler a better shot at optimising /
> unrolling (although, I haven't checked that I will admit).

Good idea, thanks, I'll make that change too.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]