From: Takatoshi Kondo <redboltz@gmail.com>
Date: Sun, 14 Jun 2020 18:46:44 +0900
X-Dgit-Generated: 3.3.0-2 002d626690e3c85586bb509f8f257d45a703a48e
Subject: Improved clock adaptor.


---

--- msgpack-c-3.3.0.orig/include/msgpack/v1/adaptor/cpp11/chrono.hpp
+++ msgpack-c-3.3.0/include/msgpack/v1/adaptor/cpp11/chrono.hpp
@@ -25,299 +25,187 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
 
 namespace adaptor {
 
-namespace detail {
-
-template <typename T>
-typename T::time_point chrono_as(msgpack::object const& o) {
-    if(o.type != msgpack::type::EXT) { throw msgpack::type_error(); }
-    if(o.via.ext.type() != -1) { throw msgpack::type_error(); }
-    typename T::time_point tp;
-    switch(o.via.ext.size) {
-    case 4: {
-        uint32_t sec;
-        _msgpack_load32(uint32_t, o.via.ext.data(), &sec);
-        tp += std::chrono::seconds(sec);
-    } break;
-    case 8: {
-        uint64_t value;
-        _msgpack_load64(uint64_t, o.via.ext.data(), &value);
-        uint32_t nanosec = static_cast<uint32_t>(value >> 34);
-        uint64_t sec = value & 0x00000003ffffffffLL;
-        tp += std::chrono::duration_cast<typename T::duration>(
-            std::chrono::nanoseconds(nanosec));
-        tp += std::chrono::seconds(sec);
-    } break;
-    case 12: {
-        uint32_t nanosec;
-        _msgpack_load32(uint32_t, o.via.ext.data(), &nanosec);
-        int64_t sec;
-        _msgpack_load64(int64_t, o.via.ext.data() + 4, &sec);
-        tp += std::chrono::duration_cast<typename T::duration>(
-            std::chrono::nanoseconds(nanosec));
-        tp += std::chrono::seconds(sec);
-    } break;
-    default:
-        throw msgpack::type_error();
+template <typename Clock>
+struct as<std::chrono::time_point<Clock>> {
+    typename std::chrono::time_point<Clock> operator()(msgpack::object const& o) const {
+        using duration_t = typename std::chrono::time_point<Clock>::duration;
+        if(o.type != msgpack::type::EXT) { throw msgpack::type_error(); }
+        if(o.via.ext.type() != -1) { throw msgpack::type_error(); }
+        std::chrono::time_point<Clock> tp;
+        switch(o.via.ext.size) {
+        case 4: {
+            uint32_t sec;
+            _msgpack_load32(uint32_t, o.via.ext.data(), &sec);
+            tp += std::chrono::seconds(sec);
+        } break;
+        case 8: {
+            uint64_t value;
+            _msgpack_load64(uint64_t, o.via.ext.data(), &value);
+            uint32_t nanosec = static_cast<uint32_t>(value >> 34);
+            uint64_t sec = value & 0x00000003ffffffffLL;
+            tp += std::chrono::duration_cast<duration_t>(
+                std::chrono::nanoseconds(nanosec));
+            tp += std::chrono::seconds(sec);
+        } break;
+        case 12: {
+            uint32_t nanosec;
+            _msgpack_load32(uint32_t, o.via.ext.data(), &nanosec);
+            int64_t sec;
+            _msgpack_load64(int64_t, o.via.ext.data() + 4, &sec);
+            tp += std::chrono::duration_cast<duration_t>(
+                std::chrono::nanoseconds(nanosec));
+            tp += std::chrono::seconds(sec);
+        } break;
+        default:
+            throw msgpack::type_error();
+        }
+        return tp;
     }
-    return tp;
-}
+};
 
-template <typename T>
-msgpack::object const& chrono_convert(msgpack::object const& o, typename T::time_point& v) {
-    if(o.type != msgpack::type::EXT) { throw msgpack::type_error(); }
-    if(o.via.ext.type() != -1) { throw msgpack::type_error(); }
-    typename T::time_point tp;
-    switch(o.via.ext.size) {
-    case 4: {
-        uint32_t sec;
-        _msgpack_load32(uint32_t, o.via.ext.data(), &sec);
-        tp += std::chrono::seconds(sec);
-        v = tp;
-    } break;
-    case 8: {
-        uint64_t value;
-        _msgpack_load64(uint64_t, o.via.ext.data(), &value);
-        uint32_t nanosec = static_cast<uint32_t>(value >> 34);
-        uint64_t sec = value & 0x00000003ffffffffLL;
-        tp += std::chrono::duration_cast<typename T::duration>(
-            std::chrono::nanoseconds(nanosec));
-        tp += std::chrono::seconds(sec);
-        v = tp;
-    } break;
-    case 12: {
-        uint32_t nanosec;
-        _msgpack_load32(uint32_t, o.via.ext.data(), &nanosec);
-        int64_t sec;
-        _msgpack_load64(int64_t, o.via.ext.data() + 4, &sec);
-        tp += std::chrono::duration_cast<typename T::duration>(
-            std::chrono::nanoseconds(nanosec));
-        tp += std::chrono::seconds(sec);
-        v = tp;
-    } break;
-    default:
-        throw msgpack::type_error();
+template <typename Clock>
+struct convert<std::chrono::time_point<Clock>> {
+    msgpack::object const& operator()(msgpack::object const& o, std::chrono::time_point<Clock>& v) const {
+        using duration_t = typename std::chrono::time_point<Clock>::duration;
+        if(o.type != msgpack::type::EXT) { throw msgpack::type_error(); }
+        if(o.via.ext.type() != -1) { throw msgpack::type_error(); }
+        std::chrono::time_point<Clock> tp;
+        switch(o.via.ext.size) {
+        case 4: {
+            uint32_t sec;
+            _msgpack_load32(uint32_t, o.via.ext.data(), &sec);
+            tp += std::chrono::seconds(sec);
+            v = tp;
+        } break;
+        case 8: {
+            uint64_t value;
+            _msgpack_load64(uint64_t, o.via.ext.data(), &value);
+            uint32_t nanosec = static_cast<uint32_t>(value >> 34);
+            uint64_t sec = value & 0x00000003ffffffffLL;
+            tp += std::chrono::duration_cast<duration_t>(
+                std::chrono::nanoseconds(nanosec));
+            tp += std::chrono::seconds(sec);
+            v = tp;
+        } break;
+        case 12: {
+            uint32_t nanosec;
+            _msgpack_load32(uint32_t, o.via.ext.data(), &nanosec);
+            int64_t sec;
+            _msgpack_load64(int64_t, o.via.ext.data() + 4, &sec);
+            tp += std::chrono::duration_cast<duration_t>(
+                std::chrono::nanoseconds(nanosec));
+            tp += std::chrono::seconds(sec);
+            v = tp;
+        } break;
+        default:
+            throw msgpack::type_error();
+        }
+        return o;
     }
-    return o;
-}
-
-template <typename T, typename Stream>
-msgpack::packer<Stream>& chrono_pack(msgpack::packer<Stream>& o, const typename T::time_point& v) {
-    int64_t count = static_cast<int64_t>(v.time_since_epoch().count());
-
-    int64_t nano_num =
-        T::duration::period::ratio::num *
-        (1000000000 / T::duration::period::ratio::den);
+};
 
-    int64_t nanosec = count % (1000000000 / nano_num) * nano_num;
-    int64_t sec = 0;
-    if (nanosec < 0) {
-        nanosec = 1000000000 + nanosec;
-        --sec;
-    }
-    sec += count
-        * T::duration::period::ratio::num
-        / T::duration::period::ratio::den;
-    if ((sec >> 34) == 0) {
-        uint64_t data64 = (static_cast<uint64_t>(nanosec) << 34) | static_cast<uint64_t>(sec);
-        if ((data64 & 0xffffffff00000000L) == 0) {
-            // timestamp 32
-            o.pack_ext(4, -1);
-            uint32_t data32 = static_cast<uint32_t>(data64);
-            char buf[4];
-            _msgpack_store32(buf, data32);
-            o.pack_ext_body(buf, 4);
+template <typename Clock>
+struct pack<std::chrono::time_point<Clock>> {
+    template <typename Stream>
+    msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, std::chrono::time_point<Clock> const& v) const {
+        using duration_t = typename std::chrono::time_point<Clock>::duration;
+        int64_t count = static_cast<int64_t>(v.time_since_epoch().count());
+
+        int64_t nano_num =
+            duration_t::period::ratio::num *
+            (1000000000 / duration_t::period::ratio::den);
+
+        int64_t nanosec = count % (1000000000 / nano_num) * nano_num;
+        int64_t sec = 0;
+        if (nanosec < 0) {
+            nanosec = 1000000000 + nanosec;
+            --sec;
+        }
+        sec += count
+            * duration_t::period::ratio::num
+            / duration_t::period::ratio::den;
+        if ((sec >> 34) == 0) {
+            uint64_t data64 = (static_cast<uint64_t>(nanosec) << 34) | static_cast<uint64_t>(sec);
+            if ((data64 & 0xffffffff00000000L) == 0) {
+                // timestamp 32
+                o.pack_ext(4, -1);
+                uint32_t data32 = static_cast<uint32_t>(data64);
+                char buf[4];
+                _msgpack_store32(buf, data32);
+                o.pack_ext_body(buf, 4);
+            }
+            else {
+                // timestamp 64
+                o.pack_ext(8, -1);
+                char buf[8];
+                _msgpack_store64(buf, data64);
+                o.pack_ext_body(buf, 8);
+            }
         }
         else {
-            // timestamp 64
-            o.pack_ext(8, -1);
-            char buf[8];
-            _msgpack_store64(buf, data64);
-            o.pack_ext_body(buf, 8);
+            // timestamp 96
+            o.pack_ext(12, -1);
+            char buf[12];
+            _msgpack_store32(&buf[0], static_cast<uint32_t>(nanosec));
+            _msgpack_store64(&buf[4], sec);
+            o.pack_ext_body(buf, 12);
         }
+        return o;
     }
-    else {
-        // timestamp 96
-        o.pack_ext(12, -1);
-        char buf[12];
-        _msgpack_store32(&buf[0], static_cast<uint32_t>(nanosec));
-        _msgpack_store64(&buf[4], sec);
-        o.pack_ext_body(buf, 12);
-    }
-    return o;
-}
+};
 
-template <typename T>
-void chrono_object_with_zone(msgpack::object::with_zone& o, const typename T::time_point& v) {
-    int64_t count = static_cast<int64_t>(v.time_since_epoch().count());
+template <typename Clock>
+struct object_with_zone<std::chrono::time_point<Clock>> {
+    void operator()(msgpack::object::with_zone& o, const std::chrono::time_point<Clock>& v) const {
+        using duration_t = typename std::chrono::time_point<Clock>::duration;
+        int64_t count = static_cast<int64_t>(v.time_since_epoch().count());
 
-    int64_t nano_num =
-        T::duration::period::ratio::num *
-        (1000000000 / T::duration::period::ratio::den);
+        int64_t nano_num =
+            duration_t::period::ratio::num *
+            (1000000000 / duration_t::period::ratio::den);
 
-    int64_t nanosec = count % (1000000000 / nano_num) * nano_num;
-    int64_t sec = 0;
-    if (nanosec < 0) {
-        nanosec = 1000000000 + nanosec;
-        --sec;
-    }
-    sec += count
-        * T::duration::period::ratio::num
-        / T::duration::period::ratio::den;
-    if ((sec >> 34) == 0) {
-        uint64_t data64 = (static_cast<uint64_t>(nanosec) << 34) | static_cast<uint64_t>(sec);
-        if ((data64 & 0xffffffff00000000L) == 0) {
-            // timestamp 32
-            o.type = msgpack::type::EXT;
-            o.via.ext.size = 4;
-            char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
-            p[0] = static_cast<char>(-1);
-            uint32_t data32 = static_cast<uint32_t>(data64);
-            _msgpack_store32(&p[1], data32);
-            o.via.ext.ptr = p;
+        int64_t nanosec = count % (1000000000 / nano_num) * nano_num;
+        int64_t sec = 0;
+        if (nanosec < 0) {
+            nanosec = 1000000000 + nanosec;
+            --sec;
+        }
+        sec += count
+            * duration_t::period::ratio::num
+            / duration_t::period::ratio::den;
+        if ((sec >> 34) == 0) {
+            uint64_t data64 = (static_cast<uint64_t>(nanosec) << 34) | static_cast<uint64_t>(sec);
+            if ((data64 & 0xffffffff00000000L) == 0) {
+                // timestamp 32
+                o.type = msgpack::type::EXT;
+                o.via.ext.size = 4;
+                char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
+                p[0] = static_cast<char>(-1);
+                uint32_t data32 = static_cast<uint32_t>(data64);
+                _msgpack_store32(&p[1], data32);
+                o.via.ext.ptr = p;
+            }
+            else {
+                // timestamp 64
+                o.type = msgpack::type::EXT;
+                o.via.ext.size = 8;
+                char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
+                p[0] = static_cast<char>(-1);
+                _msgpack_store64(&p[1], data64);
+                o.via.ext.ptr = p;
+            }
         }
         else {
-            // timestamp 64
+            // timestamp 96
             o.type = msgpack::type::EXT;
-            o.via.ext.size = 8;
+            o.via.ext.size = 12;
             char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
             p[0] = static_cast<char>(-1);
-            _msgpack_store64(&p[1], data64);
+            _msgpack_store32(&p[1], static_cast<uint32_t>(nanosec));
+            _msgpack_store64(&p[1 + 4], sec);
             o.via.ext.ptr = p;
         }
     }
-    else {
-        // timestamp 96
-        o.type = msgpack::type::EXT;
-        o.via.ext.size = 12;
-        char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
-        p[0] = static_cast<char>(-1);
-        _msgpack_store32(&p[1], static_cast<uint32_t>(nanosec));
-        _msgpack_store64(&p[1 + 4], sec);
-        o.via.ext.ptr = p;
-    }
-}
-
-} // namespace detail
-
-template <>
-struct as<std::chrono::system_clock::time_point> {
-    typename std::chrono::system_clock::time_point operator()(msgpack::object const& o) const {
-        return detail::chrono_as<std::chrono::system_clock>(o);
-    }
-};
-
-template <>
-struct convert<std::chrono::system_clock::time_point> {
-    msgpack::object const& operator()(msgpack::object const& o, std::chrono::system_clock::time_point& v) const {
-        return detail::chrono_convert<std::chrono::system_clock>(o, v);
-    }
-};
-
-template <>
-struct pack<std::chrono::system_clock::time_point> {
-    template <typename Stream>
-    msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::chrono::system_clock::time_point& v) const {
-        return detail::chrono_pack<std::chrono::system_clock>(o, v);
-    }
-};
-
-template <>
-struct object_with_zone<std::chrono::system_clock::time_point> {
-    void operator()(msgpack::object::with_zone& o, const std::chrono::system_clock::time_point& v) const {
-        detail::chrono_object_with_zone<std::chrono::system_clock>(o, v);
-    }
-};
-
-
-template <>
-struct as<std::chrono::steady_clock::time_point> {
-    typename std::chrono::steady_clock::time_point operator()(msgpack::object const& o) const {
-        return detail::chrono_as<std::chrono::steady_clock>(o);
-    }
-};
-
-template <>
-struct convert<std::chrono::steady_clock::time_point> {
-    msgpack::object const& operator()(msgpack::object const& o, std::chrono::steady_clock::time_point& v) const {
-        return detail::chrono_convert<std::chrono::steady_clock>(o, v);
-    }
-};
-
-template <>
-struct pack<std::chrono::steady_clock::time_point> {
-    template <typename Stream>
-    msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::chrono::steady_clock::time_point& v) const {
-        return detail::chrono_pack<std::chrono::steady_clock>(o, v);
-    }
-};
-
-template <>
-struct object_with_zone<std::chrono::steady_clock::time_point> {
-    void operator()(msgpack::object::with_zone& o, const std::chrono::steady_clock::time_point& v) const {
-        detail::chrono_object_with_zone<std::chrono::steady_clock>(o, v);
-    }
-};
-
-
-template <>
-struct as<
-    std::chrono::high_resolution_clock::time_point,
-    typename std::conditional<
-        !std::is_same<std::chrono::high_resolution_clock, std::chrono::system_clock>::value &&
-        !std::is_same<std::chrono::high_resolution_clock, std::chrono::steady_clock>::value,
-        void,
-        std::nullptr_t
-    >::type
-> {
-    typename std::chrono::high_resolution_clock::time_point operator()(msgpack::object const& o) const {
-        return detail::chrono_as<std::chrono::high_resolution_clock>(o);
-    }
-};
-
-template <>
-struct convert<
-    std::chrono::high_resolution_clock::time_point,
-    typename std::conditional<
-        !std::is_same<std::chrono::high_resolution_clock, std::chrono::system_clock>::value &&
-        !std::is_same<std::chrono::high_resolution_clock, std::chrono::steady_clock>::value,
-        void,
-        std::nullptr_t
-    >::type
-> {
-    msgpack::object const& operator()(msgpack::object const& o, std::chrono::high_resolution_clock::time_point& v) const {
-        return detail::chrono_convert<std::chrono::high_resolution_clock>(o, v);
-    }
-};
-
-template <>
-struct pack<
-    std::chrono::high_resolution_clock::time_point,
-    typename std::conditional<
-        !std::is_same<std::chrono::high_resolution_clock, std::chrono::system_clock>::value &&
-        !std::is_same<std::chrono::high_resolution_clock, std::chrono::steady_clock>::value,
-        void,
-        std::nullptr_t
-    >::type
-> {
-    template <typename Stream>
-    msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, const std::chrono::high_resolution_clock::time_point& v) const {
-        return detail::chrono_pack<std::chrono::high_resolution_clock>(o, v);
-    }
-};
-
-template <>
-struct object_with_zone<
-    std::chrono::high_resolution_clock::time_point,
-    typename std::conditional<
-        !std::is_same<std::chrono::high_resolution_clock, std::chrono::system_clock>::value &&
-        !std::is_same<std::chrono::high_resolution_clock, std::chrono::steady_clock>::value,
-        void,
-        std::nullptr_t
-    >::type
-> {
-    void operator()(msgpack::object::with_zone& o, const std::chrono::high_resolution_clock::time_point& v) const {
-        detail::chrono_object_with_zone<std::chrono::high_resolution_clock>(o, v);
-    }
 };
 
 } // namespace adaptor
