boost_fusion.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include <msgpack.hpp>
  2. #include <sstream>
  3. #include <iterator>
  4. #include <cmath>
  5. #include <gtest/gtest.h>
  6. #ifdef HAVE_CONFIG_H
  7. #include "config.h"
  8. #endif
  9. #if defined(MSGPACK_USE_BOOST)
  10. #include <boost/fusion/adapted/struct/define_struct.hpp>
  11. #include <boost/fusion/adapted/struct/adapt_struct.hpp>
  12. const double kEPS = 1e-10;
  13. BOOST_FUSION_DEFINE_STRUCT(
  14. BOOST_PP_EMPTY(),
  15. mystruct,
  16. (int, f1)
  17. (double, f2)
  18. )
  19. TEST(MSGPACK_BOOST, fusion_pack_unpack_convert)
  20. {
  21. std::stringstream ss;
  22. mystruct val1;
  23. val1.f1 = 42;
  24. val1.f2 = 123.45;
  25. msgpack::pack(ss, val1);
  26. msgpack::object_handle oh =
  27. msgpack::unpack(ss.str().data(), ss.str().size());
  28. mystruct val2 = oh.get().as<mystruct>();
  29. EXPECT_TRUE(val1.f1 == val2.f1);
  30. EXPECT_TRUE(fabs(val2.f2 - val1.f2) <= kEPS);
  31. }
  32. TEST(MSGPACK_BOOST, object_with_zone_convert)
  33. {
  34. mystruct val1;
  35. val1.f1 = 42;
  36. val1.f2 = 123.45;
  37. msgpack::zone z;
  38. msgpack::object obj(val1, z);
  39. mystruct val2 = obj.as<mystruct>();
  40. EXPECT_TRUE(val1.f1 == val2.f1);
  41. EXPECT_TRUE(fabs(val2.f2 - val1.f2) <= kEPS);
  42. }
  43. #if !defined(MSGPACK_USE_CPP03)
  44. struct no_def_con1 {
  45. no_def_con1() = delete;
  46. no_def_con1(int i):i(i) {}
  47. int i;
  48. MSGPACK_DEFINE(i);
  49. };
  50. inline bool operator==(no_def_con1 const& lhs, no_def_con1 const& rhs) {
  51. return lhs.i == rhs.i;
  52. }
  53. inline bool operator!=(no_def_con1 const& lhs, no_def_con1 const& rhs) {
  54. return !(lhs == rhs);
  55. }
  56. struct no_def_con2 {
  57. no_def_con2() = delete;
  58. no_def_con2(int i):i(i) {}
  59. int i;
  60. MSGPACK_DEFINE(i);
  61. };
  62. inline bool operator==(no_def_con2 const& lhs, no_def_con2 const& rhs) {
  63. return lhs.i == rhs.i;
  64. }
  65. inline bool operator!=(no_def_con2 const& lhs, no_def_con2 const& rhs) {
  66. return !(lhs == rhs);
  67. }
  68. namespace msgpack {
  69. MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
  70. namespace adaptor {
  71. template <>
  72. struct as<no_def_con1> {
  73. no_def_con1 operator()(msgpack::object const& o) const {
  74. if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
  75. if (o.via.array.size != 1) throw msgpack::type_error();
  76. return no_def_con1(o.via.array.ptr[0].as<int>());
  77. }
  78. };
  79. template <>
  80. struct as<no_def_con2> {
  81. no_def_con2 operator()(msgpack::object const& o) const {
  82. if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
  83. if (o.via.array.size != 1) throw msgpack::type_error();
  84. return no_def_con2(o.via.array.ptr[0].as<int>());
  85. }
  86. };
  87. } // adaptor
  88. } // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
  89. } // msgpack
  90. struct mystruct_no_def_con {
  91. mystruct_no_def_con() = delete;
  92. // Constructor that have parameters corresponding to BOOST_FUSION_ADAPT_STRUCT is mandatory.
  93. // See *1, *2, and *3
  94. mystruct_no_def_con(
  95. no_def_con1 i,
  96. no_def_con2 j,
  97. no_def_con1 k):
  98. f1(std::move(i)),
  99. f2(std::move(j)),
  100. f3(std::move(k)) {}
  101. no_def_con1 f1;
  102. no_def_con2 f2;
  103. no_def_con1 f3;
  104. };
  105. inline bool operator==(mystruct_no_def_con const& lhs, mystruct_no_def_con const& rhs) {
  106. return lhs.f1 == rhs.f1 && lhs.f2 == rhs.f2 && lhs.f3 == rhs.f3;
  107. }
  108. inline bool operator!=(mystruct_no_def_con const& lhs, mystruct_no_def_con const& rhs) {
  109. return !(lhs == rhs);
  110. }
  111. BOOST_FUSION_ADAPT_STRUCT(
  112. mystruct_no_def_con,
  113. f1, // *1
  114. f2, // *2
  115. f3 // *3
  116. )
  117. // MSVC2015's std::tuple requires default constructor during 'as' process.
  118. // It doesn't support Expression SFINAE yet, then 'as' is fallbacked to 'convert'.
  119. // After MSVC would support Expression SFINAE, remove this guard.
  120. #if !defined(_MSC_VER)
  121. TEST(MSGPACK_BOOST, pack_convert_no_def_con)
  122. {
  123. std::stringstream ss;
  124. mystruct_no_def_con val1(no_def_con1(1), no_def_con2(2), no_def_con1(3));
  125. msgpack::pack(ss, val1);
  126. msgpack::object_handle oh =
  127. msgpack::unpack(ss.str().data(), ss.str().size());
  128. mystruct_no_def_con val2 = oh.get().as<mystruct_no_def_con>();
  129. EXPECT_TRUE(val1 == val2);
  130. }
  131. #endif // !defined(_MSC_VER)
  132. struct mystruct_no_def_con_def_con {
  133. mystruct_no_def_con_def_con() = delete;
  134. // Constructor that have parameters corresponding to BOOST_FUSION_ADAPT_STRUCT is mandatory.
  135. // See *1, *2, and *3
  136. mystruct_no_def_con_def_con(
  137. no_def_con1 i,
  138. no_def_con2 j,
  139. int k):
  140. f1(std::move(i)),
  141. f2(std::move(j)),
  142. f3(std::move(k)) {}
  143. no_def_con1 f1;
  144. no_def_con2 f2;
  145. int f3;
  146. };
  147. inline bool operator==(mystruct_no_def_con_def_con const& lhs, mystruct_no_def_con_def_con const& rhs) {
  148. return lhs.f1 == rhs.f1 && lhs.f2 == rhs.f2 && lhs.f3 == rhs.f3;
  149. }
  150. inline bool operator!=(mystruct_no_def_con_def_con const& lhs, mystruct_no_def_con_def_con const& rhs) {
  151. return !(lhs == rhs);
  152. }
  153. BOOST_FUSION_ADAPT_STRUCT(
  154. mystruct_no_def_con_def_con,
  155. f1, // *1
  156. f2, // *2
  157. f3 // *3
  158. )
  159. // MSVC2015's std::tuple requires default constructor during 'as' process.
  160. // It doesn't support Expression SFINAE yet, then 'as' is fallbacked to 'convert'.
  161. // After MSVC would support Expression SFINAE, remove this guard.
  162. #if !defined(_MSC_VER)
  163. TEST(MSGPACK_BOOST, pack_convert_no_def_con_def_con)
  164. {
  165. std::stringstream ss;
  166. mystruct_no_def_con_def_con val1(no_def_con1(1), no_def_con2(2), 3);
  167. msgpack::pack(ss, val1);
  168. msgpack::object_handle oh =
  169. msgpack::unpack(ss.str().data(), ss.str().size());
  170. mystruct_no_def_con_def_con val2 = oh.get().as<mystruct_no_def_con_def_con>();
  171. EXPECT_TRUE(val1 == val2);
  172. }
  173. #endif // !defined(_MSC_VER)
  174. #endif // !defined(MSGPACK_USE_CPP03
  175. #include <boost/fusion/include/std_pair.hpp>
  176. TEST(MSGPACK_BOOST, fusion_pack_unpack_convert_pair)
  177. {
  178. std::stringstream ss;
  179. std::pair<bool, int> val1(false, 42);
  180. msgpack::pack(ss, val1);
  181. msgpack::object_handle oh =
  182. msgpack::unpack(ss.str().data(), ss.str().size());
  183. std::pair<bool, int> val2 = oh.get().as<std::pair<bool, int> >();
  184. EXPECT_TRUE(val1.first == val2.first);
  185. EXPECT_TRUE(val1.second == val2.second);
  186. }
  187. #if !defined(MSGPACK_USE_CPP03)
  188. #include <boost/fusion/include/std_tuple.hpp>
  189. TEST(MSGPACK_BOOST, fusion_pack_unpack_convert_tuple)
  190. {
  191. std::stringstream ss;
  192. std::tuple<bool, int> val1(false, 42);
  193. msgpack::pack(ss, val1);
  194. msgpack::object_handle oh =
  195. msgpack::unpack(ss.str().data(), ss.str().size());
  196. std::tuple<bool, int> val2 = oh.get().as<std::tuple<bool, int> >();
  197. EXPECT_TRUE(val1 == val2);
  198. }
  199. #endif // !defined(MSGPACK_USE_CPP03)
  200. #endif // defined(MSGPACK_USE_BOOST)