`<xutility>`: Should we skip `_Debug_lt_pred()` for known comparators with known types?
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 11.1k
- Forks
- 1.7k
- Avg merge
- 4d 15h
- Merged PRs (30d)
- 22
Description
_Debug_lt_pred() detects bogus user-provided comparators, e.g. less-than-or-equal behavior, or those who tried to implement tuple-like comparison but got it wrong (this is tricky for people who haven't learned to recognize the pattern):
This debug check is very valuable, but we always perform it ("when the arguments are the cv-same-type"), even when we could statically detect that the predicate and arguments are good. This is likely because metaprogramming was very difficult for us historically (this check predates <type_traits> and definitely if constexpr), and tag dispatch was expensive in debug mode, so doing anything would have been counterproductive. Now it should be easier.
I believe that an exhaustive list of the "known predicates" is:
less<T>whereTis a "known type"less<>ranges::lessgreater<T>whereTis a "known type"greater<>ranges::greater
We can't trust less<InvolvesUserProvidedType> because it could call a user-provided operator< or even be directly specialized by the user (specializing less is one of the few Standard Library types where this is actually done in practice).
As for "known types", we know what will happen if we compare many types with operator<. This is not an exhaustive list:
- Certain primary type categories:
- Integral types
- Floating-point types
- While NaN values break the "strict weak ordering" property (and are therefore forbidden from participating in sorting or ordered associative containers),
_Debug_lt_pred()is only checking whenpred(x, y)andpred(y, x)are simultaneouslytrue(i.e. looking for less-equal behavior). NaNs can't cause that, so we may as well skip this check for floating-point types.
- While NaN values break the "strict weak ordering" property (and are therefore forbidden from participating in sorting or ordered associative containers),
- Pointer types
- Popular Standard Library types:
basic_string<Elem, char_traits<Elem>, AnyAlloc>- When
Elemis any ofchar,wchar_t,char8_t,char16_t,char32_t
- When
basic_string_view<Elem, char_traits<Elem>>
Because this would only be a debug perf improvement, I think we should limit ourselves to how many Standard Library types we detect. We know how vector<int> comparisons will behave, but while vector is popular, how often is it being given to _Debug_lt_pred()? I could see a case for pair<Known1, Known2>, maybe tuple<Known...>, especially because saving debug checks there is potentially a bigger win. We should think some more about what types we want to handle, before writing code.
We should perhaps think of an extensible system, e.g. an internal type trait that basic_string and basic_string_view specialize, so that if we do wish to extend the known types later, we can do so more easily. I'm much less interested in over-engineering something that users can extend (whether for their predicates or their types), as that starts to sound like complexity we would need to support.
Note that less<T> doesn't need to exactly match its argument types to have known behavior. less<int> comparing two shorts is going to have known results. I think it would be sufficient to require that all of the types involved be known, but not require any relationships between the types, before we skip the debug check.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with _Debug_lt_pred() in stl/inc/xutility at the linked lines, then review the listed known predicates and known types. Done means agreeing on a bounded set of cases where the debug check can be skipped safely, with an implementation plan that avoids over-engineering user-extensible traits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- performance
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100