mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-06-26 14:34:02 +02:00
Merge pull request #1076 from uyha/chrono-no-boost
remove dependency on boost in chrono.hpp
This commit is contained in:
commit
1fb1dad6bc
5
.gitignore
vendored
5
.gitignore
vendored
@ -49,3 +49,8 @@ Makefile
|
|||||||
/test/streaming_c
|
/test/streaming_c
|
||||||
/test/version
|
/test/version
|
||||||
/test/zone
|
/test/zone
|
||||||
|
|
||||||
|
build
|
||||||
|
*-build
|
||||||
|
.cache
|
||||||
|
compile_commands.json
|
||||||
|
@ -37,9 +37,7 @@
|
|||||||
#include "adaptor/cpp11/array_char.hpp"
|
#include "adaptor/cpp11/array_char.hpp"
|
||||||
#include "adaptor/cpp11/array_unsigned_char.hpp"
|
#include "adaptor/cpp11/array_unsigned_char.hpp"
|
||||||
|
|
||||||
#if !defined(MSGPACK_NO_BOOST)
|
|
||||||
#include "adaptor/cpp11/chrono.hpp"
|
#include "adaptor/cpp11/chrono.hpp"
|
||||||
#endif // !defined(MSGPACK_NO_BOOST)
|
|
||||||
|
|
||||||
#include "adaptor/cpp11/forward_list.hpp"
|
#include "adaptor/cpp11/forward_list.hpp"
|
||||||
#include "adaptor/cpp11/reference_wrapper.hpp"
|
#include "adaptor/cpp11/reference_wrapper.hpp"
|
||||||
|
@ -11,17 +11,14 @@
|
|||||||
#ifndef MSGPACK_V1_TYPE_CPP11_CHRONO_HPP
|
#ifndef MSGPACK_V1_TYPE_CPP11_CHRONO_HPP
|
||||||
#define MSGPACK_V1_TYPE_CPP11_CHRONO_HPP
|
#define MSGPACK_V1_TYPE_CPP11_CHRONO_HPP
|
||||||
|
|
||||||
#if !defined(MSGPACK_NO_BOOST)
|
|
||||||
|
|
||||||
#include "msgpack/versioning.hpp"
|
#include "msgpack/versioning.hpp"
|
||||||
#include "msgpack/adaptor/adaptor_base.hpp"
|
#include "msgpack/adaptor/adaptor_base.hpp"
|
||||||
#include "msgpack/object.hpp"
|
#include "msgpack/object.hpp"
|
||||||
#include "msgpack/adaptor/check_container_size.hpp"
|
#include "msgpack/adaptor/check_container_size.hpp"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
#include <boost/numeric/conversion/cast.hpp>
|
|
||||||
|
|
||||||
namespace msgpack {
|
namespace msgpack {
|
||||||
|
|
||||||
/// @cond
|
/// @cond
|
||||||
@ -30,6 +27,113 @@ MSGPACK_API_VERSION_NAMESPACE(v1) {
|
|||||||
|
|
||||||
namespace adaptor {
|
namespace adaptor {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template <
|
||||||
|
typename Target,
|
||||||
|
typename Source,
|
||||||
|
bool target_is_signed = std::is_signed<Target>::value,
|
||||||
|
bool source_is_signed = std::is_signed<Source>::value,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
std::is_integral<Target>::value &&
|
||||||
|
std::is_integral<Source>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
struct would_underflow {
|
||||||
|
// The default case includes the cases that Source being unsigned, and since Source
|
||||||
|
// is unsigned, no underflow can happen
|
||||||
|
would_underflow(Source) : value{false} {}
|
||||||
|
bool value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Target, typename Source>
|
||||||
|
struct would_underflow<Target, Source, false, true> {
|
||||||
|
// When Source is signed and Target is unsigned, we only need to compare with 0 to
|
||||||
|
// detect underflow, this works correctly and also avoids warnings from the compiler
|
||||||
|
would_underflow(Source source) : value{source < 0} {}
|
||||||
|
bool value;
|
||||||
|
};
|
||||||
|
template <typename Target, typename Source>
|
||||||
|
struct would_underflow<Target, Source, true, true> {
|
||||||
|
// When Source and Target are signed, the promotion rules apply sensibly so we do
|
||||||
|
// not need to do anything
|
||||||
|
would_underflow(Source source)
|
||||||
|
: value{source < std::numeric_limits<Target>::min()} {}
|
||||||
|
bool value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename Target,
|
||||||
|
typename Source,
|
||||||
|
bool target_is_signed = std::is_signed<Target>::value,
|
||||||
|
bool source_is_signed = std::is_signed<Source>::value,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
std::is_integral<Target>::value &&
|
||||||
|
std::is_integral<Source>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
struct would_overflow {
|
||||||
|
// The default case is Source and Target having the same signedness, the promotion
|
||||||
|
// rule also apply sensibly here so nothing special needs to be done
|
||||||
|
would_overflow(Source source)
|
||||||
|
: value{source > std::numeric_limits<Target>::max()} {}
|
||||||
|
bool value;
|
||||||
|
};
|
||||||
|
template <typename Target, typename Source>
|
||||||
|
struct would_overflow <Target, Source, false, true> {
|
||||||
|
// When Target is unsigned and Source is signed, we cannot rely on the promotion
|
||||||
|
// rule.
|
||||||
|
would_overflow(Source source)
|
||||||
|
: value{
|
||||||
|
sizeof(Target) >= sizeof(Source)
|
||||||
|
// Given Source is signed, Target being unsigned and having at least the
|
||||||
|
// same size makes impossible to overflow
|
||||||
|
? false
|
||||||
|
// Source being larger than Target makes it safe to cast the maximum value
|
||||||
|
// of Target to Source
|
||||||
|
: source > static_cast<Source>(std::numeric_limits<Target>::max())
|
||||||
|
} {}
|
||||||
|
bool value;
|
||||||
|
};
|
||||||
|
template <typename Target, typename Source>
|
||||||
|
struct would_overflow <Target, Source, true, false> {
|
||||||
|
// When Target is signed and Source is unsigned, we cannot rely on the promotion
|
||||||
|
// rule.
|
||||||
|
would_overflow(Source source)
|
||||||
|
: value{
|
||||||
|
sizeof(Target) > sizeof(Source)
|
||||||
|
// Target being larger than Source makes it impossible to overflow
|
||||||
|
? false
|
||||||
|
// Source being unsigned and having at least the size of Target makes it
|
||||||
|
// safe to cast the maximum value of Target to Source
|
||||||
|
: source > static_cast<Source>(std::numeric_limits<Target>::max())
|
||||||
|
} {}
|
||||||
|
bool value;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <
|
||||||
|
typename Target,
|
||||||
|
typename Source,
|
||||||
|
typename = typename std::enable_if<
|
||||||
|
std::is_integral<Target>::value &&
|
||||||
|
std::is_integral<Source>::value
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
Target integral_cast(Source source) {
|
||||||
|
if (would_underflow<Target, Source>(source).value) {
|
||||||
|
throw std::underflow_error{
|
||||||
|
"casting from Source to Target causes an underflow error"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if(would_overflow<Target, Source>(source).value) {
|
||||||
|
throw std::overflow_error{
|
||||||
|
"casting from Source to Target causes an overflow error"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<Target>(source);
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
template <typename Clock, typename Duration>
|
template <typename Clock, typename Duration>
|
||||||
struct as<std::chrono::time_point<Clock, Duration>> {
|
struct as<std::chrono::time_point<Clock, Duration>> {
|
||||||
typename std::chrono::time_point<Clock, Duration> operator()(msgpack::object const& o) const {
|
typename std::chrono::time_point<Clock, Duration> operator()(msgpack::object const& o) const {
|
||||||
@ -45,7 +149,7 @@ struct as<std::chrono::time_point<Clock, Duration>> {
|
|||||||
case 8: {
|
case 8: {
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
_msgpack_load64(uint64_t, o.via.ext.data(), &value);
|
_msgpack_load64(uint64_t, o.via.ext.data(), &value);
|
||||||
uint32_t nanosec = boost::numeric_cast<uint32_t>(value >> 34);
|
uint32_t nanosec = detail::integral_cast<uint32_t>(value >> 34);
|
||||||
uint64_t sec = value & 0x00000003ffffffffLL;
|
uint64_t sec = value & 0x00000003ffffffffLL;
|
||||||
tp += std::chrono::duration_cast<Duration>(
|
tp += std::chrono::duration_cast<Duration>(
|
||||||
std::chrono::nanoseconds(nanosec));
|
std::chrono::nanoseconds(nanosec));
|
||||||
@ -69,7 +173,7 @@ struct as<std::chrono::time_point<Clock, Duration>> {
|
|||||||
else {
|
else {
|
||||||
++sec;
|
++sec;
|
||||||
tp += std::chrono::seconds(sec);
|
tp += std::chrono::seconds(sec);
|
||||||
int64_t ns = boost::numeric_cast<int64_t>(nanosec) - 1000000000L;
|
int64_t ns = detail::integral_cast<int64_t>(nanosec) - 1000000000L;
|
||||||
tp += std::chrono::duration_cast<Duration>(
|
tp += std::chrono::duration_cast<Duration>(
|
||||||
std::chrono::nanoseconds(ns));
|
std::chrono::nanoseconds(ns));
|
||||||
}
|
}
|
||||||
@ -98,7 +202,7 @@ struct convert<std::chrono::time_point<Clock, Duration>> {
|
|||||||
case 8: {
|
case 8: {
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
_msgpack_load64(uint64_t, o.via.ext.data(), &value);
|
_msgpack_load64(uint64_t, o.via.ext.data(), &value);
|
||||||
uint32_t nanosec = boost::numeric_cast<uint32_t>(value >> 34);
|
uint32_t nanosec = detail::integral_cast<uint32_t>(value >> 34);
|
||||||
uint64_t sec = value & 0x00000003ffffffffLL;
|
uint64_t sec = value & 0x00000003ffffffffLL;
|
||||||
tp += std::chrono::duration_cast<Duration>(
|
tp += std::chrono::duration_cast<Duration>(
|
||||||
std::chrono::nanoseconds(nanosec));
|
std::chrono::nanoseconds(nanosec));
|
||||||
@ -123,7 +227,7 @@ struct convert<std::chrono::time_point<Clock, Duration>> {
|
|||||||
else {
|
else {
|
||||||
++sec;
|
++sec;
|
||||||
tp += std::chrono::seconds(sec);
|
tp += std::chrono::seconds(sec);
|
||||||
int64_t ns = boost::numeric_cast<int64_t>(nanosec) - 1000000000L;
|
int64_t ns = detail::integral_cast<int64_t>(nanosec) - 1000000000L;
|
||||||
tp += std::chrono::duration_cast<Duration>(
|
tp += std::chrono::duration_cast<Duration>(
|
||||||
std::chrono::nanoseconds(ns));
|
std::chrono::nanoseconds(ns));
|
||||||
}
|
}
|
||||||
@ -142,7 +246,7 @@ template <typename Clock, typename Duration>
|
|||||||
struct pack<std::chrono::time_point<Clock, Duration>> {
|
struct pack<std::chrono::time_point<Clock, Duration>> {
|
||||||
template <typename Stream>
|
template <typename Stream>
|
||||||
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, std::chrono::time_point<Clock, Duration> const& v) const {
|
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, std::chrono::time_point<Clock, Duration> const& v) const {
|
||||||
int64_t count = boost::numeric_cast<int64_t>(v.time_since_epoch().count());
|
int64_t count = detail::integral_cast<int64_t>(v.time_since_epoch().count());
|
||||||
int64_t nano_num =
|
int64_t nano_num =
|
||||||
Duration::period::ratio::num *
|
Duration::period::ratio::num *
|
||||||
(1000000000L / Duration::period::ratio::den);
|
(1000000000L / Duration::period::ratio::den);
|
||||||
@ -158,11 +262,11 @@ struct pack<std::chrono::time_point<Clock, Duration>> {
|
|||||||
/ Duration::period::ratio::den;
|
/ Duration::period::ratio::den;
|
||||||
|
|
||||||
if ((sec >> 34) == 0) {
|
if ((sec >> 34) == 0) {
|
||||||
uint64_t data64 = (boost::numeric_cast<uint64_t>(nanosec) << 34) | boost::numeric_cast<uint64_t>(sec);
|
uint64_t data64 = (detail::integral_cast<uint64_t>(nanosec) << 34) | detail::integral_cast<uint64_t>(sec);
|
||||||
if ((data64 & 0xffffffff00000000L) == 0) {
|
if ((data64 & 0xffffffff00000000L) == 0) {
|
||||||
// timestamp 32
|
// timestamp 32
|
||||||
o.pack_ext(4, -1);
|
o.pack_ext(4, -1);
|
||||||
uint32_t data32 = boost::numeric_cast<uint32_t>(data64);
|
uint32_t data32 = detail::integral_cast<uint32_t>(data64);
|
||||||
char buf[4];
|
char buf[4];
|
||||||
_msgpack_store32(buf, data32);
|
_msgpack_store32(buf, data32);
|
||||||
o.pack_ext_body(buf, 4);
|
o.pack_ext_body(buf, 4);
|
||||||
@ -181,7 +285,7 @@ struct pack<std::chrono::time_point<Clock, Duration>> {
|
|||||||
char buf[12];
|
char buf[12];
|
||||||
|
|
||||||
|
|
||||||
_msgpack_store32(&buf[0], boost::numeric_cast<uint32_t>(nanosec));
|
_msgpack_store32(&buf[0], detail::integral_cast<uint32_t>(nanosec));
|
||||||
_msgpack_store64(&buf[4], sec);
|
_msgpack_store64(&buf[4], sec);
|
||||||
o.pack_ext_body(buf, 12);
|
o.pack_ext_body(buf, 12);
|
||||||
}
|
}
|
||||||
@ -192,7 +296,7 @@ struct pack<std::chrono::time_point<Clock, Duration>> {
|
|||||||
template <typename Clock, typename Duration>
|
template <typename Clock, typename Duration>
|
||||||
struct object_with_zone<std::chrono::time_point<Clock, Duration>> {
|
struct object_with_zone<std::chrono::time_point<Clock, Duration>> {
|
||||||
void operator()(msgpack::object::with_zone& o, const std::chrono::time_point<Clock, Duration>& v) const {
|
void operator()(msgpack::object::with_zone& o, const std::chrono::time_point<Clock, Duration>& v) const {
|
||||||
int64_t count = boost::numeric_cast<int64_t>(v.time_since_epoch().count());
|
int64_t count = detail::integral_cast<int64_t>(v.time_since_epoch().count());
|
||||||
|
|
||||||
int64_t nano_num =
|
int64_t nano_num =
|
||||||
Duration::period::ratio::num *
|
Duration::period::ratio::num *
|
||||||
@ -208,14 +312,14 @@ struct object_with_zone<std::chrono::time_point<Clock, Duration>> {
|
|||||||
* Duration::period::ratio::num
|
* Duration::period::ratio::num
|
||||||
/ Duration::period::ratio::den;
|
/ Duration::period::ratio::den;
|
||||||
if ((sec >> 34) == 0) {
|
if ((sec >> 34) == 0) {
|
||||||
uint64_t data64 = (boost::numeric_cast<uint64_t>(nanosec) << 34) | boost::numeric_cast<uint64_t>(sec);
|
uint64_t data64 = (detail::integral_cast<uint64_t>(nanosec) << 34) | detail::integral_cast<uint64_t>(sec);
|
||||||
if ((data64 & 0xffffffff00000000L) == 0) {
|
if ((data64 & 0xffffffff00000000L) == 0) {
|
||||||
// timestamp 32
|
// timestamp 32
|
||||||
o.type = msgpack::type::EXT;
|
o.type = msgpack::type::EXT;
|
||||||
o.via.ext.size = 4;
|
o.via.ext.size = 4;
|
||||||
char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
|
char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
|
||||||
p[0] = static_cast<char>(-1);
|
p[0] = static_cast<char>(-1);
|
||||||
uint32_t data32 = boost::numeric_cast<uint32_t>(data64);
|
uint32_t data32 = detail::integral_cast<uint32_t>(data64);
|
||||||
_msgpack_store32(&p[1], data32);
|
_msgpack_store32(&p[1], data32);
|
||||||
o.via.ext.ptr = p;
|
o.via.ext.ptr = p;
|
||||||
}
|
}
|
||||||
@ -235,7 +339,7 @@ struct object_with_zone<std::chrono::time_point<Clock, Duration>> {
|
|||||||
o.via.ext.size = 12;
|
o.via.ext.size = 12;
|
||||||
char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
|
char* p = static_cast<char*>(o.zone.allocate_no_align(o.via.ext.size + 1));
|
||||||
p[0] = static_cast<char>(-1);
|
p[0] = static_cast<char>(-1);
|
||||||
_msgpack_store32(&p[1], boost::numeric_cast<uint32_t>(nanosec));
|
_msgpack_store32(&p[1], detail::integral_cast<uint32_t>(nanosec));
|
||||||
_msgpack_store64(&p[1 + 4], sec);
|
_msgpack_store64(&p[1 + 4], sec);
|
||||||
o.via.ext.ptr = p;
|
o.via.ext.ptr = p;
|
||||||
}
|
}
|
||||||
@ -250,6 +354,4 @@ struct object_with_zone<std::chrono::time_point<Clock, Duration>> {
|
|||||||
|
|
||||||
} // namespace msgpack
|
} // namespace msgpack
|
||||||
|
|
||||||
#endif // !defined(MSGPACK_NO_BOOST)
|
|
||||||
|
|
||||||
#endif // MSGPACK_V1_TYPE_CPP11_CHRONO_HPP
|
#endif // MSGPACK_V1_TYPE_CPP11_CHRONO_HPP
|
||||||
|
@ -870,8 +870,6 @@ BOOST_AUTO_TEST_CASE(no_def_con_array_simple_buffer)
|
|||||||
BOOST_CHECK(val1 == val2);
|
BOOST_CHECK(val1 == val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MSGPACK_NO_BOOST)
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(system_clock)
|
BOOST_AUTO_TEST_CASE(system_clock)
|
||||||
{
|
{
|
||||||
std::chrono::system_clock::time_point val1;
|
std::chrono::system_clock::time_point val1;
|
||||||
@ -1437,8 +1435,6 @@ BOOST_AUTO_TEST_CASE(high_resolution_clock_impl_now)
|
|||||||
BOOST_CHECK(val1 == val3);
|
BOOST_CHECK(val1 == val3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !defined(MSGPACK_NO_BOOST)
|
|
||||||
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(timespec_pack_convert_zero)
|
BOOST_AUTO_TEST_CASE(timespec_pack_convert_zero)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user