On 30/07/2015 12:30, Jonathan Wakely wrote:
> On 29/07/15 22:08 +0200, François Dumont wrote:
>> Hi
>>
>>    Here is a patch to add irreflexive debug check.
>
> Awesome!
>
> You can add PR libstdc++/60519 to the changelog.
Sure.
>
>
>>    Standard algos signatures are such that there is no guaranty that
>> the operator < or predicate to compare the iterator value type will
>> exist. So I had to check if the call is valid using C++11 features
>> declval and decltype.
>
> Surely if someone calls an algorithm that requires a
> StrictWeakOrdering then we know that it's valid to compare the value
> types using the comparison implied by that particular call (either
> operator< or the supplied predicate), and we should only be adding
> this assertion to algorithms that require a StrictWeakOrdering.
>
> Am I missing something?
    If you consider for instance lower_bound signature:

  template<typename _ForwardIterator, typename _Tp>
    inline _ForwardIterator
    lower_bound(_ForwardIterator __first, _ForwardIterator __last,
        const _Tp& __val)

    This algo require expressions *__first < __val or __val < *__first
to be well defined. But what the check is doing is *__first < *__first
that might not exist as the algo won't need it. The range [__first,
__last[ might have been sorted using another functor that we don't know
at the time of the call to lower_bound.

    There might be situations where the check will be useless but I
prefer to keep this debug check simple and so always go through the check.
>
> Assuming those validity checks are needed ...
>
>> +  struct _Irreflexive_checker
>> +  {
>> +#if __cplusplus >= 201103L
>> +    template<typename _It>
>> +      using __it_ref_t = typename std::iterator_traits<_It>::reference;
>
> I'd just call this __ref_t, because where you use it the "it" part is
> already implied by the template argument: __ref_t<_It>
>
> Or you could add:
>
>  template<typename _It>
>    static typename std::iterator_traits<_It>::reference
>    __deref();
>
> and replace every std::declval<__it_ref_t<_It>>() with __deref<_It>()
> which is much shorter.

Nice, I will use that.

>
>> +    template<typename _It,
>> +         typename = decltype(
>> +    std::declval<__it_ref_t<_It> >() < std::declval<__it_ref_t<_It>
>> >())>
>
> N.B. as this is only for C++11 and later there's no need for the
> spaces before the closing >

You read my mind on this one, thanks.

François

Reply via email to