--- /dev/null
+// Copyright (C) 2022 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#pragma once
+
+#include <cstdint>
+
+namespace util {
+
+class Duration
+{
+public:
+ explicit Duration(int64_t sec = 0, int64_t nsec = 0);
+
+ bool operator==(const Duration& other) const;
+ bool operator!=(const Duration& other) const;
+ bool operator<(const Duration& other) const;
+ bool operator>(const Duration& other) const;
+ bool operator<=(const Duration& other) const;
+ bool operator>=(const Duration& other) const;
+
+ Duration operator+(const Duration& other) const;
+ Duration operator-(const Duration& other) const;
+ Duration operator*(double factor) const;
+ Duration operator/(double factor) const;
+
+ Duration operator-() const;
+
+ int64_t sec() const;
+ int64_t nsec() const;
+ int32_t nsec_decimal_part() const;
+
+private:
+ int64_t m_ns = 0;
+};
+
+inline Duration::Duration(int64_t sec, int64_t nsec)
+ : m_ns(1'000'000'000 * sec + nsec)
+{
+}
+
+inline bool
+Duration::operator==(const Duration& other) const
+{
+ return m_ns == other.m_ns;
+}
+
+inline bool
+Duration::operator!=(const Duration& other) const
+{
+ return m_ns != other.m_ns;
+}
+
+inline bool
+Duration::operator<(const Duration& other) const
+{
+ return m_ns < other.m_ns;
+}
+
+inline bool
+Duration::operator>(const Duration& other) const
+{
+ return m_ns > other.m_ns;
+}
+
+inline bool
+Duration::operator<=(const Duration& other) const
+{
+ return m_ns <= other.m_ns;
+}
+
+inline bool
+Duration::operator>=(const Duration& other) const
+{
+ return m_ns >= other.m_ns;
+}
+
+inline Duration
+Duration::operator+(const Duration& other) const
+{
+ return Duration(m_ns + other.m_ns);
+}
+
+inline Duration
+Duration::operator-(const Duration& other) const
+{
+ return Duration(m_ns - other.m_ns);
+}
+
+inline Duration
+Duration::operator*(double factor) const
+{
+ return Duration(factor * m_ns);
+}
+
+inline Duration
+Duration::operator/(double factor) const
+{
+ return Duration(m_ns / factor);
+}
+
+inline int64_t
+Duration::sec() const
+{
+ return m_ns / 1'000'000'000;
+}
+
+inline int64_t
+Duration::nsec() const
+{
+ return m_ns;
+}
+
+inline int32_t
+Duration::nsec_decimal_part() const
+{
+ return m_ns % 1'000'000'000;
+}
+
+} // namespace util
--- /dev/null
+// Copyright (C) 2022 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "TimePoint.hpp"
+
+#include <chrono>
+
+namespace util {
+
+TimePoint
+TimePoint::now()
+{
+ return TimePoint(0,
+ std::chrono::time_point_cast<std::chrono::nanoseconds>(
+ std::chrono::system_clock::now())
+ .time_since_epoch()
+ .count());
+}
+
+} // namespace util
--- /dev/null
+// Copyright (C) 2022 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#pragma once
+
+#include <util/Duration.hpp>
+
+#include <cstdint>
+#include <ctime>
+
+namespace util {
+
+class TimePoint
+{
+public:
+ explicit TimePoint(int64_t sec = 0, int64_t nsec = 0);
+ TimePoint(const TimePoint& other);
+ explicit TimePoint(const timespec& timespec);
+
+ TimePoint& operator=(const TimePoint& other);
+
+ static TimePoint now();
+
+ timespec to_timespec() const;
+
+ int64_t sec() const;
+ int64_t nsec() const;
+ int32_t nsec_decimal_part() const;
+
+ void set_sec(int64_t sec, uint32_t nsec = 0);
+ void set_nsec(int64_t nsec);
+
+ bool operator==(const TimePoint& other) const;
+ bool operator!=(const TimePoint& other) const;
+ bool operator<(const TimePoint& other) const;
+ bool operator>(const TimePoint& other) const;
+ bool operator<=(const TimePoint& other) const;
+ bool operator>=(const TimePoint& other) const;
+
+ TimePoint operator+(const util::Duration& duration) const;
+ TimePoint operator-(const util::Duration& duration) const;
+
+ util::Duration operator-(const TimePoint& other) const;
+
+private:
+ int64_t m_ns = 0;
+};
+
+inline TimePoint::TimePoint(int64_t sec, int64_t nsec)
+ : m_ns(1'000'000'000 * sec + nsec)
+{
+}
+
+inline TimePoint::TimePoint(const TimePoint& other) : m_ns(other.m_ns)
+{
+}
+
+inline TimePoint::TimePoint(const timespec& timespec)
+ : TimePoint(timespec.tv_sec, timespec.tv_nsec)
+{
+}
+
+inline TimePoint&
+TimePoint::operator=(const TimePoint& other)
+{
+ m_ns = other.m_ns;
+ return *this;
+}
+
+inline timespec
+TimePoint::to_timespec() const
+{
+ return {static_cast<time_t>(sec()), nsec_decimal_part()};
+}
+
+inline int64_t
+TimePoint::sec() const
+{
+ return m_ns / 1'000'000'000;
+}
+
+inline int64_t
+TimePoint::nsec() const
+{
+ return m_ns;
+}
+
+inline int32_t
+TimePoint::nsec_decimal_part() const
+{
+ return m_ns % 1'000'000'000;
+}
+
+inline void
+TimePoint::set_sec(int64_t sec, uint32_t nsec)
+{
+ m_ns = 1'000'000'000 * sec + nsec;
+}
+
+inline void
+TimePoint::set_nsec(int64_t nsec)
+{
+ m_ns = nsec;
+}
+
+inline bool
+TimePoint::operator==(const TimePoint& other) const
+{
+ return m_ns == other.m_ns;
+}
+
+inline bool
+TimePoint::operator!=(const TimePoint& other) const
+{
+ return m_ns != other.m_ns;
+}
+
+inline bool
+TimePoint::operator<(const TimePoint& other) const
+{
+ return m_ns < other.m_ns;
+}
+
+inline bool
+TimePoint::operator>(const TimePoint& other) const
+{
+ return m_ns > other.m_ns;
+}
+
+inline bool
+TimePoint::operator<=(const TimePoint& other) const
+{
+ return m_ns <= other.m_ns;
+}
+
+inline bool
+TimePoint::operator>=(const TimePoint& other) const
+{
+ return m_ns >= other.m_ns;
+}
+
+inline TimePoint
+TimePoint::operator+(const util::Duration& duration) const
+{
+ return TimePoint(0, nsec() + duration.nsec());
+}
+
+inline TimePoint
+TimePoint::operator-(const util::Duration& duration) const
+{
+ return TimePoint(0, nsec() - duration.nsec());
+}
+
+inline util::Duration
+TimePoint::operator-(const TimePoint& other) const
+{
+ return util::Duration(0, nsec() - other.nsec());
+}
+
+} // namespace util
test_util_Bytes.cpp
test_util_LockFile.cpp
test_util_TextTable.cpp
+ test_util_TimePoint.cpp
test_util_Tokenizer.cpp
test_util_XXH3_128.cpp
test_util_XXH3_64.cpp
--- /dev/null
+// Copyright (C) 2022 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include <util/TimePoint.hpp>
+
+#include <third_party/doctest.h>
+
+TEST_SUITE_BEGIN("util::TimePoint");
+
+using util::TimePoint;
+
+TEST_CASE("Basics")
+{
+ TimePoint t0(4711, 2042);
+
+ CHECK(t0.sec() == 4711);
+ CHECK(t0.nsec() == 4711000002042);
+}
+
+TEST_CASE("Conversions")
+{
+ TimePoint t0(4711, 2042);
+
+ SUBCASE("to_timespec")
+ {
+ timespec ts = t0.to_timespec();
+ CHECK(ts.tv_sec == 4711);
+ CHECK(ts.tv_nsec == 2042);
+ }
+}
+
+TEST_CASE("Comparison operators")
+{
+ TimePoint t0(1000, 0);
+ TimePoint t1(1000, 42);
+ TimePoint t2(1001, 0);
+
+ SUBCASE("operator==")
+ {
+ CHECK(t0 == t0);
+ CHECK(!(t0 == t1));
+ CHECK(!(t1 == t0));
+ CHECK(!(t0 == t2));
+ CHECK(!(t2 == t0));
+ }
+
+ SUBCASE("operator!=")
+ {
+ CHECK(!(t0 != t0));
+ CHECK(t0 != t1);
+ CHECK(t1 != t0);
+ }
+
+ SUBCASE("operator<")
+ {
+ CHECK(t0 < t1);
+ CHECK(t0 < t2);
+ CHECK(t1 < t2);
+ CHECK(!(t1 < t0));
+ CHECK(!(t2 < t0));
+ CHECK(!(t2 < t1));
+ }
+
+ SUBCASE("operator>")
+ {
+ CHECK(t2 > t1);
+ CHECK(t2 > t0);
+ CHECK(t1 > t0);
+ CHECK(!(t1 > t2));
+ CHECK(!(t0 > t2));
+ CHECK(!(t0 > t1));
+ }
+
+ SUBCASE("operator<=")
+ {
+ CHECK(t0 <= t0);
+ CHECK(t0 <= t1);
+ CHECK(t0 <= t2);
+ CHECK(!(t1 <= t0));
+ CHECK(!(t2 <= t0));
+ }
+
+ SUBCASE("operator>=")
+ {
+ CHECK(t2 >= t1);
+ CHECK(t2 >= t0);
+ CHECK(t1 >= t0);
+ CHECK(!(t1 >= t2));
+ CHECK(!(t0 >= t2));
+ }
+}
+
+TEST_CASE("Operations with duration")
+{
+ TimePoint t0(1, 2);
+ TimePoint t1(3, 17);
+
+ SUBCASE("operator-(TimePoint)")
+ {
+ CHECK(t1 - t0 == util::Duration(2, 15));
+ CHECK(t0 - t1 == util::Duration(-2, -15));
+ }
+
+ SUBCASE("operator+(Duration)")
+ {
+ CHECK(t0 + util::Duration(4, 999999999) == util::TimePoint(6, 1));
+ }
+
+ SUBCASE("operator-(Duration))")
+ {
+ auto t = t0 - util::Duration(4, 999999999);
+ CHECK(t.sec() == -3);
+ CHECK(t.nsec_decimal_part() == -999999997);
+ }
+}
+
+TEST_SUITE_END();