msgpack_variant_mapbased.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // MessagePack for C++ example
  2. //
  3. // Copyright (C) 2015 KONDO Takatoshi
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. #include <string>
  10. #include <sstream>
  11. #include <iostream>
  12. #include <msgpack.hpp>
  13. struct user {
  14. std::string name;
  15. int age;
  16. std::string address;
  17. MSGPACK_DEFINE_MAP(name, age, address);
  18. };
  19. struct proc:boost::static_visitor<void> {
  20. // msgpack::type::MAP is converted to std::multimap, not std::map.
  21. void operator()(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>& v) const {
  22. std::cout << "match map" << std::endl;
  23. std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::iterator it = v.begin();
  24. std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::iterator end = v.end();
  25. while(it != end) {
  26. boost::string_ref const& key = it->first.as_boost_string_ref();
  27. if (key == "name") {
  28. boost::string_ref const& value = it->second.as_boost_string_ref();
  29. if (value == "Takatoshi Kondo") {
  30. // You can add values to msgpack::type::variant_ref.
  31. v.insert(
  32. std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::value_type(
  33. "role",
  34. "msgpack-c committer"
  35. )
  36. );
  37. }
  38. ++it;
  39. }
  40. else if (key == "age") {
  41. // You can remove key-value pair from msgpack::type::variant_ref
  42. #if defined(MSGPACK_USE_CPP03)
  43. # if MSGPACK_LIB_STD_CXX
  44. v.erase(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::const_iterator(it++));
  45. # else // MSGPACK_LIB_STD_CXX
  46. v.erase(it++);
  47. # endif // MSGPACK_LIB_STD_CXX
  48. #else // defined(MSGPACK_USE_CPP03)
  49. # if MSGPACK_LIB_STD_CXX
  50. it = v.erase(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::const_iterator(it));
  51. # else // MSGPACK_LIB_STD_CXX
  52. it = v.erase(it);
  53. # endif // MSGPACK_LIB_STD_CXX
  54. #endif // defined(MSGPACK_USE_CPP03)
  55. }
  56. else if (key == "address") {
  57. // When you want to append string
  58. // "Tokyo" -> "Tokyo, JAPAN"
  59. // Use msgpack::type::variant instead of msgpack::type::variant_ref
  60. // or do as follows:
  61. boost::string_ref const& value = it->second.as_boost_string_ref();
  62. it->second = std::string(&value.front(), value.size()) + ", JAPAN";
  63. ++it;
  64. }
  65. }
  66. }
  67. template <typename T>
  68. void operator()(T const&) const {
  69. std::cout << " match others" << std::endl;
  70. }
  71. };
  72. int main() {
  73. std::stringstream ss;
  74. user u;
  75. u.name = "Takatoshi Kondo";
  76. u.age = 42;
  77. u.address = "Tokyo";
  78. msgpack::pack(ss, u);
  79. msgpack::object_handle oh = msgpack::unpack(ss.str().data(), ss.str().size());
  80. msgpack::object const& obj = oh.get();
  81. std::cout << "Unpacked msgpack object." << std::endl;
  82. std::cout << obj << std::endl;
  83. msgpack::type::variant_ref v = obj.as<msgpack::type::variant_ref>();
  84. std::cout << "Applying proc..." << std::endl;
  85. boost::apply_visitor(proc(), v);
  86. msgpack::zone z;
  87. std::cout << "Applied msgpack object." << std::endl;
  88. std::cout << msgpack::object(v, z) << std::endl;
  89. }