Skip to content

Commit 9d19604

Browse files
author
me
committed
using a cpp file. might remove and make header-only
1 parent 2b94c09 commit 9d19604

File tree

1 file changed

+126
-0
lines changed

1 file changed

+126
-0
lines changed

src/msgpack.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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

Comments
 (0)