mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 21:30:53 +00:00
Add update and merge methods to Intervals<T>
Also updated build files and added tests for `Intervals<T>`.
This commit is contained in:
committed by
Baldur Karlsson
parent
a6a1a76ca5
commit
3bc53094da
@@ -105,6 +105,8 @@ set(sources
|
||||
core/remote_server.cpp
|
||||
core/replay_proxy.cpp
|
||||
core/replay_proxy.h
|
||||
core/intervals.h
|
||||
core/intervals_tests.cpp
|
||||
android/android.cpp
|
||||
android/android_patch.cpp
|
||||
android/android_tools.cpp
|
||||
|
||||
@@ -189,21 +189,106 @@ public:
|
||||
inline iterator begin() { return Wrap(StartPoints.begin()); }
|
||||
inline const_iterator begin() const { return Wrap(StartPoints.begin()); }
|
||||
inline const_iterator end() const { return Wrap(StartPoints.end()); }
|
||||
// finds the interval containing `x`.
|
||||
// Find the interval containing `x`.
|
||||
iterator find(uint64_t x)
|
||||
{
|
||||
auto it = StartPoints.upper_bound(x); // first starting after `x`
|
||||
// Find the first interval starting after `x`; return the preceding interval.
|
||||
auto it = StartPoints.upper_bound(x);
|
||||
RDCASSERT(it != StartPoints.begin());
|
||||
it--; // last *not* starting after `x`
|
||||
it--;
|
||||
return Wrap(it);
|
||||
}
|
||||
|
||||
// finds the interval containing `x`.
|
||||
// Find the interval containing `x`.
|
||||
const_iterator find(uint64_t x) const
|
||||
{
|
||||
auto it = StartPoints.upper_bound(x); // first starting after `x`
|
||||
// Find the first interval starting after `x`; return the preceding interval.
|
||||
auto it = StartPoints.upper_bound(x);
|
||||
RDCASSERT(it != StartPoints.begin());
|
||||
it--; // last *not* starting after `x`
|
||||
it--;
|
||||
return Wrap(it);
|
||||
}
|
||||
};
|
||||
|
||||
// Update the values of overlapping intervals to `comp(oldValue, val)`
|
||||
// (where `oldValue` is the value of the interval prior to calling `update`).
|
||||
// If start/finish do not lie on the boundaries between intervals, the intervals
|
||||
// will be split as necessary.
|
||||
template <typename Compose>
|
||||
void update(uint64_t start, uint64_t finish, T val, Compose comp)
|
||||
{
|
||||
auto i = find(start);
|
||||
|
||||
// Split the interval so that `i.start == start`
|
||||
i->split(start);
|
||||
|
||||
// Loop over all the intervals in `a` that intersect the interval [start, finish)
|
||||
for(; i->start() < finish; i++)
|
||||
{
|
||||
if(i->finish() > finish)
|
||||
{
|
||||
// In this case, interval `i` extends beyond `finish`;
|
||||
// split `i` so that we only update the portion of `i` in [start, finish).
|
||||
i->split(finish);
|
||||
|
||||
// `split` leaves `i` pointing at the interval starting at `finish`;
|
||||
// move back to the interval finishing at `finish`.
|
||||
i--;
|
||||
}
|
||||
i->setValue(comp(i->value(), val));
|
||||
i->mergeLeft();
|
||||
}
|
||||
|
||||
// `i` now points to the interval following the last interval whose value was
|
||||
// modified; merge `i` with that last modified interval, if the values match.
|
||||
i->mergeLeft();
|
||||
}
|
||||
|
||||
// Update `this` by composing the value of each interval with the value of the
|
||||
// corresponding interval in `other`.
|
||||
// If the intervals in `this` and `other` do not line up, then the intervals in
|
||||
// `this` will be split as necessary.
|
||||
template <typename Compose>
|
||||
void merge(const Intervals &other, Compose comp)
|
||||
{
|
||||
auto j = other.begin();
|
||||
auto i = begin();
|
||||
|
||||
// Loop over the intervals in `this` (iterator `i`), while maintaining the
|
||||
// interval `j` in `other` that contains `i`.
|
||||
// The intervals in `this` are split as necessary, so that each `i` is
|
||||
// contained in a single interval of `other`.
|
||||
// Loop invariants:
|
||||
// * i.start() >= j.start()
|
||||
// * i.start() < j.end()
|
||||
while(true)
|
||||
{
|
||||
RDCASSERT(i->start() >= j->start());
|
||||
RDCASSERT(i->start() < j->finish());
|
||||
if(i->finish() > j->finish())
|
||||
{
|
||||
i->split(j->finish());
|
||||
i--;
|
||||
}
|
||||
|
||||
// Now i is contained in j, so we can update the value of all of i
|
||||
i->setValue(comp(i->value(), j->value()));
|
||||
|
||||
// The value of i and the interval left of i are now final;
|
||||
// if these two intervals now have the same value, they can safely be
|
||||
// merged into a single interval.
|
||||
i->mergeLeft();
|
||||
|
||||
// Move to the next interval in `this`; also advance to the next interval
|
||||
// in `other`, if necessary to maintain the invariant `i.start < j.end`.
|
||||
i++;
|
||||
if(i == end())
|
||||
{
|
||||
j++;
|
||||
RDCASSERT(j == other.end());
|
||||
return;
|
||||
}
|
||||
if(i->start() >= j->finish())
|
||||
j++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,393 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "intervals.h"
|
||||
#include "common/globalconfig.h"
|
||||
|
||||
#if ENABLED(ENABLE_UNIT_TESTS)
|
||||
|
||||
#include "3rdparty/catch/catch.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <vector>
|
||||
|
||||
struct Interval
|
||||
{
|
||||
uint64_t start;
|
||||
uint64_t value;
|
||||
uint64_t end;
|
||||
};
|
||||
|
||||
void check_intervals(Intervals<uint64_t> &value, const std::vector<Interval> &expected)
|
||||
{
|
||||
auto i = value.begin();
|
||||
auto j = expected.begin();
|
||||
for(; i != value.end() && j != expected.end(); i++, j++)
|
||||
{
|
||||
CHECK(i->start() == j->start);
|
||||
CHECK(i->value() == j->value);
|
||||
CHECK(i->finish() == j->end);
|
||||
}
|
||||
CHECK((i == value.end()));
|
||||
CHECK((j == expected.end()));
|
||||
}
|
||||
|
||||
Intervals<uint64_t> make_intervals(const std::vector<Interval> &intervals)
|
||||
{
|
||||
Intervals<uint64_t> res;
|
||||
for(auto i = intervals.begin(); i != intervals.end(); i++)
|
||||
{
|
||||
auto j = res.end();
|
||||
j--;
|
||||
if(i->start > j->start())
|
||||
j->split(i->start);
|
||||
if(i->end < j->finish())
|
||||
{
|
||||
j->split(i->end);
|
||||
j--;
|
||||
}
|
||||
j->setValue(i->value);
|
||||
}
|
||||
check_intervals(res, intervals);
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST_CASE("Test Intervals type", "[intervals]")
|
||||
{
|
||||
SECTION("update tests")
|
||||
{
|
||||
SECTION("empty Intervals")
|
||||
{
|
||||
Intervals<uint64_t> test;
|
||||
check_intervals(test, {{0, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update a sub-interval")
|
||||
{
|
||||
Intervals<uint64_t> test;
|
||||
test.update(5, 10, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update a sub-interval matching on the left")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(5, 7, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 2, 7}, {7, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update a sub-interval matching on the right")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(7, 10, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 7}, {7, 2, 10}, {10, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update an interval that exactly matches an existing interval")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(5, 10, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 2, 10}, {10, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update a properly overlapping interval")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(7, 15, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 7}, {7, 2, 10}, {10, 1, 15}, {15, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update a super-interval")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(2, 15, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 2}, {2, 1, 5}, {5, 2, 10}, {10, 1, 15}, {15, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update a super-interval matching on the left")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(5, 15, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 2, 10}, {10, 1, 15}, {15, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update a super-interval matching on the right")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(2, 10, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 2}, {2, 1, 5}, {5, 2, 10}, {10, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update overlapping 2 intervals")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, 20}, {20, 10, 30}, {30, 0, UINT64_MAX}});
|
||||
test.update(7, 25, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5},
|
||||
{5, 1, 7},
|
||||
{7, 2, 10},
|
||||
{10, 1, 20},
|
||||
{20, 11, 25},
|
||||
{25, 10, 30},
|
||||
{30, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update overlapping 2 intervals matching on start of leftmost interval")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, 20}, {20, 10, 30}, {30, 0, UINT64_MAX}});
|
||||
test.update(5, 25, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(
|
||||
test,
|
||||
{{0, 0, 5}, {5, 2, 10}, {10, 1, 20}, {20, 11, 25}, {25, 10, 30}, {30, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update overlapping 2 intervals matching on end of leftmost interval")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 5}, {5, 5, 10}, {10, 0, 20}, {20, 10, 30}, {30, 0, UINT64_MAX}});
|
||||
test.update(10, 25, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(
|
||||
test,
|
||||
{{0, 0, 5}, {5, 5, 10}, {10, 1, 20}, {20, 11, 25}, {25, 10, 30}, {30, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update overlapping 2 intervals matching on start of rightmost interval")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, 20}, {20, 10, 30}, {30, 0, UINT64_MAX}});
|
||||
test.update(7, 20, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(
|
||||
test, {{0, 0, 5}, {5, 1, 7}, {7, 2, 10}, {10, 1, 20}, {20, 10, 30}, {30, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update overlapping 2 intervals matching on end of rightmost interval")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, 20}, {20, 10, 30}, {30, 0, UINT64_MAX}});
|
||||
test.update(7, 30, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(
|
||||
test, {{0, 0, 5}, {5, 1, 7}, {7, 2, 10}, {10, 1, 20}, {20, 11, 30}, {30, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update triggering merge on left")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(10, 20, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 20}, {20, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update triggering merge on right")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(2, 5, 1, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 2}, {2, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("overlapping update triggering merge on left")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(7, 20, 1, [](uint64_t, uint64_t) -> uint64_t { return 1; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 20}, {20, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("overlapping update triggering merge on right")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 5}, {5, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
test.update(2, 7, 1, [](uint64_t, uint64_t) -> uint64_t { return 1; });
|
||||
check_intervals(test, {{0, 0, 2}, {2, 1, 10}, {10, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("update triggering multiple merges")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals(
|
||||
{{0, 0, 5}, {5, 1, 10}, {10, 0, 12}, {12, 5, 18}, {18, 0, 20}, {20, 1, 30}, {30, 0, UINT64_MAX}});
|
||||
test.update(7, 25, 1, [](uint64_t, uint64_t) -> uint64_t { return 1; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 30}, {30, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION(
|
||||
"update triggering multiple merges, including merge with non-overlapping interval on left")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals(
|
||||
{{0, 0, 5}, {5, 1, 10}, {10, 0, 12}, {12, 5, 18}, {18, 0, 20}, {20, 1, 30}, {30, 0, UINT64_MAX}});
|
||||
test.update(10, 25, 1, [](uint64_t, uint64_t) -> uint64_t { return 1; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 30}, {30, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION(
|
||||
"update triggering multiple merges, including merge with non-overlapping interval on right")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals(
|
||||
{{0, 0, 5}, {5, 1, 10}, {10, 0, 12}, {12, 5, 18}, {18, 0, 20}, {20, 1, 30}, {30, 0, UINT64_MAX}});
|
||||
test.update(7, 20, 1, [](uint64_t, uint64_t) -> uint64_t { return 1; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 30}, {30, 0, UINT64_MAX}});
|
||||
};
|
||||
};
|
||||
|
||||
SECTION("mergeIntervals tests")
|
||||
{
|
||||
SECTION("merge matching intervals")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 10}, {10, 1, 20}, {20, 0, 30}, {30, 1, 40}, {40, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other =
|
||||
make_intervals({{0, 0, 10}, {10, 1, 20}, {20, 0, 30}, {30, 1, 40}, {40, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 10}, {10, 2, 20}, {20, 0, 30}, {30, 2, 40}, {40, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("merge shifted intervals")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 10}, {10, 1, 20}, {20, 0, 30}, {30, 1, 40}, {40, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other =
|
||||
make_intervals({{0, 0, 5}, {5, 1, 15}, {15, 0, 25}, {25, 1, 35}, {35, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5},
|
||||
{5, 1, 10},
|
||||
{10, 2, 15},
|
||||
{15, 1, 20},
|
||||
{20, 0, 25},
|
||||
{25, 1, 30},
|
||||
{30, 2, 35},
|
||||
{35, 1, 40},
|
||||
{40, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("merge into empty intervals")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other =
|
||||
make_intervals({{0, 0, 5}, {5, 1, 15}, {15, 0, 25}, {25, 1, 35}, {35, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 15}, {15, 0, 25}, {25, 1, 35}, {35, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("merge with empty intervals")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 5}, {5, 1, 15}, {15, 0, 25}, {25, 1, 35}, {35, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other = make_intervals({{0, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5}, {5, 1, 15}, {15, 0, 25}, {25, 1, 35}, {35, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("merge into single interval")
|
||||
{
|
||||
Intervals<uint64_t> test = make_intervals({{0, 0, 10}, {10, 1, 30}, {30, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other =
|
||||
make_intervals({{0, 0, 5}, {5, 1, 15}, {15, 0, 25}, {25, 1, 35}, {35, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5},
|
||||
{5, 1, 10},
|
||||
{10, 2, 15},
|
||||
{15, 1, 25},
|
||||
{25, 2, 30},
|
||||
{30, 1, 35},
|
||||
{35, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("merge with single interval")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 5}, {5, 1, 15}, {15, 0, 25}, {25, 1, 35}, {35, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other = make_intervals({{0, 0, 10}, {10, 1, 30}, {30, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 5},
|
||||
{5, 1, 10},
|
||||
{10, 2, 15},
|
||||
{15, 1, 25},
|
||||
{25, 2, 30},
|
||||
{30, 1, 35},
|
||||
{35, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("merge disjoint before")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 50}, {50, 1, 60}, {60, 0, 70}, {70, 1, 80}, {80, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other =
|
||||
make_intervals({{0, 0, 10}, {10, 1, 20}, {20, 0, 30}, {30, 1, 40}, {40, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 10},
|
||||
{10, 1, 20},
|
||||
{20, 0, 30},
|
||||
{30, 1, 40},
|
||||
{40, 0, 50},
|
||||
{50, 1, 60},
|
||||
{60, 0, 70},
|
||||
{70, 1, 80},
|
||||
{80, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("merge disjoint after")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 10}, {10, 1, 20}, {20, 0, 30}, {30, 1, 40}, {40, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other =
|
||||
make_intervals({{0, 0, 50}, {50, 1, 60}, {60, 0, 70}, {70, 1, 80}, {80, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 10},
|
||||
{10, 1, 20},
|
||||
{20, 0, 30},
|
||||
{30, 1, 40},
|
||||
{40, 0, 50},
|
||||
{50, 1, 60},
|
||||
{60, 0, 70},
|
||||
{70, 1, 80},
|
||||
{80, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("merge disjoint interleaved")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 10}, {10, 1, 20}, {20, 0, 50}, {50, 1, 60}, {60, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other =
|
||||
make_intervals({{0, 0, 30}, {30, 1, 40}, {40, 0, 70}, {70, 1, 80}, {80, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 10},
|
||||
{10, 1, 20},
|
||||
{20, 0, 30},
|
||||
{30, 1, 40},
|
||||
{40, 0, 50},
|
||||
{50, 1, 60},
|
||||
{60, 0, 70},
|
||||
{70, 1, 80},
|
||||
{80, 0, UINT64_MAX}});
|
||||
};
|
||||
|
||||
SECTION("merge disjoint interleaved touching")
|
||||
{
|
||||
Intervals<uint64_t> test =
|
||||
make_intervals({{0, 0, 10}, {10, 1, 20}, {20, 0, 30}, {30, 1, 40}, {40, 0, UINT64_MAX}});
|
||||
Intervals<uint64_t> other =
|
||||
make_intervals({{0, 0, 20}, {20, 1, 30}, {30, 0, 40}, {40, 1, 50}, {50, 0, UINT64_MAX}});
|
||||
test.merge(other, [](uint64_t x, uint64_t y) -> uint64_t { return x + y; });
|
||||
check_intervals(test, {{0, 0, 10}, {10, 1, 50}, {50, 0, UINT64_MAX}});
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#endif // ENABLED(ENABLE_UNIT_TESTS)
|
||||
@@ -410,6 +410,7 @@
|
||||
<ClCompile Include="common\threading_tests.cpp" />
|
||||
<ClCompile Include="core\core.cpp" />
|
||||
<ClCompile Include="core\image_viewer.cpp" />
|
||||
<ClCompile Include="core\intervals_tests.cpp" />
|
||||
<ClCompile Include="core\plugins.cpp" />
|
||||
<ClCompile Include="core\precompiled.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
|
||||
@@ -824,6 +824,9 @@
|
||||
<ClCompile Include="common\threading_tests.cpp">
|
||||
<Filter>Common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="core\intervals_tests.cpp">
|
||||
<Filter>Core</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="os\win32\comexport.def">
|
||||
|
||||
Reference in New Issue
Block a user