Less than operator is broken
- Dominant language
- C++
- Stars
- 16
- Forks
- 50
- PR merge metrics
- No merged PRs in 30d
Description
From `interval.hpp`:
```
//- operator < -----------------------------------------------------------------
template
typename boost::enable_if, bool>::type
operator < (const Type& left, const Type& right)
{
if(icl::is_empty(left))
return !icl::is_empty(right);
else
return lower_less(left,right)
|| (lower_equal(left,right) && upper_less(left,right));
}
```
This does not seem at all right. Consider this code and its results (the comments).
```
#include
#include
int main()
{
const auto e0 = boost::icl::interval::right_open(0, 0);
const auto e4 = boost::icl::interval::right_open(4, 4);
const auto i2 = boost::icl::interval::right_open(2, 3);
const auto i6 = boost::icl::interval::right_open(6, 7);
std::cout << (e0 < e4) << "\n"; // false
std::cout << (e4 < e0) << "\n"; // false
std::cout << (i2 < i6) << "\n"; // true
std::cout << (i6 < i2) << "\n"; // false
std::cout << (e0 < i2) << "\n"; // true
std::cout << (i2 < e0) << "\n"; // false
std::cout << (e4 < i2) << "\n"; // true
std::cout << (i2 < e4) << "\n"; // true
}
```
There are various WTFs in those results. Obviously the basic invariant `(a < b) == !(b < a)` is violated twice, and also the last 4 results are clearly inconsistent.
Also, I think the basic idea that empty sets are treated specially is wrong, because it means you can't use them for things like `interval_set<>::lower_bound()`. I think the correct implementation would just be:
```
//- operator < -----------------------------------------------------------------
template
typename boost::enable_if, bool>::type
operator < (const Type& left, const Type& right)
{
return lower_less(left,right) || (lower_equal(left,right) && upper_less(left,right));
}
```
But maybe there is code that relies on the current broken behaviour?
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.