Refactor json renderer to share implementation for vector and string
This commit is contained in:
parent
463663b05e
commit
a9c72e393a
@ -27,18 +27,18 @@ namespace
|
|||||||
constexpr int MAX_FLOAT_STRING_LENGTH = 256;
|
constexpr int MAX_FLOAT_STRING_LENGTH = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Renderer
|
template <typename Out> struct Renderer
|
||||||
{
|
{
|
||||||
explicit Renderer(std::ostream &_out) : out(_out) {}
|
explicit Renderer(Out &_out) : out(_out) {}
|
||||||
|
|
||||||
void operator()(const String &string) const
|
void operator()(const String &string)
|
||||||
{
|
{
|
||||||
out << "\"";
|
write('"');
|
||||||
out << escape_JSON(string.value);
|
write(escape_JSON(string.value));
|
||||||
out << "\"";
|
write('"');
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const Number &number) const
|
void operator()(const Number &number)
|
||||||
{
|
{
|
||||||
char buffer[MAX_FLOAT_STRING_LENGTH] = {'\0'};
|
char buffer[MAX_FLOAT_STRING_LENGTH] = {'\0'};
|
||||||
ieee754::dtoa_milo(number.value, buffer);
|
ieee754::dtoa_milo(number.value, buffer);
|
||||||
@ -64,120 +64,72 @@ struct Renderer
|
|||||||
}
|
}
|
||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
out << buffer;
|
write(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const Object &object) const
|
void operator()(const Object &object)
|
||||||
{
|
{
|
||||||
out << "{";
|
write('{');
|
||||||
for (auto it = object.values.begin(), end = object.values.end(); it != end;)
|
for (auto it = object.values.begin(), end = object.values.end(); it != end;)
|
||||||
{
|
{
|
||||||
out << "\"" << it->first << "\":";
|
write('\"');
|
||||||
|
write(it->first);
|
||||||
|
write("\"");
|
||||||
mapbox::util::apply_visitor(Renderer(out), it->second);
|
mapbox::util::apply_visitor(Renderer(out), it->second);
|
||||||
if (++it != end)
|
if (++it != end)
|
||||||
{
|
{
|
||||||
out << ",";
|
write(',');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out << "}";
|
write('}');
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const Array &array) const
|
void operator()(const Array &array)
|
||||||
{
|
{
|
||||||
out << "[";
|
write('[');
|
||||||
for (auto it = array.values.cbegin(), end = array.values.cend(); it != end;)
|
for (auto it = array.values.cbegin(), end = array.values.cend(); it != end;)
|
||||||
{
|
{
|
||||||
mapbox::util::apply_visitor(Renderer(out), *it);
|
mapbox::util::apply_visitor(Renderer(out), *it);
|
||||||
if (++it != end)
|
if (++it != end)
|
||||||
{
|
{
|
||||||
out << ",";
|
write(',');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out << "]";
|
write(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(const True &) const { out << "true"; }
|
void operator()(const True &) { write("true"); }
|
||||||
|
|
||||||
void operator()(const False &) const { out << "false"; }
|
void operator()(const False &) { write("false"); }
|
||||||
|
|
||||||
void operator()(const Null &) const { out << "null"; }
|
void operator()(const Null &) { write("null"); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ostream &out;
|
void write(const std::string &str);
|
||||||
|
void write(const char *str);
|
||||||
|
void write(char ch);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Out &out;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ArrayRenderer
|
template <> void Renderer<std::vector<char>>::write(const std::string &str)
|
||||||
{
|
{
|
||||||
explicit ArrayRenderer(std::vector<char> &_out) : out(_out) {}
|
out.insert(out.end(), str.begin(), str.end());
|
||||||
|
}
|
||||||
|
|
||||||
void operator()(const String &string) const
|
template <> void Renderer<std::vector<char>>::write(const char *str)
|
||||||
{
|
{
|
||||||
out.push_back('\"');
|
out.insert(out.end(), str, str + strlen(str));
|
||||||
const auto string_to_insert = escape_JSON(string.value);
|
}
|
||||||
out.insert(std::end(out), std::begin(string_to_insert), std::end(string_to_insert));
|
|
||||||
out.push_back('\"');
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(const Number &number) const
|
template <> void Renderer<std::ostream>::write(const std::string &str) { out << str; }
|
||||||
{
|
|
||||||
const std::string number_string = cast::to_string_with_precision(number.value);
|
|
||||||
out.insert(out.end(), number_string.begin(), number_string.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(const Object &object) const
|
template <> void Renderer<std::ostream>::write(const char *str) { out << str; }
|
||||||
{
|
|
||||||
out.push_back('{');
|
|
||||||
for (auto it = object.values.begin(), end = object.values.end(); it != end;)
|
|
||||||
{
|
|
||||||
out.push_back('\"');
|
|
||||||
out.insert(out.end(), it->first.begin(), it->first.end());
|
|
||||||
out.push_back('\"');
|
|
||||||
out.push_back(':');
|
|
||||||
|
|
||||||
mapbox::util::apply_visitor(ArrayRenderer(out), it->second);
|
template <> void Renderer<std::vector<char>>::write(char ch) { out.push_back(ch); }
|
||||||
if (++it != end)
|
|
||||||
{
|
|
||||||
out.push_back(',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.push_back('}');
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(const Array &array) const
|
template <> void Renderer<std::ostream>::write(char ch) { out << ch; }
|
||||||
{
|
|
||||||
out.push_back('[');
|
|
||||||
for (auto it = array.values.cbegin(), end = array.values.cend(); it != end;)
|
|
||||||
{
|
|
||||||
mapbox::util::apply_visitor(ArrayRenderer(out), *it);
|
|
||||||
if (++it != end)
|
|
||||||
{
|
|
||||||
out.push_back(',');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out.push_back(']');
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(const True &) const
|
|
||||||
{
|
|
||||||
const std::string temp("true");
|
|
||||||
out.insert(out.end(), temp.begin(), temp.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(const False &) const
|
|
||||||
{
|
|
||||||
const std::string temp("false");
|
|
||||||
out.insert(out.end(), temp.begin(), temp.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void operator()(const Null &) const
|
|
||||||
{
|
|
||||||
const std::string temp("null");
|
|
||||||
out.insert(out.end(), temp.begin(), temp.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<char> &out;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void render(std::ostream &out, const Object &object)
|
inline void render(std::ostream &out, const Object &object)
|
||||||
{
|
{
|
||||||
@ -188,7 +140,7 @@ inline void render(std::ostream &out, const Object &object)
|
|||||||
inline void render(std::vector<char> &out, const Object &object)
|
inline void render(std::vector<char> &out, const Object &object)
|
||||||
{
|
{
|
||||||
Value value = object;
|
Value value = object;
|
||||||
mapbox::util::apply_visitor(ArrayRenderer(out), value);
|
mapbox::util::apply_visitor(Renderer(out), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace json
|
} // namespace json
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
|
#include "osrm/json_container.hpp"
|
||||||
#include "util/json_container.hpp"
|
#include "util/json_container.hpp"
|
||||||
#include "util/json_renderer.hpp"
|
#include "util/json_renderer.hpp"
|
||||||
#include "util/timing_util.hpp"
|
#include "util/timing_util.hpp"
|
||||||
#include "osrm/json_container.hpp"
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -123,18 +123,24 @@ int main(int, char **)
|
|||||||
{"in", 0}}}}}}
|
{"in", 0}}}}}}
|
||||||
|
|
||||||
}}}}}}}}}}}}}}}}};
|
}}}}}}}}}}}}}}}}};
|
||||||
json::Array arr;
|
json::Array arr;
|
||||||
for (size_t index = 0; index < 256; ++index) {
|
for (size_t index = 0; index < 4096; ++index)
|
||||||
|
{
|
||||||
arr.values.push_back(reference);
|
arr.values.push_back(reference);
|
||||||
}
|
}
|
||||||
json::Object obj{{{"arr", arr}}};
|
json::Object obj{{{"arr", arr}}};
|
||||||
std::string ss;
|
|
||||||
TIMER_START(create_object);
|
TIMER_START(stringstream);
|
||||||
|
std::stringstream ss;
|
||||||
json::render(ss, obj);
|
json::render(ss, obj);
|
||||||
//std::string s{ss.begin(), ss.end()};
|
std::string s{ss.str()};
|
||||||
TIMER_STOP(create_object);
|
TIMER_STOP(stringstream);
|
||||||
std::cout << TIMER_MSEC(create_object) << "ms"
|
std::cout << "String: " << TIMER_MSEC(stringstream) << "ms" << std::endl;
|
||||||
<< std::endl;
|
TIMER_START(vector);
|
||||||
|
std::vector<char> vec;
|
||||||
|
json::render(vec, obj);
|
||||||
|
TIMER_STOP(vector);
|
||||||
|
std::cout << "Vector: " << TIMER_MSEC(vector) << "ms" << std::endl;
|
||||||
// (void)s;
|
// (void)s;
|
||||||
// std::cerr << ss << "\n";
|
// std::cerr << ss << "\n";
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user