diff --git a/persistent-data/run_set.h b/persistent-data/run_set.h index 707dde0..4ecd137 100644 --- a/persistent-data/run_set.h +++ b/persistent-data/run_set.h @@ -87,6 +87,33 @@ namespace base { return runs_.end(); } + void negate() { + rset replacement; + + if (runs_.begin() == runs_.end()) + replacement.insert(run()); + else { + auto b = runs_.begin(); + maybe last = b->end_; + + if (b->begin_) + replacement.insert(run(maybe(), *(b->begin_))); + + ++b; + while (b != runs_.end()) { + replacement.insert(run(last, b->begin_)); + last = b->end_; + ++b; + } + + if (last) + replacement.insert(run(last, maybe())); + + } + + runs_ = replacement; + } + private: typedef typename run::maybe maybe; @@ -104,7 +131,7 @@ namespace base { return maybe(std::max(*m1, *m2)); } - std::set, compare_begin> runs_; + rset runs_; }; } diff --git a/unit-tests/run_set_t.cc b/unit-tests/run_set_t.cc index e6f26bd..02ce070 100644 --- a/unit-tests/run_set_t.cc +++ b/unit-tests/run_set_t.cc @@ -16,6 +16,18 @@ namespace { (arg.end_ == static_cast(e)); } + MATCHER(EqAll, "") { + return !arg.begin_ && !arg.end_; + } + + MATCHER_P(EqOpenBegin, e, "") { + return !arg.begin_ && (arg.end_ == static_cast(e)); + } + + MATCHER_P(EqOpenEnd, b, "") { + return (arg.begin_ == static_cast(b)) && !arg.end_; + } + class RunSetTests : public Test { }; } @@ -176,4 +188,46 @@ TEST_F(RunSetTests, merge_discrete_sets) ASSERT_THAT(++(++(rs1.begin())), Eq(rs1.end())); } +TEST_F(RunSetTests, negate_empty) +{ + run_set rs; + rs.negate(); + ASSERT_THAT(*rs.begin(), EqAll()); + ASSERT_THAT(++rs.begin(), Eq(rs.end())); +} + +TEST_F(RunSetTests, negate_single) +{ + run_set rs; + rs.add(5, 10); + rs.negate(); + ASSERT_THAT(*rs.begin(), EqOpenBegin(5)); + ASSERT_THAT(*(++rs.begin()), EqOpenEnd(10)); + ASSERT_THAT(++(++rs.begin()), Eq(rs.end())); +} + +TEST_F(RunSetTests, negate_double) +{ + run_set rs; + rs.add(5, 10); + rs.add(15, 20); + rs.negate(); + ASSERT_THAT(*rs.begin(), EqOpenBegin(5)); + ASSERT_THAT(*(++rs.begin()), EqRun(10, 15)); + ASSERT_THAT(*(++(++rs.begin())), EqOpenEnd(20)); + ASSERT_THAT(++(++(++rs.begin())), Eq(rs.end())); +} + +TEST_F(RunSetTests, negate_negate) +{ + run_set rs; + rs.add(5, 10); + rs.add(15, 20); + rs.negate(); + rs.negate(); + ASSERT_THAT(*rs.begin(), EqRun(5, 10)); + ASSERT_THAT(*(++rs.begin()), EqRun(15, 20)); + ASSERT_THAT(++(++rs.begin()), Eq(rs.end())); +} + //----------------------------------------------------------------