Compare commits
7
Commits
99759b82b7
...
11fdc64447
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11fdc64447 | ||
|
|
a92ac29d19 | ||
|
|
07df4054da | ||
|
|
2915c1c1ec | ||
|
|
161be80fd6 | ||
|
|
c3f5df7a29 | ||
|
|
93eb2f4f6a |
+11
-3
@@ -30,18 +30,26 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void clear() { m_elements.clear(); }
|
||||
void emplace_back(Value element);
|
||||
// Capacity
|
||||
|
||||
bool empty() const { return m_elements.empty(); }
|
||||
size_t size() const { return m_elements.size(); }
|
||||
void reserve(size_t size) { m_elements.reserve(size); }
|
||||
|
||||
// Element access
|
||||
|
||||
Value& operator[](size_t index);
|
||||
|
||||
Value& at(size_t index) { return m_elements.at(index); }
|
||||
const Value& at(size_t index) const { return m_elements.at(index); }
|
||||
|
||||
size_t size() const { return m_elements.size(); }
|
||||
const std::vector<Value>& elements() const { return m_elements; }
|
||||
|
||||
// Modifiers
|
||||
|
||||
void clear() { m_elements.clear(); }
|
||||
void emplace_back(Value element);
|
||||
|
||||
private:
|
||||
std::vector<Value> m_elements;
|
||||
};
|
||||
|
||||
+11
-3
@@ -27,17 +27,25 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
void clear() { m_members.clear(); }
|
||||
void emplace(const std::string& name, Value value);
|
||||
// Capacity
|
||||
|
||||
bool empty() const { return m_members.empty(); }
|
||||
size_t size() const { return m_members.size(); }
|
||||
|
||||
// Member access
|
||||
|
||||
Value& operator[](const std::string& name);
|
||||
|
||||
Value& at(const std::string& name) { return m_members.at(name); }
|
||||
const Value& at(const std::string& name) const { return m_members.at(name); }
|
||||
|
||||
size_t size() const { return m_members.size(); }
|
||||
const std::map<std::string, Value>& members() const { return m_members; }
|
||||
|
||||
// Modifiers
|
||||
|
||||
void clear() { m_members.clear(); }
|
||||
void emplace(const std::string& name, Value value);
|
||||
|
||||
private:
|
||||
std::map<std::string, Value> m_members;
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <cstdint> // uint32_t
|
||||
#include <iterator> // prev
|
||||
#include <iterator> // next
|
||||
#include <sstream> // ostringstream
|
||||
#include <string>
|
||||
|
||||
@@ -16,9 +16,8 @@
|
||||
|
||||
namespace Json {
|
||||
|
||||
Serializer::Serializer(const Value& value, const uint32_t indent, const char indentCharacter)
|
||||
: m_value(value)
|
||||
, m_indent(indent)
|
||||
Serializer::Serializer(const uint32_t indent, const char indentCharacter)
|
||||
: m_indent(indent)
|
||||
, m_indentCharacter(indentCharacter)
|
||||
{
|
||||
}
|
||||
@@ -29,112 +28,127 @@ Serializer::~Serializer()
|
||||
|
||||
// ------------------------------------------
|
||||
|
||||
std::string Serializer::dump()
|
||||
std::string Serializer::dump(const Value& value)
|
||||
{
|
||||
return dumpHelper(m_value);
|
||||
dumpHelper(value);
|
||||
return m_output;
|
||||
}
|
||||
|
||||
// ------------------------------------------
|
||||
|
||||
std::string Serializer::dumpHelper(const Value& value, const uint32_t indentLevel)
|
||||
void Serializer::dumpHelper(const Value& value, const uint32_t indentLevel)
|
||||
{
|
||||
switch (value.m_type) {
|
||||
case Value::Type::Null:
|
||||
return "null";
|
||||
m_output += "null";
|
||||
break;
|
||||
case Value::Type::Bool:
|
||||
return value.m_value.boolean ? "true" : "false";
|
||||
m_output += value.m_value.boolean ? "true" : "false";
|
||||
break;
|
||||
case Value::Type::Number: {
|
||||
std::ostringstream os;
|
||||
os << value.m_value.number;
|
||||
return os.str();
|
||||
m_output += os.str();
|
||||
break;
|
||||
}
|
||||
case Value::Type::String:
|
||||
return "\"" + *value.m_value.string + "\"";
|
||||
m_output += "\"" + *value.m_value.string + "\"";
|
||||
break;
|
||||
case Value::Type::Array:
|
||||
return dumpArray(value, indentLevel);
|
||||
dumpArray(value, indentLevel);
|
||||
break;
|
||||
case Value::Type::Object:
|
||||
return dumpObject(value, indentLevel);
|
||||
dumpObject(value, indentLevel);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string Serializer::dumpArray(const Value& value, const uint32_t indentLevel)
|
||||
void Serializer::dumpArray(const Value& value, const uint32_t indentLevel)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
// Append [
|
||||
result += "[";
|
||||
if (m_indent > 0) {
|
||||
result += '\n';
|
||||
m_output += '[';
|
||||
m_output += '\n';
|
||||
}
|
||||
|
||||
auto values = value.m_value.array->elements();
|
||||
for (auto it = values.begin(); it != values.end(); ++it) {
|
||||
result += std::string(m_indent * (indentLevel + 1), m_indentCharacter);
|
||||
result += dumpHelper(*it, indentLevel + 1);
|
||||
|
||||
// Add comma, except after the last element
|
||||
if (it != std::prev(values.end(), 1)) {
|
||||
result += ",";
|
||||
}
|
||||
if (m_indent > 0) {
|
||||
result += '\n';
|
||||
}
|
||||
// Empty Array early return
|
||||
if (value.m_value.array->empty()) {
|
||||
m_output += ']';
|
||||
return;
|
||||
}
|
||||
|
||||
// Append indentation
|
||||
result += std::string(m_indent * indentLevel, m_indentCharacter);
|
||||
size_t i = 0;
|
||||
auto it = value.m_value.array->elements().cbegin();
|
||||
if (!m_indent) {
|
||||
for (; i < value.m_value.array->size() - 1; ++i, ++it) {
|
||||
dumpHelper(*it, indentLevel + 1);
|
||||
m_output += ',';
|
||||
}
|
||||
dumpHelper(*it, indentLevel + 1);
|
||||
}
|
||||
else {
|
||||
std::string indentation = std::string(m_indent * (indentLevel + 1), m_indentCharacter);
|
||||
|
||||
// Append ]
|
||||
result += "]";
|
||||
for (; i < value.m_value.array->size() - 1; ++i, ++it) {
|
||||
m_output += indentation;
|
||||
dumpHelper(*it, indentLevel + 1);
|
||||
m_output += ",\n";
|
||||
}
|
||||
m_output += indentation;
|
||||
dumpHelper(*it, indentLevel + 1);
|
||||
m_output += '\n';
|
||||
|
||||
return result;
|
||||
// Append indentation
|
||||
m_output += std::string(m_indent * indentLevel, m_indentCharacter);
|
||||
}
|
||||
|
||||
m_output += "]";
|
||||
}
|
||||
|
||||
std::string Serializer::dumpObject(const Value& value, const uint32_t indentLevel)
|
||||
void Serializer::dumpObject(const Value& value, const uint32_t indentLevel)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
// Append {
|
||||
result += "{";
|
||||
if (m_indent > 0) {
|
||||
result += '\n';
|
||||
m_output += '{';
|
||||
m_output += '\n';
|
||||
}
|
||||
|
||||
auto members = value.m_value.object->members();
|
||||
for (auto it = members.begin(); it != members.end(); ++it) {
|
||||
result += std::string(m_indent * (indentLevel + 1), m_indentCharacter);
|
||||
result += "\"" + it->first + "\":";
|
||||
if (m_indent > 0) {
|
||||
result += ' ';
|
||||
}
|
||||
result += dumpHelper(it->second, indentLevel + 1);
|
||||
|
||||
// Add comma, except after the last element
|
||||
if (it != std::prev(members.end(), 1)) {
|
||||
result += ",";
|
||||
}
|
||||
if (m_indent > 0) {
|
||||
result += '\n';
|
||||
}
|
||||
// Empty Object early return
|
||||
if (value.m_value.object->empty()) {
|
||||
m_output += '}';
|
||||
return;
|
||||
}
|
||||
|
||||
// Append indentation
|
||||
result += std::string(m_indent * indentLevel, m_indentCharacter);
|
||||
size_t i = 0;
|
||||
auto it = value.m_value.object->members().cbegin();
|
||||
if (!m_indent) {
|
||||
for (; i < value.m_value.object->size() - 1; ++i, ++it) {
|
||||
m_output += '"' + it->first + "\":";
|
||||
dumpHelper(it->second, indentLevel + 1);
|
||||
m_output += ',';
|
||||
}
|
||||
m_output += '"' + it->first + "\":";
|
||||
dumpHelper(it->second, indentLevel + 1);
|
||||
}
|
||||
else {
|
||||
std::string indentation = std::string(m_indent * (indentLevel + 1), m_indentCharacter);
|
||||
|
||||
// Append }
|
||||
result += "}";
|
||||
for (; i < value.m_value.object->size() - 1; ++i, ++it) {
|
||||
m_output += indentation;
|
||||
m_output += '"' + it->first + "\": ";
|
||||
dumpHelper(it->second, indentLevel + 1);
|
||||
m_output += ",\n";
|
||||
}
|
||||
m_output += indentation;
|
||||
m_output += '"' + it->first + "\": ";
|
||||
dumpHelper(it->second, indentLevel + 1);
|
||||
m_output += '\n';
|
||||
|
||||
return result;
|
||||
// Append indentation
|
||||
m_output += std::string(m_indent * indentLevel, m_indentCharacter);
|
||||
}
|
||||
|
||||
m_output += '}';
|
||||
}
|
||||
|
||||
} // namespace Json
|
||||
|
||||
@@ -16,17 +16,17 @@ namespace Json {
|
||||
|
||||
class Serializer {
|
||||
public:
|
||||
Serializer(const Value& value, const uint32_t indent = 0, const char indentCharacter = ' ');
|
||||
Serializer(const uint32_t indent = 0, const char indentCharacter = ' ');
|
||||
virtual ~Serializer();
|
||||
|
||||
std::string dump();
|
||||
std::string dump(const Value& value);
|
||||
|
||||
private:
|
||||
std::string dumpHelper(const Value& value, const uint32_t indentLevel = 0);
|
||||
std::string dumpArray(const Value& value, const uint32_t indentLevel = 0);
|
||||
std::string dumpObject(const Value& value, const uint32_t indentLevel = 0);
|
||||
void dumpHelper(const Value& value, const uint32_t indentLevel = 0);
|
||||
void dumpArray(const Value& value, const uint32_t indentLevel = 0);
|
||||
void dumpObject(const Value& value, const uint32_t indentLevel = 0);
|
||||
|
||||
Value m_value;
|
||||
std::string m_output;
|
||||
|
||||
uint32_t m_indent { 0 };
|
||||
char m_indentCharacter { ' ' };
|
||||
|
||||
+10
-4
@@ -157,10 +157,17 @@ Value Value::parse(const std::string& input)
|
||||
return Job(input).fire();
|
||||
}
|
||||
|
||||
Value Value::parse(std::ifstream& file)
|
||||
{
|
||||
Value value;
|
||||
file >> value;
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string Value::dump(const uint32_t indent, const char indentCharacter) const
|
||||
{
|
||||
Serializer serializer(*this, indent, indentCharacter);
|
||||
return serializer.dump();
|
||||
Serializer serializer(indent, indentCharacter);
|
||||
return serializer.dump(*this);
|
||||
}
|
||||
|
||||
void Value::emplace_back(Value value)
|
||||
@@ -313,8 +320,7 @@ std::istream& operator>>(std::istream& input, Value& value)
|
||||
}
|
||||
inputString.append(buffer, input.gcount());
|
||||
|
||||
Job job(inputString);
|
||||
value = job.fire();
|
||||
value = Job(inputString).fire();
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
// --------------------------------------
|
||||
|
||||
static Value parse(const std::string& input);
|
||||
static Value parse(std::ifstream& file);
|
||||
std::string dump(const uint32_t indent = 0, const char indentCharacter = ' ') const;
|
||||
|
||||
void clear();
|
||||
|
||||
+47
-4
@@ -1,21 +1,57 @@
|
||||
#include <chrono> // high_resolution_clock, seconds, milliseconds, microseconds, nanoseconds
|
||||
#include <cstdint> // uint64_t
|
||||
#include <cstdio> // printf
|
||||
#include <cstdio> // printf
|
||||
|
||||
#include "util/timer.h"
|
||||
|
||||
namespace Util {
|
||||
|
||||
Timer::Timer()
|
||||
: m_start(std::chrono::high_resolution_clock::now())
|
||||
: m_running(true)
|
||||
, m_accumulated(TimePoint::min())
|
||||
, m_start(now())
|
||||
{
|
||||
}
|
||||
|
||||
Timer::Timer(const TimePoint& timePoint)
|
||||
: m_running(true)
|
||||
, m_accumulated(TimePoint::min())
|
||||
, m_start(timePoint)
|
||||
{
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
Timer Timer::operator-(const Timer& timer)
|
||||
{
|
||||
return Timer(TimePoint { m_start - timer.start() });
|
||||
}
|
||||
|
||||
TimePoint Timer::now()
|
||||
{
|
||||
return std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
void Timer::pause()
|
||||
{
|
||||
if (!m_running) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_accumulated += now() - m_start;
|
||||
m_running = false;
|
||||
}
|
||||
|
||||
void Timer::resume()
|
||||
{
|
||||
if (m_running) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_running = true;
|
||||
m_start = now();
|
||||
}
|
||||
|
||||
template<typename To, typename From>
|
||||
To Timer::to(From from)
|
||||
{
|
||||
@@ -45,8 +81,15 @@ uint64_t Timer::toNanoseconds()
|
||||
template<typename T>
|
||||
uint64_t Timer::elapsed()
|
||||
{
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
return std::chrono::duration_cast<T>(now - m_start).count();
|
||||
uint64_t elapsed = 0;
|
||||
|
||||
if (m_running) {
|
||||
elapsed += std::chrono::duration_cast<T>(now() - m_start).count();
|
||||
}
|
||||
|
||||
elapsed += std::chrono::duration_cast<T>(m_accumulated - TimePoint::min()).count();
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
uint64_t Timer::elapsedSeconds()
|
||||
|
||||
+7
-4
@@ -11,13 +11,14 @@ using TimePoint = std::chrono::high_resolution_clock::time_point;
|
||||
class Timer {
|
||||
public:
|
||||
Timer();
|
||||
Timer(const TimePoint& timePoint)
|
||||
: m_start(timePoint)
|
||||
{
|
||||
}
|
||||
Timer(const TimePoint& timePoint);
|
||||
|
||||
Timer operator-(const Timer& timer);
|
||||
|
||||
static TimePoint now();
|
||||
void pause();
|
||||
void resume();
|
||||
|
||||
template<typename To, typename From>
|
||||
To to(From from);
|
||||
uint64_t toSeconds();
|
||||
@@ -37,6 +38,8 @@ public:
|
||||
const TimePoint& start() const { return m_start; }
|
||||
|
||||
private:
|
||||
bool m_running { true };
|
||||
TimePoint m_accumulated;
|
||||
TimePoint m_start;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user