msgpack/example/boost/msgpack_variant_mapbased.cpp
Takatoshi Kondo 70f950ac05 Fixed #806.
Removed `ss.str().data()` (the type of ss is std::stringstream).
Introduced variable that is const reference of `ss.str()`.
2019-08-29 20:22:10 +09:00

98 lines
3.5 KiB
C++

// MessagePack for C++ example
//
// Copyright (C) 2015 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)
//
#include <string>
#include <sstream>
#include <iostream>
#include <msgpack.hpp>
struct user {
std::string name;
int age;
std::string address;
MSGPACK_DEFINE_MAP(name, age, address);
};
struct proc:boost::static_visitor<void> {
// msgpack::type::MAP is converted to std::multimap, not std::map.
void operator()(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>& v) const {
std::cout << "match map" << std::endl;
std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::iterator it = v.begin();
std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::iterator end = v.end();
while(it != end) {
boost::string_ref const& key = it->first.as_boost_string_ref();
if (key == "name") {
boost::string_ref const& value = it->second.as_boost_string_ref();
if (value == "Takatoshi Kondo") {
// You can add values to msgpack::type::variant_ref.
v.insert(
std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::value_type(
"role",
"msgpack-c committer"
)
);
}
++it;
}
else if (key == "age") {
// You can remove key-value pair from msgpack::type::variant_ref
#if defined(MSGPACK_USE_CPP03)
# if MSGPACK_LIB_STD_CXX
v.erase(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::const_iterator(it++));
# else // MSGPACK_LIB_STD_CXX
v.erase(it++);
# endif // MSGPACK_LIB_STD_CXX
#else // defined(MSGPACK_USE_CPP03)
# if MSGPACK_LIB_STD_CXX
it = v.erase(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::const_iterator(it));
# else // MSGPACK_LIB_STD_CXX
it = v.erase(it);
# endif // MSGPACK_LIB_STD_CXX
#endif // defined(MSGPACK_USE_CPP03)
}
else if (key == "address") {
// When you want to append string
// "Tokyo" -> "Tokyo, JAPAN"
// Use msgpack::type::variant instead of msgpack::type::variant_ref
// or do as follows:
boost::string_ref const& value = it->second.as_boost_string_ref();
it->second = std::string(&value.front(), value.size()) + ", JAPAN";
++it;
}
}
}
template <typename T>
void operator()(T const&) const {
std::cout << " match others" << std::endl;
}
};
int main() {
std::stringstream ss;
user u;
u.name = "Takatoshi Kondo";
u.age = 42;
u.address = "Tokyo";
msgpack::pack(ss, u);
std::string const& str = ss.str();
msgpack::object_handle oh = msgpack::unpack(str.data(), str.size());
msgpack::object const& obj = oh.get();
std::cout << "Unpacked msgpack object." << std::endl;
std::cout << obj << std::endl;
msgpack::type::variant_ref v = obj.as<msgpack::type::variant_ref>();
std::cout << "Applying proc..." << std::endl;
boost::apply_visitor(proc(), v);
msgpack::zone z;
std::cout << "Applied msgpack object." << std::endl;
std::cout << msgpack::object(v, z) << std::endl;
}