summaryrefslogtreecommitdiff
path: root/src/mongo/util/duration.h
diff options
context:
space:
mode:
authorAndy Schwerin <schwerin@mongodb.com>2016-05-09 16:27:06 -0400
committerAndy Schwerin <schwerin@mongodb.com>2016-05-17 11:11:57 -0400
commit76de5323b88080f852ca4c2f42593502d26c5620 (patch)
treeed2757f12d12670a25f29529c78b327bb308263d /src/mongo/util/duration.h
parent73a042328a539b51b3bf35efc16ec3245381dc40 (diff)
downloadmongo-76de5323b88080f852ca4c2f42593502d26c5620.tar.gz
SERVER-24104 Replace stdx::duration with mongo::Duration.
The mongo::Duration type does overflow checking on casts and arithmetic. This patch also moves DESTRUCTOR_GUARD out of assert_util.h into destructor_guard.h in order to break an include cycle with duration.h.
Diffstat (limited to 'src/mongo/util/duration.h')
-rw-r--r--src/mongo/util/duration.h49
1 files changed, 38 insertions, 11 deletions
diff --git a/src/mongo/util/duration.h b/src/mongo/util/duration.h
index ba4f15ec44e..6cf26b06421 100644
--- a/src/mongo/util/duration.h
+++ b/src/mongo/util/duration.h
@@ -27,13 +27,13 @@
#pragma once
-#include <chrono>
#include <cstdint>
#include <iosfwd>
#include <limits>
#include <ratio>
#include "mongo/platform/overflow_arithmetic.h"
+#include "mongo/stdx/chrono.h"
#include "mongo/stdx/type_traits.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/mongoutils/str.h"
@@ -43,8 +43,6 @@ namespace mongo {
template <typename Allocator>
class StringBuilderImpl;
-namespace x {
-
template <typename Period>
class Duration;
@@ -103,7 +101,7 @@ using HigherPrecisionDuration =
* so attempting to cast that value to Milliseconds will throw an exception.
*/
template <typename ToDuration, typename FromPeriod>
-ToDuration durationCast(const Duration<FromPeriod>& from) {
+ToDuration duration_cast(const Duration<FromPeriod>& from) {
using FromOverTo = std::ratio_divide<FromPeriod, typename ToDuration::period>;
if (ToDuration::template isHigherPrecisionThan<Duration<FromPeriod>>()) {
typename ToDuration::rep toCount;
@@ -115,6 +113,29 @@ ToDuration durationCast(const Duration<FromPeriod>& from) {
return ToDuration{from.count() / FromOverTo::den};
}
+template <typename ToDuration, typename FromRep, typename FromPeriod>
+inline ToDuration duration_cast(const stdx::chrono::duration<FromRep, FromPeriod>& d) {
+ return duration_cast<ToDuration>(Duration<FromPeriod>{d.count()});
+}
+
+/**
+ * Convenience method for reading the count of a duration with specified units.
+ *
+ * Use when logging or comparing to integers, to ensure that you're using
+ * the units you intend.
+ *
+ * E.g., log() << durationCount<Seconds>(some duration) << " seconds";
+ */
+template <typename DOut, typename DIn>
+inline long long durationCount(DIn d) {
+ return duration_cast<DOut>(d).count();
+}
+
+template <typename DOut, typename RepIn, typename PeriodIn>
+inline long long durationCount(const stdx::chrono::duration<RepIn, PeriodIn>& d) {
+ return durationCount<DOut>(Duration<PeriodIn>{d.count()});
+}
+
/**
* Type representing a duration using a 64-bit counter.
*
@@ -197,12 +218,14 @@ public:
template <typename Rep2>
constexpr explicit Duration(const Rep2& r)
: _count(r) {
- static_assert(std::is_integral<Rep2>::value && std::is_signed<Rep2>::value,
- "Durations must be constructed from values of signed integral type");
+ static_assert(std::is_integral<Rep2>::value &&
+ (std::is_signed<Rep2>::value || sizeof(Rep2) < sizeof(rep)),
+ "Durations must be constructed from values of integral type that are "
+ "representable as 64-bit signed integers");
}
/**
- * Constructs a higher-precision duration from a lower-precision one, as by durationCast.
+ * Constructs a higher-precision duration from a lower-precision one, as by duration_cast.
*
* Throws a UserException if "from" is out of the range of this duration type.
*
@@ -210,18 +233,23 @@ public:
* this constructor.
*/
template <typename FromPeriod>
- /*implicit*/ Duration(const Duration<FromPeriod>& from) : Duration(durationCast<Duration>(from)) {
+ /*implicit*/ Duration(const Duration<FromPeriod>& from)
+ : Duration(duration_cast<Duration>(from)) {
static_assert(!isLowerPrecisionThan<Duration<FromPeriod>>(),
"Use duration_cast to convert from higher precision Duration types to lower "
"precision ones");
}
- constexpr operator stdx::chrono::duration<int64_t, period>() const {
- return stdx::chrono::duration<int64_t, period>{_count};
+ stdx::chrono::system_clock::duration toSystemDuration() const {
+ using SystemDuration = stdx::chrono::system_clock::duration;
+ return SystemDuration{duration_cast<Duration<SystemDuration::period>>(*this).count()};
}
/**
* Returns the number of periods represented by this duration.
+ *
+ * It is better to use durationCount<DesiredDurationType>(value), since it makes the unit of the
+ * count clear at the call site.
*/
constexpr rep count() const {
return _count;
@@ -411,5 +439,4 @@ Duration<Period> operator/(Duration<Period> d, const Rep2& scale) {
return d;
}
-} // namespace x
} // namespace mongo