Skip to content

Commit 9314232

Browse files
committed
Merge pull request #349 from redboltz/variant
Variant
2 parents 3352b2f + d17c70c commit 9314232

File tree

12 files changed

+1489
-0
lines changed

12 files changed

+1489
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ IF (MSGPACK_ENABLE_CXX)
167167
include/msgpack/adaptor/array_ref.hpp
168168
include/msgpack/adaptor/bool.hpp
169169
include/msgpack/adaptor/boost/fusion.hpp
170+
include/msgpack/adaptor/boost/msgpack_variant.hpp
170171
include/msgpack/adaptor/boost/optional.hpp
171172
include/msgpack/adaptor/boost/string_ref.hpp
172173
include/msgpack/adaptor/char_ptr.hpp

example/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
ADD_SUBDIRECTORY (c)
22
ADD_SUBDIRECTORY (cpp03)
33
ADD_SUBDIRECTORY (cpp11)
4+
ADD_SUBDIRECTORY (boost)

example/boost/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
IF (MSGPACK_BOOST)
2+
LIST (APPEND exec_PROGRAMS
3+
msgpack_variant_capitalize.cpp
4+
msgpack_variant_mapbased.cpp
5+
)
6+
ENDIF ()
7+
8+
FOREACH (source_file ${exec_PROGRAMS})
9+
GET_FILENAME_COMPONENT (source_file_we ${source_file} NAME_WE)
10+
ADD_EXECUTABLE (
11+
${source_file_we}
12+
${source_file}
13+
)
14+
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
15+
SET_PROPERTY (TARGET ${source_file_we} APPEND_STRING PROPERTY COMPILE_FLAGS "-Wall -Wextra -Werror -Wno-mismatched-tags -g -O3")
16+
ENDIF ()
17+
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
18+
IF (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
19+
STRING(REGEX REPLACE "/W[0-4]" "/W3 /WX" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
20+
ELSE ()
21+
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /WX")
22+
ENDIF ()
23+
ENDIF ()
24+
ENDFOREACH ()
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// MessagePack for C++ example
2+
//
3+
// Copyright (C) 2015 KONDO Takatoshi
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
//
17+
18+
#include <string>
19+
#include <sstream>
20+
#include <iostream>
21+
#include <algorithm>
22+
#include <cctype>
23+
24+
#include <msgpack.hpp>
25+
26+
struct user {
27+
std::string name;
28+
int age;
29+
std::string address;
30+
MSGPACK_DEFINE(name, age, address);
31+
};
32+
33+
struct proc:boost::static_visitor<void> {
34+
void operator()(std::string& v) const {
35+
std::cout << " match std::string& v" << std::endl;
36+
std::cout << " v: " << v << std::endl;
37+
std::cout << " capitalize" << std::endl;
38+
for (std::string::iterator it = v.begin(), end = v.end();
39+
it != end;
40+
++it) {
41+
*it = std::toupper(*it);
42+
}
43+
}
44+
void operator()(std::vector<msgpack::type::variant>& v) const {
45+
std::cout << "match vector (msgpack::type::ARRAY)" << std::endl;
46+
std::vector<msgpack::type::variant>::iterator it = v.begin();
47+
std::vector<msgpack::type::variant>::const_iterator end = v.end();
48+
for (; it != end; ++it) {
49+
boost::apply_visitor(*this, *it);
50+
}
51+
}
52+
template <typename T>
53+
void operator()(T const&) const {
54+
std::cout << " match others" << std::endl;
55+
}
56+
};
57+
58+
void print(std::string const& buf) {
59+
for (std::string::const_iterator it = buf.begin(), end = buf.end();
60+
it != end;
61+
++it) {
62+
std::cout
63+
<< std::setw(2)
64+
<< std::hex
65+
<< std::setfill('0')
66+
<< (static_cast<int>(*it) & 0xff)
67+
<< ' ';
68+
}
69+
std::cout << std::dec << std::endl;
70+
}
71+
72+
73+
int main() {
74+
std::stringstream ss1;
75+
user u;
76+
u.name = "Takatoshi Kondo";
77+
u.age = 42;
78+
u.address = "Tokyo, JAPAN";
79+
80+
std::cout << "Packing object." << std::endl;
81+
msgpack::pack(ss1, u);
82+
print(ss1.str());
83+
84+
msgpack::unpacked unp1 = msgpack::unpack(ss1.str().data(), ss1.str().size());
85+
msgpack::object const& obj1 = unp1.get();
86+
std::cout << "Unpacked msgpack object." << std::endl;
87+
std::cout << obj1 << std::endl;
88+
89+
msgpack::type::variant v = obj1.as<msgpack::type::variant>();
90+
std::cout << "Applying proc..." << std::endl;
91+
boost::apply_visitor(proc(), v);
92+
93+
std::stringstream ss2;
94+
std::cout << "Packing modified object." << std::endl;
95+
msgpack::pack(ss2, v);
96+
print(ss2.str());
97+
98+
msgpack::unpacked unp2 = msgpack::unpack(ss2.str().data(), ss2.str().size());
99+
msgpack::object const& obj2 = unp2.get();
100+
std::cout << "Modified msgpack object." << std::endl;
101+
std::cout << obj2 << std::endl;
102+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// MessagePack for C++ example
2+
//
3+
// Copyright (C) 2015 KONDO Takatoshi
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
//
17+
18+
#include <string>
19+
#include <sstream>
20+
#include <iostream>
21+
22+
#include <msgpack.hpp>
23+
24+
struct user {
25+
std::string name;
26+
int age;
27+
std::string address;
28+
MSGPACK_DEFINE_MAP(name, age, address);
29+
};
30+
31+
struct proc:boost::static_visitor<void> {
32+
// msgpack::type::MAP is converted to std::multimap, not std::map.
33+
void operator()(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>& v) const {
34+
std::cout << "match map" << std::endl;
35+
std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::iterator it = v.begin();
36+
std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::iterator end = v.end();
37+
while(it != end) {
38+
boost::string_ref const& key = it->first.as_boost_string_ref();
39+
if (key == "name") {
40+
boost::string_ref const& value = it->second.as_boost_string_ref();
41+
if (value == "Takatoshi Kondo") {
42+
// You can add values to msgpack::type::variant_ref.
43+
v.insert(
44+
std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::value_type(
45+
"role",
46+
"msgpack-c committer"
47+
)
48+
);
49+
}
50+
++it;
51+
}
52+
else if (key == "age") {
53+
// You can remove key-value pair from msgpack::type::variant_ref
54+
55+
#if defined(MSGPACK_USE_CPP03)
56+
v.erase(it++);
57+
#else // defined(MSGPACK_USE_CPP03)
58+
# if MSGPACK_LIB_STD_CXX
59+
it = v.erase(std::multimap<msgpack::type::variant_ref, msgpack::type::variant_ref>::const_iterator(it));
60+
# else // MSGPACK_LIB_STD_CXX
61+
it = v.erase(it);
62+
# endif // MSGPACK_LIB_STD_CXX
63+
#endif // defined(MSGPACK_USE_CPP03)
64+
}
65+
else if (key == "address") {
66+
// When you want to append string
67+
// "Tokyo" -> "Tokyo, JAPAN"
68+
// Use msgpack::type::variant instead of msgpack::type::variant_ref
69+
// or do as follows:
70+
boost::string_ref const& value = it->second.as_boost_string_ref();
71+
it->second = std::string(&value.front(), value.size()) + ", JAPAN";
72+
++it;
73+
}
74+
}
75+
}
76+
template <typename T>
77+
void operator()(T const&) const {
78+
std::cout << " match others" << std::endl;
79+
}
80+
};
81+
82+
int main() {
83+
std::stringstream ss;
84+
user u;
85+
u.name = "Takatoshi Kondo";
86+
u.age = 42;
87+
u.address = "Tokyo";
88+
msgpack::pack(ss, u);
89+
90+
msgpack::unpacked unp = msgpack::unpack(ss.str().data(), ss.str().size());
91+
msgpack::object const& obj = unp.get();
92+
std::cout << "Unpacked msgpack object." << std::endl;
93+
std::cout << obj << std::endl;
94+
msgpack::type::variant_ref v = obj.as<msgpack::type::variant_ref>();
95+
std::cout << "Applying proc..." << std::endl;
96+
boost::apply_visitor(proc(), v);
97+
msgpack::zone z;
98+
std::cout << "Applied msgpack object." << std::endl;
99+
std::cout << msgpack::object(v, z) << std::endl;
100+
}

0 commit comments

Comments
 (0)