1+ #include < algorithm>
2+ #include " msgpack.h"
3+
4+ namespace msgpackcpp
5+ {
6+
7+ // ----------------------------------------------------------------------------------------------------------------
8+
9+ template <class ... Ts>
10+ struct overloaded : Ts... { using Ts::operator ()...; };
11+ template <class ... Ts>
12+ overloaded (Ts...) -> overloaded<Ts...>;
13+
14+ // ----------------------------------------------------------------------------------------------------------------
15+
16+ value::value (std::nullptr_t ) : val{nullptr } {}
17+ value::value (bool v) : val{v} {}
18+ value::value (const char * v) : val(std::string(v)) {}
19+ value::value (std::string_view v) : val(std::string(v)) {}
20+ value::value (std::string v) : val{std::move (v)} {}
21+ value::value (std::vector<value> v) : val{std::move (v)} {}
22+ value::value (std::map<std::string, value> v) : val{std::move (v)} {}
23+
24+ value::value (std::initializer_list<value> v)
25+ {
26+ const bool is_object = std::all_of (begin (v), end (v), [](const auto & el) {
27+ return el.is_array () && el.size () == 2 && el[0 ].is_str ();
28+ });
29+
30+ if (is_object)
31+ {
32+ auto & map = val.emplace <std::map<std::string, value>>();
33+ for (const auto & el : v)
34+ map.emplace (el[0 ].as_str (), el[1 ]);
35+ }
36+ else
37+ val.emplace <std::vector<value>>(v);
38+ }
39+
40+ // ----------------------------------------------------------------------------------------------------------------
41+
42+ size_t value::size () const noexcept
43+ {
44+ return std::visit (overloaded{
45+ [&](const std::vector<value>& v) {return v.size ();},
46+ [&](const std::map<std::string, value>& v) {return v.size ();},
47+ [&](std::nullptr_t ) {return (size_t )0 ;},
48+ [&](const auto &) {return (size_t )1 ;}
49+ }, val);
50+ }
51+
52+ // ----------------------------------------------------------------------------------------------------------------
53+
54+ bool value::is_null () const noexcept {return std::holds_alternative<std::nullptr_t >(val);}
55+ bool value::is_bool () const noexcept {return std::holds_alternative<bool >(val);}
56+ bool value::is_int () const noexcept {return std::holds_alternative<int64_t >(val) || std::holds_alternative<uint64_t >(val);}
57+ bool value::is_real () const noexcept {return std::holds_alternative<double >(val);}
58+ bool value::is_str () const noexcept {return std::holds_alternative<std::string>(val);}
59+ bool value::is_array () const noexcept {return std::holds_alternative<std::vector<value>>(val);}
60+ bool value::is_object () const noexcept {return std::holds_alternative<std::map<std::string, value>>(val);}
61+
62+ // ----------------------------------------------------------------------------------------------------------------
63+
64+ auto value::as_bool () const -> bool {return std::get<bool >(val);}
65+ auto value::as_bool () -> bool& {return std::get<bool >(val);}
66+ auto value::as_int64 () const -> int64_t {return std::get<int64_t >(val);}
67+ auto value::as_int64 () -> int64_t& {return std::get<int64_t >(val);}
68+ auto value::as_uint64 () const -> uint64_t {return std::get<uint64_t >(val);}
69+ auto value::as_uint64 () -> uint64_t& {return std::get<uint64_t >(val);}
70+ auto value::as_real () const -> double {return std::get<double >(val);}
71+ auto value::as_real () -> double& {return std::get<double >(val);}
72+ auto value::as_str () const -> const std::string& {return std::get<std::string>(val);}
73+ auto value::as_str () -> std::string& {return std::get<std::string>(val);}
74+ auto value::as_array () const -> const std::vector<value>& {return std::get<std::vector<value>>(val);}
75+ auto value::as_array () -> std::vector<value>& {return std::get<std::vector<value>>(val);}
76+ auto value::as_object () const -> const std::map<std::string, value>& {return std::get<std::map<std::string, value>>(val);}
77+ auto value::as_object () -> std::map<std::string, value>& {return std::get<std::map<std::string, value>>(val);}
78+
79+ // ----------------------------------------------------------------------------------------------------------------
80+
81+ const value& value::at (const std::string& key) const { return std::get<std::map<std::string, value>>(val).at (key); }
82+ value& value::at (const std::string& key) { return std::get<std::map<std::string, value>>(val).at (key); }
83+
84+ value& value::operator [](const std::string& key)
85+ {
86+ if (!std::holds_alternative<std::map<std::string, value>>(val))
87+ val.emplace <std::map<std::string, value>>();
88+ return std::get<std::map<std::string, value>>(val)[key];
89+ }
90+
91+ // ----------------------------------------------------------------------------------------------------------------
92+
93+ const value& value::operator [](size_t array_index) const { return std::get<std::vector<value>>(val)[array_index]; }
94+ value& value::operator [](size_t array_index) { return std::get<std::vector<value>>(val)[array_index]; }
95+
96+ // ----------------------------------------------------------------------------------------------------------------
97+
98+ struct deserialization_error_category : std::error_category
99+ {
100+ const char * name () const noexcept override
101+ {
102+ return " msgpack deserialization" ;
103+ }
104+
105+ std::string message (int ev) const override
106+ {
107+ switch (static_cast <deserialization_error>(ev))
108+ {
109+ case OUT_OF_DATA: return " Ran out of data while deserializing" ;
110+ case BAD_FORMAT: return " Found bad format" ;
111+ case BAD_SIZE: return " Found bad size" ;
112+ case BAD_NAME: return " Found bad name" ;
113+ default : return " Unrecognised error" ;
114+ }
115+ }
116+ };
117+
118+ std::error_code make_error_code (deserialization_error ec)
119+ {
120+ static const deserialization_error_category singleton;
121+ return {static_cast <int >(ec), singleton};
122+ }
123+
124+ // ----------------------------------------------------------------------------------------------------------------
125+
126+ }
0 commit comments