From 52b3cd46c76fd4be18aeb8422a08a073484b9fad Mon Sep 17 00:00:00 2001 From: Rutger Broekhoff Date: Sat, 29 Aug 2026 12:01:42 +0200 Subject: More module implementation partition units --- server/src/time.cppm | 169 ++++----------------------------------------------- 1 file changed, 12 insertions(+), 157 deletions(-) (limited to 'server/src/time.cppm') diff --git a/server/src/time.cppm b/server/src/time.cppm index 8f53bd9..0007839 100644 --- a/server/src/time.cppm +++ b/server/src/time.cppm @@ -14,39 +14,13 @@ class period timestamp end_; public: - explicit period(timestamp start, timestamp end) : start_{start}, end_{end} - { - if (start >= end) - { - throw std::invalid_argument("period: start should be before end"); - } - } - - [[nodiscard]] auto intersect(period other) const -> std::optional - { - auto const new_start = start_ < other.start() ? other.start() : start_; - auto const new_end = other.end() < end_ ? other.end() : end_; - return new_start < new_end ? std::make_optional(period{new_start, new_end}) - : std::nullopt; - } + explicit period(timestamp start, timestamp end); + [[nodiscard]] auto intersect(period other) const -> std::optional; [[nodiscard]] auto except(period other) const - -> std::pair, std::optional> - { - auto const before_start = start_; - auto const before_end = other.start(); - auto const after_start = end_; - auto const after_end = other.end(); - std::optional before, after; - if (before_start < before_end) - before = period{before_start, before_end}; - if (after_start < after_end) - after = period{after_end, after_start}; - return std::make_pair(before, after); - } - - [[nodiscard]] auto start() const -> timestamp { return start_; } - [[nodiscard]] auto end() const -> timestamp { return end_; } + -> std::pair, std::optional>; + [[nodiscard]] auto start() const -> timestamp; + [[nodiscard]] auto end() const -> timestamp; }; class period_seq @@ -115,21 +89,7 @@ class period_seq return periods; } - explicit period_seq(std::vector periods) - : periods_{std::move(periods)} - { - for (auto i = 0uz; i < periods_.size(); i++) - { - if (i + 1 < periods_.size()) - { - if (periods_[i].end() >= periods_[i + 1].start()) - { - throw std::logic_error{"period_seq: vector provided to private " - "constructor not ordered properly"}; - } - } - } - } + explicit period_seq(std::vector periods); public: template S> @@ -138,119 +98,14 @@ public: { } - explicit period_seq(period singleton) : periods_{singleton} {} - - [[nodiscard]] auto intersect(period_seq const& other) const -> period_seq - { - auto it1 = periods_.begin(); - auto end1 = periods_.end(); - auto it2 = other.periods_.begin(); - auto end2 = other.periods_.end(); - - auto res = std::vector{}; - while (it1 != end1 && it2 != end2) - { - auto overlap = it1->intersect(*it2); - if (overlap) - { - res.push_back(*overlap); - if (it1->end() < it2->end()) - { - it1++; - } - else - { - it2++; - } - } - else - { - if (it1->end() < it2->start()) - { - it1++; - } - else - { - it2++; - } - } - } - - return period_seq{res}; - } - - [[nodiscard]] auto except(period_seq const& other) const -> period_seq - { - // This code was pretty tricky to write, I wouldn't be surprised if it - // has some bugs in it. - - auto it1 = periods_.begin(); - auto end1 = periods_.end(); - auto it2 = other.periods_.begin(); - auto end2 = other.periods_.end(); - - auto res = std::vector{}; - if (it1 == end1) - return period_seq{res}; - if (it2 == end2) - return period_seq{periods_}; - auto period1 = period{*it1++}; - - while (it1 != end1 && it2 != end2) - { - if (period1.end() <= it2->start()) - { - res.push_back(period1); - period1 = *it1++; - } - else if (it2->end() <= period1.start()) - { - it2++; - } - else /* period1.begin() < it2->end() && it2->begin() < - period1.end() */ - { - auto const [mbefore, mafter] = period1.except(*it2); - if (mbefore) - res.push_back(*mbefore); - if (mafter) - { - period1 = *mafter; - } - else - { - period1 = *it1++; - } - } - } - - return period_seq{res}; - } + explicit period_seq(period singleton); - [[nodiscard]] auto periods() const -> std::vector const& - { - return periods_; - } + [[nodiscard]] auto intersect(period_seq const& other) const -> period_seq; + [[nodiscard]] auto except(period_seq const& other) const -> period_seq; + [[nodiscard]] auto periods() const -> std::vector const&; }; -auto operator<<(std::ostream& os, period const& p) -> std::ostream& -{ - return os << "[" << p.start() << ", " << p.end() << ")"; -} - -auto operator<<(std::ostream& os, period_seq const& ps) -> std::ostream& -{ - os << "{"; - auto it = ps.periods().begin(); - while (it != ps.periods().end()) - { - os << " " << *it; - if (++it != ps.periods().end()) - { - os << ","; - } - } - return os << " }"; -} +auto operator<<(std::ostream& os, period const& p) -> std::ostream&; +auto operator<<(std::ostream& os, period_seq const& ps) -> std::ostream&; } // namespace routemon::time -- cgit v1.3