mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-10-14 23:07:58 +02:00
Fixed #1070.
- msgpack::type::variant behaves as MessagePack format. e.g.) 12.34 => double 12.0 => uint64_t -12.34 => double -12.0 => int64_t - msgpack::type::variant::as_double() can be used even if interval type is int64_t and/or uint64_t. - msgpack::type::variant::as_*() don't return non const reference internal value. - fix coding style
This commit is contained in:
@@ -122,6 +122,12 @@ struct basic_variant :
|
|||||||
int_init(v);
|
int_init(v);
|
||||||
}
|
}
|
||||||
basic_variant(unsigned long long v):base(uint64_t(v)) {}
|
basic_variant(unsigned long long v):base(uint64_t(v)) {}
|
||||||
|
basic_variant(float v) {
|
||||||
|
double_init(v);
|
||||||
|
}
|
||||||
|
basic_variant(double v) {
|
||||||
|
double_init(v);
|
||||||
|
}
|
||||||
|
|
||||||
bool is_nil() const {
|
bool is_nil() const {
|
||||||
return boost::get<msgpack::type::nil_t>(this) != MSGPACK_NULLPTR;
|
return boost::get<msgpack::type::nil_t>(this) != MSGPACK_NULLPTR;
|
||||||
@@ -177,71 +183,50 @@ struct basic_variant :
|
|||||||
int64_t as_int64_t() const {
|
int64_t as_int64_t() const {
|
||||||
return boost::get<int64_t>(*this);
|
return boost::get<int64_t>(*this);
|
||||||
}
|
}
|
||||||
int64_t& as_int64_t() {
|
|
||||||
return boost::get<int64_t>(*this);
|
|
||||||
}
|
|
||||||
uint64_t as_uint64_t() const {
|
uint64_t as_uint64_t() const {
|
||||||
return boost::get<uint64_t>(*this);
|
return boost::get<uint64_t>(*this);
|
||||||
}
|
}
|
||||||
uint64_t& as_uint64_t() {
|
|
||||||
return boost::get<uint64_t>(*this);
|
|
||||||
}
|
|
||||||
double as_double() const {
|
double as_double() const {
|
||||||
|
if (is_double()) {
|
||||||
return boost::get<double>(*this);
|
return boost::get<double>(*this);
|
||||||
}
|
}
|
||||||
double& as_double() {
|
if (is_int64_t()) {
|
||||||
return boost::get<double>(*this);
|
return static_cast<double>(boost::get<int64_t>(*this));
|
||||||
|
}
|
||||||
|
if (is_uint64_t()) {
|
||||||
|
return static_cast<double>(boost::get<uint64_t>(*this));
|
||||||
|
}
|
||||||
|
throw msgpack::type_error();
|
||||||
}
|
}
|
||||||
std::string const& as_string() const {
|
std::string const& as_string() const {
|
||||||
return boost::get<std::string>(*this);
|
return boost::get<std::string>(*this);
|
||||||
}
|
}
|
||||||
std::string& as_string() {
|
|
||||||
return boost::get<std::string>(*this);
|
|
||||||
}
|
|
||||||
#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
|
#if (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
|
||||||
boost::string_ref const& as_boost_string_ref() const {
|
boost::string_ref const& as_boost_string_ref() const {
|
||||||
return boost::get<boost::string_ref>(*this);
|
return boost::get<boost::string_ref>(*this);
|
||||||
}
|
}
|
||||||
boost::string_ref& as_boost_string_ref() {
|
|
||||||
return boost::get<boost::string_ref>(*this);
|
|
||||||
}
|
|
||||||
#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
|
#endif // (BOOST_VERSION / 100000) >= 1 && ((BOOST_VERSION / 100) % 1000) >= 53
|
||||||
std::vector<char> const& as_vector_char() const {
|
std::vector<char> const& as_vector_char() const {
|
||||||
return boost::get<std::vector<char> >(*this);
|
return boost::get<std::vector<char> >(*this);
|
||||||
}
|
}
|
||||||
std::vector<char>& as_vector_char() {
|
|
||||||
return boost::get<std::vector<char> >(*this);
|
|
||||||
}
|
|
||||||
raw_ref const& as_raw_ref() const {
|
raw_ref const& as_raw_ref() const {
|
||||||
return boost::get<raw_ref>(*this);
|
return boost::get<raw_ref>(*this);
|
||||||
}
|
}
|
||||||
ext const& as_ext() const {
|
ext const& as_ext() const {
|
||||||
return boost::get<ext>(*this);
|
return boost::get<ext>(*this);
|
||||||
}
|
}
|
||||||
ext& as_ext() {
|
|
||||||
return boost::get<ext>(*this);
|
|
||||||
}
|
|
||||||
ext_ref const& as_ext_ref() const {
|
ext_ref const& as_ext_ref() const {
|
||||||
return boost::get<ext_ref>(*this);
|
return boost::get<ext_ref>(*this);
|
||||||
}
|
}
|
||||||
std::vector<basic_variant<STR, BIN, EXT> > const& as_vector() const {
|
std::vector<basic_variant<STR, BIN, EXT> > const& as_vector() const {
|
||||||
return boost::get<std::vector<basic_variant<STR, BIN, EXT> > >(*this);
|
return boost::get<std::vector<basic_variant<STR, BIN, EXT> > >(*this);
|
||||||
}
|
}
|
||||||
std::vector<basic_variant<STR, BIN, EXT> >& as_vector() {
|
|
||||||
return boost::get<std::vector<basic_variant<STR, BIN, EXT> > >(*this);
|
|
||||||
}
|
|
||||||
std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > const& as_map() const {
|
std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > const& as_map() const {
|
||||||
return boost::get<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
|
return boost::get<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
|
||||||
}
|
}
|
||||||
std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> >& as_map() {
|
|
||||||
return boost::get<std::map<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
|
|
||||||
}
|
|
||||||
std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > const& as_multimap() const {
|
std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > const& as_multimap() const {
|
||||||
return boost::get<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
|
return boost::get<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
|
||||||
}
|
}
|
||||||
std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> >& as_multimap() {
|
|
||||||
return boost::get<std::multimap<basic_variant<STR, BIN, EXT>, basic_variant<STR, BIN, EXT> > >(*this);
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void int_init(T v) {
|
void int_init(T v) {
|
||||||
@@ -252,6 +237,19 @@ private:
|
|||||||
static_cast<base&>(*this) = uint64_t(v);
|
static_cast<base&>(*this) = uint64_t(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void double_init(double v) {
|
||||||
|
if (v == v) { // check for nan
|
||||||
|
if (v >= 0 && v <= double(std::numeric_limits<uint64_t>::max()) && v == double(uint64_t(v))) {
|
||||||
|
static_cast<base&>(*this) = uint64_t(v);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (v < 0 && v >= double(std::numeric_limits<int64_t>::min()) && v == double(int64_t(v))) {
|
||||||
|
static_cast<base&>(*this) = int64_t(v);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static_cast<base&>(*this) = v;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename STR, typename BIN, typename EXT>
|
template <typename STR, typename BIN, typename EXT>
|
||||||
|
@@ -264,7 +264,7 @@ BOOST_AUTO_TEST_CASE(pack_convert_variant_float)
|
|||||||
BOOST_CHECK(val2.is_double());
|
BOOST_CHECK(val2.is_double());
|
||||||
BOOST_CHECK(fabs(12.34 - val2.as_double()) <= kEPS);
|
BOOST_CHECK(fabs(12.34 - val2.as_double()) <= kEPS);
|
||||||
BOOST_CHECK_NO_THROW(boost::get<double>(val2));
|
BOOST_CHECK_NO_THROW(boost::get<double>(val2));
|
||||||
BOOST_CHECK(fabs(val2.as_double() - val2.as_double()) <= kEPS);
|
BOOST_CHECK(fabs(val1.as_double() - val2.as_double()) <= kEPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(object_variant_float)
|
BOOST_AUTO_TEST_CASE(object_variant_float)
|
||||||
@@ -277,7 +277,8 @@ BOOST_AUTO_TEST_CASE(object_variant_float)
|
|||||||
BOOST_CHECK(val2.is_double());
|
BOOST_CHECK(val2.is_double());
|
||||||
BOOST_CHECK(fabs(12.34 - val2.as_double()) <= kEPS);
|
BOOST_CHECK(fabs(12.34 - val2.as_double()) <= kEPS);
|
||||||
BOOST_CHECK_NO_THROW(boost::get<double>(val2));
|
BOOST_CHECK_NO_THROW(boost::get<double>(val2));
|
||||||
BOOST_CHECK(fabs(val2.as_double() - val2.as_double()) <= kEPS);
|
BOOST_CHECK(fabs(val1.as_double() - val2.as_double()) <= kEPS);
|
||||||
|
BOOST_CHECK(val1 == val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(object_with_zone_variant_float)
|
BOOST_AUTO_TEST_CASE(object_with_zone_variant_float)
|
||||||
@@ -291,7 +292,116 @@ BOOST_AUTO_TEST_CASE(object_with_zone_variant_float)
|
|||||||
BOOST_CHECK(val2.is_double());
|
BOOST_CHECK(val2.is_double());
|
||||||
BOOST_CHECK(fabs(12.34 - val2.as_double()) <= kEPS);
|
BOOST_CHECK(fabs(12.34 - val2.as_double()) <= kEPS);
|
||||||
BOOST_CHECK_NO_THROW(boost::get<double>(val2));
|
BOOST_CHECK_NO_THROW(boost::get<double>(val2));
|
||||||
BOOST_CHECK(fabs(val2.as_double() - val2.as_double()) <= kEPS);
|
BOOST_CHECK(fabs(val1.as_double() - val2.as_double()) <= kEPS);
|
||||||
|
BOOST_CHECK(val1 == val2);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(pack_convert_variant_float_zero_atdp_positive)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
msgpack::type::variant val1 = 12.0;
|
||||||
|
BOOST_CHECK(val1.is_uint64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_uint64_t(), 12);
|
||||||
|
BOOST_CHECK(fabs(12.0 - val1.as_double()) <= kEPS);
|
||||||
|
|
||||||
|
msgpack::pack(ss, val1);
|
||||||
|
|
||||||
|
std::string const& str = ss.str();
|
||||||
|
msgpack::object_handle oh =
|
||||||
|
msgpack::unpack(str.data(), str.size());
|
||||||
|
msgpack::type::variant val2 = oh.get().as<msgpack::type::variant>();
|
||||||
|
BOOST_CHECK(val2.is_uint64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val2.as_uint64_t(), 12);
|
||||||
|
BOOST_CHECK_NO_THROW(boost::get<uint64_t>(val2));
|
||||||
|
BOOST_CHECK(fabs(12.0 - val2.as_double()) <= kEPS);
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_uint64_t(), val2.as_uint64_t());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(object_variant_float_zero_atdp_positive)
|
||||||
|
{
|
||||||
|
msgpack::type::variant val1 = 12.0;
|
||||||
|
BOOST_CHECK(val1.is_uint64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_uint64_t(), 12);
|
||||||
|
BOOST_CHECK(fabs(12.0 - val1.as_double()) <= kEPS);
|
||||||
|
msgpack::object obj(val1);
|
||||||
|
msgpack::type::variant val2 = obj.as<msgpack::type::variant>();
|
||||||
|
BOOST_CHECK(val2.is_uint64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val2.as_uint64_t(), 12);
|
||||||
|
BOOST_CHECK_NO_THROW(boost::get<uint64_t>(val2));
|
||||||
|
BOOST_CHECK(fabs(12.0 - val2.as_double()) <= kEPS);
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_uint64_t(), val2.as_uint64_t());
|
||||||
|
BOOST_CHECK(val1 == val2);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(object_with_zone_variant_float_zero_atdp_positive)
|
||||||
|
{
|
||||||
|
msgpack::zone z;
|
||||||
|
msgpack::type::variant val1 = 12.0;
|
||||||
|
BOOST_CHECK(val1.is_uint64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_uint64_t(), 12);
|
||||||
|
BOOST_CHECK(fabs(12.0 - val1.as_double()) <= kEPS);
|
||||||
|
msgpack::object obj(val1, z);
|
||||||
|
msgpack::type::variant val2 = obj.as<msgpack::type::variant>();
|
||||||
|
BOOST_CHECK(val2.is_uint64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val2.as_uint64_t(), 12);
|
||||||
|
BOOST_CHECK_NO_THROW(boost::get<uint64_t>(val2));
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_uint64_t(), val2.as_uint64_t());
|
||||||
|
BOOST_CHECK(fabs(12.0 - val2.as_double()) <= kEPS);
|
||||||
|
BOOST_CHECK(val1 == val2);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(pack_convert_variant_float_zero_atdp_negative)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
msgpack::type::variant val1 = -12.0;
|
||||||
|
BOOST_CHECK(val1.is_int64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_int64_t(), -12);
|
||||||
|
BOOST_CHECK(fabs(-12.0 - val1.as_double()) <= kEPS);
|
||||||
|
|
||||||
|
msgpack::pack(ss, val1);
|
||||||
|
|
||||||
|
std::string const& str = ss.str();
|
||||||
|
msgpack::object_handle oh =
|
||||||
|
msgpack::unpack(str.data(), str.size());
|
||||||
|
msgpack::type::variant val2 = oh.get().as<msgpack::type::variant>();
|
||||||
|
BOOST_CHECK(val2.is_int64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val2.as_int64_t(), -12);
|
||||||
|
BOOST_CHECK_NO_THROW(boost::get<int64_t>(val2));
|
||||||
|
BOOST_CHECK(fabs(-12.0 - val2.as_double()) <= kEPS);
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_int64_t(), val2.as_int64_t());
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(object_variant_float_zero_atdp_negative)
|
||||||
|
{
|
||||||
|
msgpack::type::variant val1 = -12.0;
|
||||||
|
BOOST_CHECK(val1.is_int64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_int64_t(), -12);
|
||||||
|
BOOST_CHECK(fabs(-12.0 - val1.as_double()) <= kEPS);
|
||||||
|
msgpack::object obj(val1);
|
||||||
|
msgpack::type::variant val2 = obj.as<msgpack::type::variant>();
|
||||||
|
BOOST_CHECK(val2.is_int64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val2.as_int64_t(), -12);
|
||||||
|
BOOST_CHECK_NO_THROW(boost::get<int64_t>(val2));
|
||||||
|
BOOST_CHECK(fabs(-12.0 - val2.as_double()) <= kEPS);
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_int64_t(), val2.as_int64_t());
|
||||||
|
BOOST_CHECK(val1 == val2);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(object_with_zone_variant_float_zero_atdp_negative)
|
||||||
|
{
|
||||||
|
msgpack::zone z;
|
||||||
|
msgpack::type::variant val1 = -12.0;
|
||||||
|
BOOST_CHECK(val1.is_int64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_int64_t(), -12);
|
||||||
|
BOOST_CHECK(fabs(-12.0 - val1.as_double()) <= kEPS);
|
||||||
|
msgpack::object obj(val1, z);
|
||||||
|
msgpack::type::variant val2 = obj.as<msgpack::type::variant>();
|
||||||
|
BOOST_CHECK(val2.is_int64_t());
|
||||||
|
BOOST_CHECK_EQUAL(val2.as_int64_t(), -12);
|
||||||
|
BOOST_CHECK_NO_THROW(boost::get<int64_t>(val2));
|
||||||
|
BOOST_CHECK(fabs(-12.0 - val2.as_double()) <= kEPS);
|
||||||
|
BOOST_CHECK_EQUAL(val1.as_int64_t(), val2.as_int64_t());
|
||||||
|
BOOST_CHECK(val1 == val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// str
|
// str
|
||||||
|
Reference in New Issue
Block a user