Added complex type support.

This commit is contained in:
Takatoshi Kondo 2020-06-10 11:36:04 +09:00
parent 6b197e7328
commit 3b80c45725
7 changed files with 167 additions and 1 deletions

View File

@ -15,6 +15,7 @@ SET (msgpackc_HEADERS
include/msgpack/adaptor/char_ptr.hpp include/msgpack/adaptor/char_ptr.hpp
include/msgpack/adaptor/check_container_size.hpp include/msgpack/adaptor/check_container_size.hpp
include/msgpack/adaptor/check_container_size_decl.hpp include/msgpack/adaptor/check_container_size_decl.hpp
include/msgpack/adaptor/complex.hpp
include/msgpack/adaptor/cpp11/array.hpp include/msgpack/adaptor/cpp11/array.hpp
include/msgpack/adaptor/cpp11/array_char.hpp include/msgpack/adaptor/cpp11/array_char.hpp
include/msgpack/adaptor/cpp11/array_unsigned_char.hpp include/msgpack/adaptor/cpp11/array_unsigned_char.hpp
@ -110,6 +111,7 @@ SET (msgpackc_HEADERS
include/msgpack/v1/adaptor/char_ptr.hpp include/msgpack/v1/adaptor/char_ptr.hpp
include/msgpack/v1/adaptor/check_container_size.hpp include/msgpack/v1/adaptor/check_container_size.hpp
include/msgpack/v1/adaptor/check_container_size_decl.hpp include/msgpack/v1/adaptor/check_container_size_decl.hpp
include/msgpack/v1/adaptor/complex.hpp
include/msgpack/v1/adaptor/cpp11/array.hpp include/msgpack/v1/adaptor/cpp11/array.hpp
include/msgpack/v1/adaptor/cpp11/array_char.hpp include/msgpack/v1/adaptor/cpp11/array_char.hpp
include/msgpack/v1/adaptor/cpp11/array_unsigned_char.hpp include/msgpack/v1/adaptor/cpp11/array_unsigned_char.hpp

View File

@ -0,0 +1,15 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2020 KONDO Takatoshi
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef MSGPACK_TYPE_COMPLEX_HPP
#define MSGPACK_TYPE_COMPLEX_HPP
#include "msgpack/v1/adaptor/complex.hpp"
#endif // MSGPACK_TYPE_COMPLEX_HPP

View File

@ -8,6 +8,7 @@
#include "adaptor/fixint.hpp" #include "adaptor/fixint.hpp"
#include "adaptor/float.hpp" #include "adaptor/float.hpp"
#include "adaptor/int.hpp" #include "adaptor/int.hpp"
#include "adaptor/complex.hpp"
#include "adaptor/list.hpp" #include "adaptor/list.hpp"
#include "adaptor/map.hpp" #include "adaptor/map.hpp"
#include "adaptor/nil.hpp" #include "adaptor/nil.hpp"

View File

@ -0,0 +1,91 @@
//
// MessagePack for C++ static resolution routine
//
// Copyright (C) 2020 KONDO Takatoshi
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef MSGPACK_V1_TYPE_COMPLEX_HPP
#define MSGPACK_V1_TYPE_COMPLEX_HPP
#include <complex>
#include "msgpack/versioning.hpp"
#include "msgpack/adaptor/adaptor_base.hpp"
#include "msgpack/meta.hpp"
namespace msgpack {
/// @cond
MSGPACK_API_VERSION_NAMESPACE(v1) {
/// @endcond
namespace adaptor {
#if !defined(MSGPACK_USE_CPP03)
template <typename T>
struct as<std::complex<T>, typename std::enable_if<msgpack::has_as<T>::value>::type> {
std::complex<T> operator()(msgpack::object const& o) const {
if (o.type != msgpack::type::ARRAY)
throw msgpack::type_error();
if (o.via.array.size != 2)
throw msgpack::type_error();
return std::complex<T>(o.via.array.ptr[0].as<T>(), o.via.array.ptr[1].as<T>());
}
};
#endif // !defined(MSGPACK_USE_CPP03)
template <typename T>
struct convert<std::complex<T> > {
msgpack::object const& operator()(msgpack::object const& o, std::complex<T>& v) const {
if(o.type != msgpack::type::ARRAY)
throw msgpack::type_error();
if(o.via.array.size != 2)
throw msgpack::type_error();
T real;
T imag;
o.via.array.ptr[0].convert(real);
o.via.array.ptr[1].convert(imag);
v.real(real);
v.imag(imag);
return o;
}
};
template <typename T>
struct pack<std::complex<T> > {
template <typename Stream>
msgpack::packer<Stream>& operator()(msgpack::packer<Stream>& o, std::complex<T> const& v) const {
o.pack_array(2);
o.pack(v.real());
o.pack(v.imag());
return o;
}
};
template <typename T>
struct object_with_zone<std::complex<T> > {
void operator()(msgpack::object::with_zone& o, std::complex<T> const& v) const {
o.type = msgpack::type::ARRAY;
msgpack::object* p = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*2, MSGPACK_ZONE_ALIGNOF(msgpack::object)));
o.via.array.ptr = p;
o.via.array.size = 2;
p[0] = msgpack::object(v.real(), o.zone);
p[1] = msgpack::object(v.imag(), o.zone);
}
};
} // namespace adaptor
/// @cond
} // MSGPACK_API_VERSION_NAMESPACE(v1)
/// @endcond
} // namespace msgpack
#endif // MSGPACK_V1_TYPE_COMPLEX_HPP

View File

@ -2,7 +2,7 @@
find include -name "*.hpp" | sed -e 's/\s\+/\n/g' | LC_ALL=C sort > cpp_headers.tmp find include -name "*.hpp" | sed -e 's/\s\+/\n/g' | LC_ALL=C sort > cpp_headers.tmp
echo 'SET (msgpackc_HEADERS' >> Files.cmake echo 'SET (msgpackc_HEADERS' > Files.cmake
cat cpp_headers.tmp | sed -e 's/^/ /g' >> Files.cmake cat cpp_headers.tmp | sed -e 's/^/ /g' >> Files.cmake
echo ')' >> Files.cmake echo ')' >> Files.cmake

View File

@ -372,6 +372,36 @@ TEST(MSGPACK_STL, simple_buffer_pair)
} }
} }
TEST(MSGPACK_STL, simple_buffer_complex_float)
{
complex<float> val1 = complex<float>(1.23F, 4.56F);
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::object_handle oh =
msgpack::unpack(sbuf.data(), sbuf.size());
complex<float> val2 = oh.get().as<complex<float> >();
EXPECT_EQ(val1, val2);
complex<float> val3;
oh.get().convert(val3);
EXPECT_EQ(val1, val3);
}
TEST(MSGPACK_STL, simple_buffer_complex_double)
{
complex<double> val1 = complex<double>(1.23, 4.56);
msgpack::sbuffer sbuf;
msgpack::pack(sbuf, val1);
msgpack::object_handle oh =
msgpack::unpack(sbuf.data(), sbuf.size());
complex<double> val2 = oh.get().as<complex<double> >();
EXPECT_EQ(val1, val2);
complex<double> val3;
oh.get().convert(val3);
EXPECT_EQ(val1, val3);
}
TEST(MSGPACK_STL, simple_buffer_multimap) TEST(MSGPACK_STL, simple_buffer_multimap)
{ {
typedef multimap<int, int, test::less<int>, test::allocator<std::pair<const int, int> > > type; typedef multimap<int, int, test::less<int>, test::allocator<std::pair<const int, int> > > type;

View File

@ -365,6 +365,33 @@ TEST(object_with_zone, char_ptr)
EXPECT_EQ(obj.as<string>()[0], 'a'); EXPECT_EQ(obj.as<string>()[0], 'a');
} }
// complex
TEST(object_with_zone, complex_float)
{
typedef std::complex<float> test_t;
test_t v(1.23F, 4.56F);
msgpack::zone z;
msgpack::object obj(v, z);
float r = v.real();
EXPECT_TRUE(fabs(obj.as<test_t>().real() - v.real()) <= kEPS);
EXPECT_TRUE(fabs(obj.as<test_t>().imag() - v.imag()) <= kEPS);
v.real(7.89F);
EXPECT_TRUE(fabs(obj.as<test_t>().real() - r) <= kEPS);
}
TEST(object_with_zone, complex_double)
{
typedef std::complex<double> test_t;
test_t v(1.23, 4.56);
msgpack::zone z;
msgpack::object obj(v, z);
double r = v.real();
EXPECT_TRUE(fabs(obj.as<test_t>().real() - v.real()) <= kEPS);
EXPECT_TRUE(fabs(obj.as<test_t>().imag() - v.imag()) <= kEPS);
v.real(7.89);
EXPECT_TRUE(fabs(obj.as<test_t>().real() - r) <= kEPS);
}
#if MSGPACK_DEFAULT_API_VERSION == 1 #if MSGPACK_DEFAULT_API_VERSION == 1
TEST(object_without_zone, char_ptr) TEST(object_without_zone, char_ptr)