summaryrefslogtreecommitdiffstats
path: root/src/include/encoding.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/include/encoding.h49
1 files changed, 40 insertions, 9 deletions
diff --git a/src/include/encoding.h b/src/include/encoding.h
index 40ba9d39c..08c67c33e 100644
--- a/src/include/encoding.h
+++ b/src/include/encoding.h
@@ -14,6 +14,7 @@
#ifndef CEPH_ENCODING_H
#define CEPH_ENCODING_H
+#include <concepts>
#include <set>
#include <map>
#include <deque>
@@ -322,10 +323,11 @@ inline void decode_nohead(int len, bufferlist& s, bufferlist::const_iterator& p)
p.copy(len, s);
}
-// Time, since the templates are defined in std::chrono
+// Time, since the templates are defined in std::chrono. The default encodings
+// for time_point and duration are backward-compatible with utime_t, but
+// truncate seconds to 32 bits so are not guaranteed to round-trip.
-template<typename Clock, typename Duration,
- typename std::enable_if_t<converts_to_timespec_v<Clock>>* = nullptr>
+template<clock_with_timespec Clock, typename Duration>
void encode(const std::chrono::time_point<Clock, Duration>& t,
ceph::bufferlist &bl) {
auto ts = Clock::to_timespec(t);
@@ -336,8 +338,7 @@ void encode(const std::chrono::time_point<Clock, Duration>& t,
encode(ns, bl);
}
-template<typename Clock, typename Duration,
- typename std::enable_if_t<converts_to_timespec_v<Clock>>* = nullptr>
+template<clock_with_timespec Clock, typename Duration>
void decode(std::chrono::time_point<Clock, Duration>& t,
bufferlist::const_iterator& p) {
uint32_t s;
@@ -351,8 +352,7 @@ void decode(std::chrono::time_point<Clock, Duration>& t,
t = Clock::from_timespec(ts);
}
-template<typename Rep, typename Period,
- typename std::enable_if_t<std::is_integral_v<Rep>>* = nullptr>
+template<std::integral Rep, typename Period>
void encode(const std::chrono::duration<Rep, Period>& d,
ceph::bufferlist &bl) {
using namespace std::chrono;
@@ -362,8 +362,7 @@ void encode(const std::chrono::duration<Rep, Period>& d,
encode(ns, bl);
}
-template<typename Rep, typename Period,
- typename std::enable_if_t<std::is_integral_v<Rep>>* = nullptr>
+template<std::integral Rep, typename Period>
void decode(std::chrono::duration<Rep, Period>& d,
bufferlist::const_iterator& p) {
int32_t s;
@@ -373,6 +372,38 @@ void decode(std::chrono::duration<Rep, Period>& d,
d = std::chrono::seconds(s) + std::chrono::nanoseconds(ns);
}
+// Provide encodings for chrono::time_point and duration that use
+// the underlying representation so are guaranteed to round-trip.
+
+template <std::integral Rep, typename Period>
+void round_trip_encode(const std::chrono::duration<Rep, Period>& d,
+ ceph::bufferlist &bl) {
+ const Rep r = d.count();
+ encode(r, bl);
+}
+
+template <std::integral Rep, typename Period>
+void round_trip_decode(std::chrono::duration<Rep, Period>& d,
+ bufferlist::const_iterator& p) {
+ Rep r;
+ decode(r, p);
+ d = std::chrono::duration<Rep, Period>(r);
+}
+
+template <typename Clock, typename Duration>
+void round_trip_encode(const std::chrono::time_point<Clock, Duration>& t,
+ ceph::bufferlist &bl) {
+ round_trip_encode(t.time_since_epoch(), bl);
+}
+
+template <typename Clock, typename Duration>
+void round_trip_decode(std::chrono::time_point<Clock, Duration>& t,
+ bufferlist::const_iterator& p) {
+ Duration dur;
+ round_trip_decode(dur, p);
+ t = std::chrono::time_point<Clock, Duration>(dur);
+}
+
// -----------------------------
// STL container types