fix inconsistent behavior of Domain factories with invalid intervals

This commit is contained in:
Laurent Perron
2025-01-22 14:35:31 +01:00
parent 4e98a6512d
commit 52a91707f6
2 changed files with 29 additions and 4 deletions

View File

@@ -64,6 +64,16 @@ std::string IntervalsAsString(const Intervals& intervals) {
return result;
}
void SortAndRemoveInvalidIntervals(
absl::InlinedVector<ClosedInterval, 1>* intervals) {
intervals->erase(std::remove_if(intervals->begin(), intervals->end(),
[](const ClosedInterval& interval) {
return interval.start > interval.end;
}),
intervals->end());
std::sort(intervals->begin(), intervals->end());
}
// Transforms a sorted list of intervals in a sorted DISJOINT list for which
// IntervalsAreSortedAndNonAdjacent() would return true.
void UnionOfSortedIntervals(absl::InlinedVector<ClosedInterval, 1>* intervals) {
@@ -163,7 +173,7 @@ Domain Domain::FromValues(std::vector<int64_t> values) {
Domain Domain::FromIntervals(absl::Span<const ClosedInterval> intervals) {
Domain result;
result.intervals_.assign(intervals.begin(), intervals.end());
std::sort(result.intervals_.begin(), result.intervals_.end());
SortAndRemoveInvalidIntervals(&result.intervals_);
UnionOfSortedIntervals(&result.intervals_);
return result;
}
@@ -176,7 +186,7 @@ Domain Domain::FromFlatSpanOfIntervals(
for (int i = 0; i < flat_intervals.size(); i += 2) {
result.intervals_.push_back({flat_intervals[i], flat_intervals[i + 1]});
}
std::sort(result.intervals_.begin(), result.intervals_.end());
SortAndRemoveInvalidIntervals(&result.intervals_);
UnionOfSortedIntervals(&result.intervals_);
return result;
}
@@ -196,7 +206,7 @@ Domain Domain::FromVectorIntervals(
result.intervals_.push_back({interval[0], interval[1]});
}
}
std::sort(result.intervals_.begin(), result.intervals_.end());
SortAndRemoveInvalidIntervals(&result.intervals_);
UnionOfSortedIntervals(&result.intervals_);
return result;
}

View File

@@ -131,12 +131,18 @@ class Domain {
/**
* Creates a domain from the union of an unsorted list of intervals.
*
* Note that invalid intervals (start > end) will log a DFATAL error and will
* be ignored.
*/
static Domain FromIntervals(absl::Span<const ClosedInterval> intervals);
/**
* Same as FromIntervals() for a flattened representation (start, end,
* start, end, ...).
*
* Note that invalid intervals (start > end) will log a DFATAL error and will
* be ignored.
*/
static Domain FromFlatSpanOfIntervals(
absl::Span<const int64_t> flat_intervals);
@@ -144,7 +150,13 @@ class Domain {
/**
* This method is available in Python, Java and .NET. It allows
* building a Domain object from a list of intervals (long[][] in Java and
* .NET, [[0, 2], [5, 5], [8, 10]] in python).
* .NET, [[0, 2], [5], [8, 10]] in python).
*
* Note that the intervals can be defined with a single value (i.e. [5]), or
* two increasing values (i.e. [8, 10]).
*
* Invalid intervals (start > end) will log a DFATAL error and will be
* ignored.
*/
static Domain FromVectorIntervals(
const std::vector<std::vector<int64_t> >& intervals);
@@ -153,6 +165,9 @@ class Domain {
* This method is available in Python, Java and .NET. It allows
* building a Domain object from a flattened list of intervals
* (long[] in Java and .NET, [0, 2, 5, 5, 8, 10] in python).
*
* Note that invalid intervals (start > end) will log a DFATAL error and will
* be ignored.
*/
static Domain FromFlatIntervals(const std::vector<int64_t>& flat_intervals);