From 2360466aa93f44bac071c59db44f3079f0687768 Mon Sep 17 00:00:00 2001 From: Takatoshi Kondo Date: Sat, 22 Feb 2014 20:43:18 +0000 Subject: [PATCH 1/2] Added unordered containers support for libc++. --- src/msgpack/type/tr1/unordered_map.hpp | 34 ++++++++++++++++++-------- src/msgpack/type/tr1/unordered_set.hpp | 33 +++++++++++++++++-------- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/msgpack/type/tr1/unordered_map.hpp b/src/msgpack/type/tr1/unordered_map.hpp index 4b29f0ca..79da7fc3 100644 --- a/src/msgpack/type/tr1/unordered_map.hpp +++ b/src/msgpack/type/tr1/unordered_map.hpp @@ -19,13 +19,25 @@ #define MSGPACK_TYPE_TR1_UNORDERED_MAP_HPP__ #include "msgpack/object.hpp" + +#if defined(_LIBCPP_VERSION) + +#include +#define MSGPACK_STD_TR1 std + +#else // _LIBCPP_VERSION + #include +#define MSGPACK_STD_TR1 std::tr1 + +#endif // _LIBCPP_VERSION + namespace msgpack { template -inline std::tr1::unordered_map operator>> (object o, std::tr1::unordered_map& v) +inline MSGPACK_STD_TR1::unordered_map operator>> (object o, MSGPACK_STD_TR1::unordered_map& v) { if(o.type != type::MAP) { throw type_error(); } object_kv* p(o.via.map.ptr); @@ -39,10 +51,10 @@ inline std::tr1::unordered_map operator>> (object o, std::tr1::unordered_m } template -inline packer& operator<< (packer& o, const std::tr1::unordered_map& v) +inline packer& operator<< (packer& o, const MSGPACK_STD_TR1::unordered_map& v) { o.pack_map(v.size()); - for(typename std::tr1::unordered_map::const_iterator it(v.begin()), it_end(v.end()); + for(typename MSGPACK_STD_TR1::unordered_map::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(it->first); o.pack(it->second); @@ -51,7 +63,7 @@ inline packer& operator<< (packer& o, const std::tr1::unordered_ } template -inline void operator<< (object::with_zone& o, const std::tr1::unordered_map& v) +inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_map& v) { o.type = type::MAP; if(v.empty()) { @@ -62,7 +74,7 @@ inline void operator<< (object::with_zone& o, const std::tr1::unordered_map object_kv* const pend = p + v.size(); o.via.map.ptr = p; o.via.map.size = v.size(); - typename std::tr1::unordered_map::const_iterator it(v.begin()); + typename MSGPACK_STD_TR1::unordered_map::const_iterator it(v.begin()); do { p->key = object(it->first, o.zone); p->val = object(it->second, o.zone); @@ -74,7 +86,7 @@ inline void operator<< (object::with_zone& o, const std::tr1::unordered_map template -inline std::tr1::unordered_multimap operator>> (object o, std::tr1::unordered_multimap& v) +inline MSGPACK_STD_TR1::unordered_multimap operator>> (object o, MSGPACK_STD_TR1::unordered_multimap& v) { if(o.type != type::MAP) { throw type_error(); } object_kv* p(o.via.map.ptr); @@ -89,10 +101,10 @@ inline std::tr1::unordered_multimap operator>> (object o, std::tr1::unorde } template -inline packer& operator<< (packer& o, const std::tr1::unordered_multimap& v) +inline packer& operator<< (packer& o, const MSGPACK_STD_TR1::unordered_multimap& v) { o.pack_map(v.size()); - for(typename std::tr1::unordered_multimap::const_iterator it(v.begin()), it_end(v.end()); + for(typename MSGPACK_STD_TR1::unordered_multimap::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(it->first); o.pack(it->second); @@ -101,7 +113,7 @@ inline packer& operator<< (packer& o, const std::tr1::unordered_ } template -inline void operator<< (object::with_zone& o, const std::tr1::unordered_multimap& v) +inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_multimap& v) { o.type = type::MAP; if(v.empty()) { @@ -112,7 +124,7 @@ inline void operator<< (object::with_zone& o, const std::tr1::unordered_multimap object_kv* const pend = p + v.size(); o.via.map.ptr = p; o.via.map.size = v.size(); - typename std::tr1::unordered_multimap::const_iterator it(v.begin()); + typename MSGPACK_STD_TR1::unordered_multimap::const_iterator it(v.begin()); do { p->key = object(it->first, o.zone); p->val = object(it->second, o.zone); @@ -125,5 +137,7 @@ inline void operator<< (object::with_zone& o, const std::tr1::unordered_multimap } // namespace msgpack +#undef MSGPACK_STD_TR1 + #endif /* msgpack/type/map.hpp */ diff --git a/src/msgpack/type/tr1/unordered_set.hpp b/src/msgpack/type/tr1/unordered_set.hpp index 4af6801c..d29dc3e5 100644 --- a/src/msgpack/type/tr1/unordered_set.hpp +++ b/src/msgpack/type/tr1/unordered_set.hpp @@ -19,13 +19,24 @@ #define MSGPACK_TYPE_TR1_UNORDERED_SET_HPP__ #include "msgpack/object.hpp" + +#if defined(_LIBCPP_VERSION) + +#include +#define MSGPACK_STD_TR1 std + +#else // _LIBCPP_VERSION + #include +#define MSGPACK_STD_TR1 std::tr1 + +#endif // _LIBCPP_VERSION namespace msgpack { template -inline std::tr1::unordered_set& operator>> (object o, std::tr1::unordered_set& v) +inline MSGPACK_STD_TR1::unordered_set& operator>> (object o, MSGPACK_STD_TR1::unordered_set& v) { if(o.type != type::ARRAY) { throw type_error(); } object* p = o.via.array.ptr + o.via.array.size; @@ -38,10 +49,10 @@ inline std::tr1::unordered_set& operator>> (object o, std::tr1::unordered_set } template -inline packer& operator<< (packer& o, const std::tr1::unordered_set& v) +inline packer& operator<< (packer& o, const MSGPACK_STD_TR1::unordered_set& v) { o.pack_array(v.size()); - for(typename std::tr1::unordered_set::const_iterator it(v.begin()), it_end(v.end()); + for(typename MSGPACK_STD_TR1::unordered_set::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); } @@ -49,7 +60,7 @@ inline packer& operator<< (packer& o, const std::tr1::unordered_ } template -inline void operator<< (object::with_zone& o, const std::tr1::unordered_set& v) +inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_set& v) { o.type = type::ARRAY; if(v.empty()) { @@ -60,7 +71,7 @@ inline void operator<< (object::with_zone& o, const std::tr1::unordered_set& object* const pend = p + v.size(); o.via.array.ptr = p; o.via.array.size = v.size(); - typename std::tr1::unordered_set::const_iterator it(v.begin()); + typename MSGPACK_STD_TR1::unordered_set::const_iterator it(v.begin()); do { *p = object(*it, o.zone); ++p; @@ -71,7 +82,7 @@ inline void operator<< (object::with_zone& o, const std::tr1::unordered_set& template -inline std::tr1::unordered_multiset& operator>> (object o, std::tr1::unordered_multiset& v) +inline MSGPACK_STD_TR1::unordered_multiset& operator>> (object o, MSGPACK_STD_TR1::unordered_multiset& v) { if(o.type != type::ARRAY) { throw type_error(); } object* p = o.via.array.ptr + o.via.array.size; @@ -84,10 +95,10 @@ inline std::tr1::unordered_multiset& operator>> (object o, std::tr1::unordere } template -inline packer& operator<< (packer& o, const std::tr1::unordered_multiset& v) +inline packer& operator<< (packer& o, const MSGPACK_STD_TR1::unordered_multiset& v) { o.pack_array(v.size()); - for(typename std::tr1::unordered_multiset::const_iterator it(v.begin()), it_end(v.end()); + for(typename MSGPACK_STD_TR1::unordered_multiset::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) { o.pack(*it); } @@ -95,7 +106,7 @@ inline packer& operator<< (packer& o, const std::tr1::unordered_ } template -inline void operator<< (object::with_zone& o, const std::tr1::unordered_multiset& v) +inline void operator<< (object::with_zone& o, const MSGPACK_STD_TR1::unordered_multiset& v) { o.type = type::ARRAY; if(v.empty()) { @@ -106,7 +117,7 @@ inline void operator<< (object::with_zone& o, const std::tr1::unordered_multiset object* const pend = p + v.size(); o.via.array.ptr = p; o.via.array.size = v.size(); - typename std::tr1::unordered_multiset::const_iterator it(v.begin()); + typename MSGPACK_STD_TR1::unordered_multiset::const_iterator it(v.begin()); do { *p = object(*it, o.zone); ++p; @@ -118,5 +129,7 @@ inline void operator<< (object::with_zone& o, const std::tr1::unordered_multiset } // namespace msgpack +#undef MSGPACK_STD_TR1 + #endif /* msgpack/type/set.hpp */ From b8076fa71f8385297b7527bd4f20593cccedea37 Mon Sep 17 00:00:00 2001 From: Takatoshi Kondo Date: Thu, 27 Feb 2014 23:45:34 +0000 Subject: [PATCH 2/2] Supported VC++. Fixed testing macro for tr1 containers. --- src/msgpack/type/tr1/unordered_map.hpp | 13 ++- src/msgpack/type/tr1/unordered_set.hpp | 13 ++- test/msgpack_test.cpp | 129 +++++++++++++++++++++++-- 3 files changed, 143 insertions(+), 12 deletions(-) diff --git a/src/msgpack/type/tr1/unordered_map.hpp b/src/msgpack/type/tr1/unordered_map.hpp index 79da7fc3..f485c89a 100644 --- a/src/msgpack/type/tr1/unordered_map.hpp +++ b/src/msgpack/type/tr1/unordered_map.hpp @@ -20,17 +20,24 @@ #include "msgpack/object.hpp" -#if defined(_LIBCPP_VERSION) +#if defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) +#define MSGPACK_HAS_STD_UNOURDERED_MAP #include #define MSGPACK_STD_TR1 std -#else // _LIBCPP_VERSION +#else // defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) + +#if __GNUC__ >= 4 + +#define MSGPACK_HAS_STD_TR1_UNOURDERED_MAP #include #define MSGPACK_STD_TR1 std::tr1 -#endif // _LIBCPP_VERSION +#endif // __GNUC__ >= 4 + +#endif // defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) namespace msgpack { diff --git a/src/msgpack/type/tr1/unordered_set.hpp b/src/msgpack/type/tr1/unordered_set.hpp index d29dc3e5..252ae233 100644 --- a/src/msgpack/type/tr1/unordered_set.hpp +++ b/src/msgpack/type/tr1/unordered_set.hpp @@ -20,17 +20,24 @@ #include "msgpack/object.hpp" -#if defined(_LIBCPP_VERSION) +#if defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) +#define MSGPACK_HAS_STD_UNOURDERED_SET #include #define MSGPACK_STD_TR1 std -#else // _LIBCPP_VERSION +#else // defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) + +#if __GNUC__ >= 4 + +#define MSGPACK_HAS_STD_TR1_UNOURDERED_SET #include #define MSGPACK_STD_TR1 std::tr1 -#endif // _LIBCPP_VERSION +#endif // __GNUC__ >= 4 + +#endif // defined(_LIBCPP_VERSION) || (_MSC_VER >= 1700) namespace msgpack { diff --git a/test/msgpack_test.cpp b/test/msgpack_test.cpp index 5b60dc5b..5ed61137 100644 --- a/test/msgpack_test.cpp +++ b/test/msgpack_test.cpp @@ -452,10 +452,10 @@ TEST(MSGPACK_STL, simple_buffer_multiset) // TR1 -#ifdef HAVE_TR1_UNORDERED_MAP +#ifdef MSGPACK_HAS_STD_TR1_UNOURDERED_MAP #include #include "msgpack/type/tr1/unordered_map.hpp" -TEST(MSGPACK_TR1, simple_buffer_unordered_map) +TEST(MSGPACK_TR1, simple_buffer_tr1_unordered_map) { for (unsigned int k = 0; k < kLoop; k++) { tr1::unordered_map val1; @@ -479,7 +479,7 @@ TEST(MSGPACK_TR1, simple_buffer_unordered_map) } } -TEST(MSGPACK_TR1, simple_buffer_unordered_multimap) +TEST(MSGPACK_TR1, simple_buffer_tr1_unordered_multimap) { for (unsigned int k = 0; k < kLoop; k++) { tr1::unordered_multimap val1; @@ -513,10 +513,10 @@ TEST(MSGPACK_TR1, simple_buffer_unordered_multimap) } #endif -#ifdef HAVE_TR1_UNORDERED_SET +#ifdef MSGPACK_HAS_STD_TR1_UNOURDERED_SET #include #include "msgpack/type/tr1/unordered_set.hpp" -TEST(MSGPACK_TR1, simple_buffer_unordered_set) +TEST(MSGPACK_TR1, simple_buffer_tr1_unordered_set) { for (unsigned int k = 0; k < kLoop; k++) { tr1::unordered_set val1; @@ -538,7 +538,7 @@ TEST(MSGPACK_TR1, simple_buffer_unordered_set) } } -TEST(MSGPACK_TR1, simple_buffer_unordered_multiset) +TEST(MSGPACK_TR1, simple_buffer_tr1_unordered_multiset) { for (unsigned int k = 0; k < kLoop; k++) { tr1::unordered_multiset val1; @@ -569,6 +569,123 @@ TEST(MSGPACK_TR1, simple_buffer_unordered_multiset) } #endif +#ifdef MSGPACK_HAS_STD_UNOURDERED_MAP +#include +#include "msgpack/type/tr1/unordered_map.hpp" +TEST(MSGPACK_TR1, simple_buffer_unordered_map) +{ + for (unsigned int k = 0; k < kLoop; k++) { + unordered_map val1; + for (unsigned int i = 0; i < kElements; i++) + val1[rand()] = rand(); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + unordered_map val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + unordered_map::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) { + EXPECT_TRUE(val2.find(it->first) != val2.end()); + EXPECT_EQ(it->second, val2.find(it->first)->second); + } + } +} + +TEST(MSGPACK_TR1, simple_buffer_unordered_multimap) +{ + for (unsigned int k = 0; k < kLoop; k++) { + unordered_multimap val1; + for (unsigned int i = 0; i < kElements; i++) { + int i1 = rand(); + val1.insert(make_pair(i1, rand())); + val1.insert(make_pair(i1, rand())); + } + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + unordered_multimap val2; + obj.convert(&val2); + + vector > v1, v2; + unordered_multimap::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) + v1.push_back(make_pair(it->first, it->second)); + for (it = val2.begin(); it != val2.end(); ++it) + v2.push_back(make_pair(it->first, it->second)); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_EQ(v1.size(), v2.size()); + sort(v1.begin(), v1.end()); + sort(v2.begin(), v2.end()); + EXPECT_TRUE(v1 == v2); + } +} +#endif + +#ifdef MSGPACK_HAS_STD_UNOURDERED_SET +#include +#include "msgpack/type/tr1/unordered_set.hpp" +TEST(MSGPACK_TR1, simple_buffer_unordered_set) +{ + for (unsigned int k = 0; k < kLoop; k++) { + unordered_set val1; + for (unsigned int i = 0; i < kElements; i++) + val1.insert(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + unordered_set val2; + obj.convert(&val2); + EXPECT_EQ(val1.size(), val2.size()); + unordered_set::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) + EXPECT_TRUE(val2.find(*it) != val2.end()); + } +} + +TEST(MSGPACK_TR1, simple_buffer_unordered_multiset) +{ + for (unsigned int k = 0; k < kLoop; k++) { + unordered_multiset val1; + for (unsigned int i = 0; i < kElements; i++) + val1.insert(rand()); + msgpack::sbuffer sbuf; + msgpack::pack(sbuf, val1); + msgpack::zone z; + msgpack::object obj; + msgpack::unpack_return ret = + msgpack::unpack(sbuf.data(), sbuf.size(), NULL, &z, &obj); + EXPECT_EQ(msgpack::UNPACK_SUCCESS, ret); + unordered_multiset val2; + obj.convert(&val2); + + vector v1, v2; + unordered_multiset::const_iterator it; + for (it = val1.begin(); it != val1.end(); ++it) + v1.push_back(*it); + for (it = val2.begin(); it != val2.end(); ++it) + v2.push_back(*it); + EXPECT_EQ(val1.size(), val2.size()); + EXPECT_EQ(v1.size(), v2.size()); + sort(v1.begin(), v1.end()); + sort(v2.begin(), v2.end()); + EXPECT_TRUE(v1 == v2); + } +} +#endif + // User-Defined Structures class TestClass