user_class.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. #include <msgpack.hpp>
  2. #include <string>
  3. #include <cmath>
  4. #include <gtest/gtest.h>
  5. #ifdef HAVE_CONFIG_H
  6. #include "config.h"
  7. #endif
  8. using namespace std;
  9. const unsigned int kLoop = 1000;
  10. const unsigned int kElements = 100;
  11. const double kEPS = 1e-10;
  12. // User-Defined Structures
  13. class TestEnumMemberClass
  14. {
  15. public:
  16. TestEnumMemberClass()
  17. : t1(STATE_A), t2(STATE_B), t3(STATE_C) {}
  18. enum TestEnumType {
  19. STATE_INVALID = 0,
  20. STATE_A = 1,
  21. STATE_B = 2,
  22. STATE_C = 3
  23. };
  24. TestEnumType t1;
  25. TestEnumType t2;
  26. TestEnumType t3;
  27. MSGPACK_DEFINE(t1, t2, t3);
  28. };
  29. MSGPACK_ADD_ENUM(TestEnumMemberClass::TestEnumType);
  30. class TestClass
  31. {
  32. public:
  33. TestClass() : i(0), s("kzk") {}
  34. int i;
  35. string s;
  36. MSGPACK_DEFINE(i, s);
  37. };
  38. TEST(MSGPACK_USER_DEFINED, simple_buffer_class)
  39. {
  40. for (unsigned int k = 0; k < kLoop; k++) {
  41. TestClass val1;
  42. msgpack::sbuffer sbuf;
  43. msgpack::pack(sbuf, val1);
  44. msgpack::object_handle oh =
  45. msgpack::unpack(sbuf.data(), sbuf.size());
  46. TestClass val2 = oh.get().as<TestClass>();
  47. EXPECT_EQ(val1.i, val2.i);
  48. EXPECT_EQ(val1.s, val2.s);
  49. }
  50. }
  51. class TestClass2
  52. {
  53. public:
  54. TestClass2() : i(0), s("kzk") {
  55. for (unsigned int i = 0; i < kElements; i++)
  56. v.push_back(rand());
  57. }
  58. int i;
  59. string s;
  60. vector<int> v;
  61. MSGPACK_DEFINE(i, s, v);
  62. };
  63. TEST(MSGPACK_USER_DEFINED, simple_buffer_class_old_to_new)
  64. {
  65. for (unsigned int k = 0; k < kLoop; k++) {
  66. TestClass val1;
  67. msgpack::sbuffer sbuf;
  68. msgpack::pack(sbuf, val1);
  69. msgpack::object_handle oh =
  70. msgpack::unpack(sbuf.data(), sbuf.size());
  71. TestClass2 val2 = oh.get().as<TestClass2>();
  72. EXPECT_EQ(val1.i, val2.i);
  73. EXPECT_EQ(val1.s, val2.s);
  74. EXPECT_FALSE(val2.s.empty());
  75. }
  76. }
  77. TEST(MSGPACK_USER_DEFINED, simple_buffer_class_new_to_old)
  78. {
  79. for (unsigned int k = 0; k < kLoop; k++) {
  80. TestClass2 val1;
  81. msgpack::sbuffer sbuf;
  82. msgpack::pack(sbuf, val1);
  83. msgpack::object_handle oh =
  84. msgpack::unpack(sbuf.data(), sbuf.size());
  85. TestClass val2 = oh.get().as<TestClass>();
  86. EXPECT_EQ(val1.i, val2.i);
  87. EXPECT_EQ(val1.s, val2.s);
  88. EXPECT_FALSE(val2.s.empty());
  89. }
  90. }
  91. TEST(MSGPACK_USER_DEFINED, simple_buffer_enum_member)
  92. {
  93. TestEnumMemberClass val1;
  94. msgpack::sbuffer sbuf;
  95. msgpack::pack(sbuf, val1);
  96. msgpack::object_handle oh =
  97. msgpack::unpack(sbuf.data(), sbuf.size());
  98. TestEnumMemberClass val2 = oh.get().as<TestEnumMemberClass>();
  99. EXPECT_EQ(val1.t1, val2.t1);
  100. EXPECT_EQ(val1.t2, val2.t2);
  101. EXPECT_EQ(val1.t3, val2.t3);
  102. }
  103. class TestUnionMemberClass
  104. {
  105. public:
  106. TestUnionMemberClass() {}
  107. TestUnionMemberClass(double f) {
  108. is_double = true;
  109. value.f = f;
  110. }
  111. TestUnionMemberClass(int i) {
  112. is_double = false;
  113. value.i = i;
  114. }
  115. union {
  116. double f;
  117. int i;
  118. } value;
  119. bool is_double;
  120. template <typename Packer>
  121. void msgpack_pack(Packer& pk) const
  122. {
  123. if (is_double)
  124. pk.pack(msgpack::type::tuple<bool, double>(true, value.f));
  125. else
  126. pk.pack(msgpack::type::tuple<bool, int>(false, value.i));
  127. }
  128. void msgpack_unpack(msgpack::object o)
  129. {
  130. #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  131. #pragma GCC diagnostic push
  132. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  133. #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  134. msgpack::type::tuple<bool, msgpack::object> tuple(false, msgpack::object());
  135. o.convert(tuple);
  136. is_double = tuple.get<0>();
  137. if (is_double)
  138. tuple.get<1>().convert(value.f);
  139. else
  140. tuple.get<1>().convert(value.i);
  141. #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  142. #pragma GCC diagnostic pop
  143. #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  144. }
  145. };
  146. TEST(MSGPACK_USER_DEFINED, simple_buffer_union_member)
  147. {
  148. #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  149. #pragma GCC diagnostic push
  150. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  151. #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  152. {
  153. // double
  154. TestUnionMemberClass val1(1.0);
  155. msgpack::sbuffer sbuf;
  156. msgpack::pack(sbuf, val1);
  157. msgpack::object_handle oh =
  158. msgpack::unpack(sbuf.data(), sbuf.size());
  159. TestUnionMemberClass val2 = oh.get().as<TestUnionMemberClass>();
  160. EXPECT_EQ(val1.is_double, val2.is_double);
  161. EXPECT_TRUE(fabs(val1.value.f - val2.value.f) < kEPS);
  162. }
  163. {
  164. // int
  165. TestUnionMemberClass val1(1);
  166. msgpack::sbuffer sbuf;
  167. msgpack::pack(sbuf, val1);
  168. msgpack::object_handle oh =
  169. msgpack::unpack(sbuf.data(), sbuf.size());
  170. TestUnionMemberClass val2 = oh.get().as<TestUnionMemberClass>();
  171. EXPECT_EQ(val1.is_double, val2.is_double);
  172. EXPECT_EQ(val1.value.i, 1);
  173. EXPECT_EQ(val1.value.i, val2.value.i);
  174. }
  175. #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  176. #pragma GCC diagnostic pop
  177. #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  178. }
  179. // inheritance
  180. // define
  181. struct d_top {
  182. int t;
  183. MSGPACK_DEFINE(t);
  184. };
  185. struct d_mid1 : d_top {
  186. int m1;
  187. MSGPACK_DEFINE(MSGPACK_BASE(d_top), m1);
  188. };
  189. struct d_mid2 : d_top {
  190. int m2;
  191. MSGPACK_DEFINE(m2, MSGPACK_BASE(d_top));
  192. };
  193. struct d_bottom : d_mid1, d_mid2 {
  194. int b;
  195. MSGPACK_DEFINE(MSGPACK_BASE(d_mid1), MSGPACK_BASE(d_mid2), b);
  196. };
  197. TEST(MSGPACK_INHERIT, define_non_virtual)
  198. {
  199. d_bottom b;
  200. b.b = 1;
  201. b.m1 = 2;
  202. b.m2 = 3;
  203. b.d_mid1::t = 4;
  204. b.d_mid2::t = 5;
  205. msgpack::sbuffer sbuf;
  206. msgpack::pack(sbuf, b);
  207. msgpack::object_handle oh =
  208. msgpack::unpack(sbuf.data(), sbuf.size());
  209. d_bottom br = oh.get().as<d_bottom>();
  210. EXPECT_EQ(b.b, br.b);
  211. EXPECT_EQ(b.m1, br.m1);
  212. EXPECT_EQ(b.m2, br.m2);
  213. EXPECT_EQ(b.d_mid1::t, br.d_mid1::t);
  214. EXPECT_EQ(b.d_mid2::t, br.d_mid2::t);
  215. }
  216. struct v_d_top {
  217. int t;
  218. MSGPACK_DEFINE(t);
  219. };
  220. struct v_d_mid1 : virtual v_d_top {
  221. int m1;
  222. MSGPACK_DEFINE(m1);
  223. };
  224. struct v_d_mid2 : virtual v_d_top {
  225. int m2;
  226. MSGPACK_DEFINE(m2);
  227. };
  228. struct v_d_bottom : v_d_mid1, v_d_mid2 {
  229. int b;
  230. MSGPACK_DEFINE(MSGPACK_BASE(v_d_mid1), MSGPACK_BASE(v_d_mid2), MSGPACK_BASE(v_d_top), b);
  231. };
  232. TEST(MSGPACK_INHERIT, define_virtual)
  233. {
  234. v_d_bottom b;
  235. b.b = 1;
  236. b.m1 = 2;
  237. b.m2 = 3;
  238. b.t = 4;
  239. msgpack::sbuffer sbuf;
  240. msgpack::pack(sbuf, b);
  241. msgpack::object_handle oh =
  242. msgpack::unpack(sbuf.data(), sbuf.size());
  243. v_d_bottom br = oh.get().as<v_d_bottom>();
  244. EXPECT_EQ(b.b, br.b);
  245. EXPECT_EQ(b.m1, br.m1);
  246. EXPECT_EQ(b.m2, br.m2);
  247. EXPECT_EQ(b.t, br.t);
  248. }
  249. // define_array
  250. struct da_top {
  251. int t;
  252. MSGPACK_DEFINE_ARRAY(t);
  253. };
  254. struct da_mid1 : da_top {
  255. int m1;
  256. MSGPACK_DEFINE_ARRAY(MSGPACK_BASE_ARRAY(da_top), m1);
  257. };
  258. struct da_mid2 : da_top {
  259. int m2;
  260. MSGPACK_DEFINE_ARRAY(m2, MSGPACK_BASE_ARRAY(da_top));
  261. };
  262. struct da_bottom : da_mid1, da_mid2 {
  263. int b;
  264. MSGPACK_DEFINE_ARRAY(MSGPACK_BASE_ARRAY(da_mid1), MSGPACK_BASE_ARRAY(da_mid2), b);
  265. };
  266. TEST(MSGPACK_INHERIT, define_array_non_virtual)
  267. {
  268. da_bottom b;
  269. b.b = 1;
  270. b.m1 = 2;
  271. b.m2 = 3;
  272. b.da_mid1::t = 4;
  273. b.da_mid2::t = 5;
  274. msgpack::sbuffer sbuf;
  275. msgpack::pack(sbuf, b);
  276. msgpack::object_handle oh =
  277. msgpack::unpack(sbuf.data(), sbuf.size());
  278. da_bottom br = oh.get().as<da_bottom>();
  279. EXPECT_EQ(b.b, br.b);
  280. EXPECT_EQ(b.m1, br.m1);
  281. EXPECT_EQ(b.m2, br.m2);
  282. EXPECT_EQ(b.da_mid1::t, br.da_mid1::t);
  283. EXPECT_EQ(b.da_mid2::t, br.da_mid2::t);
  284. }
  285. struct v_da_top {
  286. int t;
  287. MSGPACK_DEFINE_ARRAY(t);
  288. };
  289. struct v_da_mid1 : virtual v_da_top {
  290. int m1;
  291. MSGPACK_DEFINE_ARRAY(m1);
  292. };
  293. struct v_da_mid2 : virtual v_da_top {
  294. int m2;
  295. MSGPACK_DEFINE_ARRAY(m2);
  296. };
  297. struct v_da_bottom : v_da_mid1, v_da_mid2 {
  298. int b;
  299. MSGPACK_DEFINE_ARRAY(MSGPACK_BASE_ARRAY(v_da_mid1), MSGPACK_BASE_ARRAY(v_da_mid2), MSGPACK_BASE_ARRAY(v_da_top), b);
  300. };
  301. TEST(MSGPACK_INHERIT, define_array_virtual)
  302. {
  303. v_da_bottom b;
  304. b.b = 1;
  305. b.m1 = 2;
  306. b.m2 = 3;
  307. b.t = 4;
  308. msgpack::sbuffer sbuf;
  309. msgpack::pack(sbuf, b);
  310. msgpack::object_handle oh =
  311. msgpack::unpack(sbuf.data(), sbuf.size());
  312. v_da_bottom br = oh.get().as<v_da_bottom>();
  313. EXPECT_EQ(b.b, br.b);
  314. EXPECT_EQ(b.m1, br.m1);
  315. EXPECT_EQ(b.m2, br.m2);
  316. EXPECT_EQ(b.t, br.t);
  317. }
  318. // define_map
  319. struct dm_top {
  320. int t;
  321. MSGPACK_DEFINE_MAP(t);
  322. };
  323. struct dm_mid1 : dm_top {
  324. int m1;
  325. MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(dm_top), m1);
  326. };
  327. struct dm_mid2 : dm_top {
  328. int m2;
  329. MSGPACK_DEFINE_MAP(m2, MSGPACK_BASE_MAP(dm_top));
  330. };
  331. struct dm_bottom : dm_mid1, dm_mid2 {
  332. int b;
  333. MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(dm_mid1), MSGPACK_BASE_MAP(dm_mid2), b);
  334. };
  335. TEST(MSGPACK_INHERIT, define_map_non_virtual)
  336. {
  337. dm_bottom b;
  338. b.b = 1;
  339. b.m1 = 2;
  340. b.m2 = 3;
  341. b.dm_mid1::t = 4;
  342. b.dm_mid2::t = 5;
  343. msgpack::sbuffer sbuf;
  344. msgpack::pack(sbuf, b);
  345. msgpack::object_handle oh =
  346. msgpack::unpack(sbuf.data(), sbuf.size());
  347. #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  348. #pragma GCC diagnostic push
  349. #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  350. #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  351. dm_bottom br = oh.get().as<dm_bottom>();
  352. #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  353. #pragma GCC diagnostic pop
  354. #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__clang__)
  355. EXPECT_EQ(b.b, br.b);
  356. EXPECT_EQ(b.m1, br.m1);
  357. EXPECT_EQ(b.m2, br.m2);
  358. EXPECT_EQ(b.dm_mid1::t, br.dm_mid1::t);
  359. EXPECT_EQ(b.dm_mid2::t, br.dm_mid2::t);
  360. }
  361. struct v_dm_top {
  362. int t;
  363. MSGPACK_DEFINE_MAP(t);
  364. };
  365. struct v_dm_mid1 : virtual v_dm_top {
  366. int m1;
  367. MSGPACK_DEFINE_MAP(m1);
  368. };
  369. struct v_dm_mid2 : virtual v_dm_top {
  370. int m2;
  371. MSGPACK_DEFINE_MAP(m2);
  372. };
  373. struct v_dm_bottom : v_dm_mid1, v_dm_mid2 {
  374. int b;
  375. MSGPACK_DEFINE_MAP(MSGPACK_BASE_MAP(v_dm_mid1), MSGPACK_BASE_MAP(v_dm_mid2), MSGPACK_BASE_MAP(v_dm_top), b);
  376. };
  377. TEST(MSGPACK_INHERIT, define_map_virtual)
  378. {
  379. v_dm_bottom b;
  380. b.b = 1;
  381. b.m1 = 2;
  382. b.m2 = 3;
  383. b.t = 4;
  384. msgpack::sbuffer sbuf;
  385. msgpack::pack(sbuf, b);
  386. msgpack::object_handle oh =
  387. msgpack::unpack(sbuf.data(), sbuf.size());
  388. v_dm_bottom br = oh.get().as<v_dm_bottom>();
  389. EXPECT_EQ(b.b, br.b);
  390. EXPECT_EQ(b.m1, br.m1);
  391. EXPECT_EQ(b.m2, br.m2);
  392. EXPECT_EQ(b.t, br.t);
  393. }
  394. // map migration
  395. struct s_v1 {
  396. int i;
  397. std::string s;
  398. s_v1():i(42), s("foo") {}
  399. MSGPACK_DEFINE_MAP(i, s);
  400. };
  401. struct s_v2 {
  402. char c; // new member variable
  403. std::string s;
  404. int i;
  405. s_v2():c('A'), s("bar"), i(77) {}
  406. MSGPACK_DEFINE_MAP(c, s, i); // variable added, order changed
  407. };
  408. TEST(MSGPACK_MIGRATION, order_number_changed)
  409. {
  410. s_v1 v1;
  411. msgpack::sbuffer sbuf;
  412. msgpack::pack(sbuf, v1);
  413. msgpack::object_handle oh =
  414. msgpack::unpack(sbuf.data(), sbuf.size());
  415. s_v2 v2 = oh.get().as<s_v2>();
  416. EXPECT_EQ(v2.c, 'A');
  417. EXPECT_EQ(v2.s, "foo"); // from v1
  418. EXPECT_EQ(v2.i, 42); // from v1
  419. }
  420. // non intrusive with operator <<
  421. class test_non_intrusive {
  422. public:
  423. const std::string& name() const { return m_name; }
  424. void set_name(const std::string& name) { m_name = name; }
  425. private:
  426. std::string m_name;
  427. };
  428. namespace msgpack {
  429. MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
  430. namespace adaptor {
  431. template<>
  432. struct convert<test_non_intrusive>
  433. {
  434. msgpack::object const& operator()(
  435. msgpack::object const& o,
  436. test_non_intrusive& t) const {
  437. t.set_name(o.as<std::string>());
  438. return o;
  439. }
  440. };
  441. template<>
  442. struct pack<test_non_intrusive>
  443. {
  444. template <typename Stream>
  445. msgpack::packer<Stream>& operator()(
  446. msgpack::packer<Stream>& p,
  447. test_non_intrusive const& t) const {
  448. p.pack(t.name());
  449. return p;
  450. }
  451. };
  452. template <>
  453. struct object_with_zone<test_non_intrusive>
  454. {
  455. void operator()(
  456. msgpack::object::with_zone& o,
  457. const test_non_intrusive& t) const {
  458. o << t.name();
  459. }
  460. };
  461. } // namespace adaptor
  462. } // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
  463. } // namespace msgpack
  464. TEST(MSGPACK_USER_DEFINED, test_non_intrusive)
  465. {
  466. test_non_intrusive t1;
  467. msgpack::sbuffer sbuf;
  468. msgpack::pack(sbuf, t1);
  469. msgpack::object_handle oh =
  470. msgpack::unpack(sbuf.data(), sbuf.size());
  471. test_non_intrusive t2 = oh.get().as<test_non_intrusive>();
  472. EXPECT_EQ(t1.name(), t2.name());
  473. }
  474. struct nvp_base {
  475. int a;
  476. int b;
  477. MSGPACK_DEFINE_MAP(MSGPACK_NVP("aaa", a), b);
  478. };
  479. struct nvp_derived : nvp_base {
  480. int c;
  481. std::string d;
  482. MSGPACK_DEFINE_MAP(MSGPACK_NVP("ccc", c), MSGPACK_NVP("base", MSGPACK_BASE(nvp_base)), MSGPACK_NVP("ddd", d));
  483. };
  484. TEST(MSGPACK_NVP, combination)
  485. {
  486. msgpack::sbuffer sbuf;
  487. nvp_derived d1;
  488. d1.a = 1;
  489. d1.b = 2;
  490. d1.c = 3;
  491. d1.d = "ABC";
  492. msgpack::pack(sbuf, d1);
  493. msgpack::object_handle oh = msgpack::unpack(sbuf.data(), sbuf.size());
  494. msgpack::object obj = oh.get();
  495. EXPECT_EQ(obj.via.map.size, static_cast<size_t>(3));
  496. EXPECT_EQ(std::string(obj.via.map.ptr[0].key.via.str.ptr, obj.via.map.ptr[0].key.via.str.size), "ccc");
  497. EXPECT_EQ(obj.via.map.ptr[0].val.via.i64, 3);
  498. EXPECT_EQ(std::string(obj.via.map.ptr[1].key.via.str.ptr, obj.via.map.ptr[1].key.via.str.size), "base");
  499. EXPECT_EQ(obj.via.map.ptr[1].val.via.map.size, static_cast<size_t>(2));
  500. EXPECT_EQ(
  501. std::string(
  502. obj.via.map.ptr[1].val.via.map.ptr[0].key.via.str.ptr,
  503. obj.via.map.ptr[1].val.via.map.ptr[0].key.via.str.size),
  504. "aaa"
  505. );
  506. EXPECT_EQ(obj.via.map.ptr[1].val.via.map.ptr[0].val.via.i64, 1);
  507. EXPECT_EQ(
  508. std::string(
  509. obj.via.map.ptr[1].val.via.map.ptr[1].key.via.str.ptr,
  510. obj.via.map.ptr[1].val.via.map.ptr[1].key.via.str.size),
  511. "b"
  512. );
  513. EXPECT_EQ(obj.via.map.ptr[1].val.via.map.ptr[1].val.via.i64, 2);
  514. EXPECT_EQ(std::string(obj.via.map.ptr[2].key.via.str.ptr, obj.via.map.ptr[2].key.via.str.size), "ddd");
  515. EXPECT_EQ(std::string(obj.via.map.ptr[2].val.via.str.ptr, obj.via.map.ptr[2].val.via.str.size), "ABC");
  516. nvp_derived d2 = obj.as<nvp_derived>();
  517. EXPECT_EQ(d2.a, 1);
  518. EXPECT_EQ(d2.b, 2);
  519. EXPECT_EQ(d2.c, 3);
  520. EXPECT_EQ(d2.d, "ABC");
  521. }
  522. struct invalid_key {
  523. int val;
  524. MSGPACK_DEFINE_MAP(val);
  525. };
  526. TEST(MSGPACK_USER_DEFINED, test_invalid_key_type)
  527. {
  528. msgpack::sbuffer sbuf;
  529. msgpack::packer<msgpack::sbuffer> pk(sbuf);
  530. pk.pack_map(1);
  531. pk.pack_int(42);
  532. pk.pack_int(43);
  533. msgpack::object_handle oh = msgpack::unpack(sbuf.data(), sbuf.size());
  534. try {
  535. oh.get().as<invalid_key>();
  536. EXPECT_TRUE(false);
  537. }
  538. catch (msgpack::type_error const&) {
  539. EXPECT_TRUE(true);
  540. }
  541. catch (...) {
  542. EXPECT_TRUE(false);
  543. }
  544. }