From fc7f4b8fba1ed63f700d690ce4904ec851fc20ab Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 28 Jun 2016 22:49:05 +0200 Subject: [PATCH 1/3] replace some raw loops with algorithms --- src/json.hpp | 62 +++++++++++++++++++++-------------------------- src/json.hpp.re2c | 62 +++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 70 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 35bdd293c..fcb5e733d 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -46,6 +46,7 @@ SOFTWARE. #include #include #include +#include #include #include #include @@ -1554,22 +1555,13 @@ class basic_json bool type_deduction = true, value_t manual_type = value_t::array) { - // the initializer list could describe an object - bool is_an_object = true; - // check if each element is an array with two elements whose first // element is a string - for (const auto& element : init) + bool is_an_object = std::all_of(init.begin(), init.end(), + [](const basic_json & element) { - if (not element.is_array() or element.size() != 2 - or not element[0].is_string()) - { - // we found an element that makes it impossible to use the - // initializer list as object - is_an_object = false; - break; - } - } + return element.is_array() and element.size() == 2 and element[0].is_string(); + }); // adjust type if type deduction is not wanted if (not type_deduction) @@ -1595,10 +1587,10 @@ class basic_json assert(m_value.object != nullptr); - for (auto& element : init) + std::for_each(init.begin(), init.end(), [this](const basic_json & element) { m_value.object->emplace(*(element[0].m_value.string), element[1]); - } + }); } else { @@ -3235,11 +3227,13 @@ class basic_json // operator[] only works for arrays if (is_array()) { - // fill up array with null values until given idx is reached + // fill up array with null values if given idx is outside range assert(m_value.array != nullptr); - for (size_t i = m_value.array->size(); i <= idx; ++i) + if (idx >= m_value.array->size()) { - m_value.array->push_back(basic_json()); + m_value.array->insert(m_value.array->end(), + idx - m_value.array->size() + 1, + basic_json()); } return m_value.array->operator[](idx); @@ -5832,9 +5826,8 @@ class basic_json */ static std::size_t extra_space(const string_t& s) noexcept { - std::size_t result = 0; - - for (const auto& c : s) + return std::accumulate(s.begin(), s.end(), size_t{}, + [](size_t res, typename string_t::value_type c) { switch (c) { @@ -5847,8 +5840,7 @@ class basic_json case '\t': { // from c (1 byte) to \x (2 bytes) - result += 1; - break; + return res + 1; } default: @@ -5856,14 +5848,15 @@ class basic_json if (c >= 0x00 and c <= 0x1f) { // from c (1 byte) to \uxxxx (6 bytes) - result += 5; + return res + 5; + } + else + { + return res; } - break; } } - } - - return result; + }); } /*! @@ -8778,14 +8771,13 @@ basic_json_parser_63: */ std::string to_string() const noexcept { - std::string result; - - for (const auto& reference_token : reference_tokens) + return std::accumulate(reference_tokens.begin(), + reference_tokens.end(), std::string{}, + [](const std::string & a, + const std::string & b) { - result += "/" + escape(reference_token); - } - - return result; + return a + "/" + escape(b); + }); } /// @copydoc to_string() diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 016ff0c51..dea0f51c5 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -46,6 +46,7 @@ SOFTWARE. #include #include #include +#include #include #include #include @@ -1554,22 +1555,13 @@ class basic_json bool type_deduction = true, value_t manual_type = value_t::array) { - // the initializer list could describe an object - bool is_an_object = true; - // check if each element is an array with two elements whose first // element is a string - for (const auto& element : init) + bool is_an_object = std::all_of(init.begin(), init.end(), + [](const basic_json & element) { - if (not element.is_array() or element.size() != 2 - or not element[0].is_string()) - { - // we found an element that makes it impossible to use the - // initializer list as object - is_an_object = false; - break; - } - } + return element.is_array() and element.size() == 2 and element[0].is_string(); + }); // adjust type if type deduction is not wanted if (not type_deduction) @@ -1595,10 +1587,10 @@ class basic_json assert(m_value.object != nullptr); - for (auto& element : init) + std::for_each(init.begin(), init.end(), [this](const basic_json & element) { m_value.object->emplace(*(element[0].m_value.string), element[1]); - } + }); } else { @@ -3235,11 +3227,13 @@ class basic_json // operator[] only works for arrays if (is_array()) { - // fill up array with null values until given idx is reached + // fill up array with null values if given idx is outside range assert(m_value.array != nullptr); - for (size_t i = m_value.array->size(); i <= idx; ++i) + if (idx >= m_value.array->size()) { - m_value.array->push_back(basic_json()); + m_value.array->insert(m_value.array->end(), + idx - m_value.array->size() + 1, + basic_json()); } return m_value.array->operator[](idx); @@ -5832,9 +5826,8 @@ class basic_json */ static std::size_t extra_space(const string_t& s) noexcept { - std::size_t result = 0; - - for (const auto& c : s) + return std::accumulate(s.begin(), s.end(), size_t{}, + [](size_t res, typename string_t::value_type c) { switch (c) { @@ -5847,8 +5840,7 @@ class basic_json case '\t': { // from c (1 byte) to \x (2 bytes) - result += 1; - break; + return res + 1; } default: @@ -5856,14 +5848,15 @@ class basic_json if (c >= 0x00 and c <= 0x1f) { // from c (1 byte) to \uxxxx (6 bytes) - result += 5; + return res + 5; + } + else + { + return res; } - break; } } - } - - return result; + }); } /*! @@ -8088,14 +8081,13 @@ class basic_json */ std::string to_string() const noexcept { - std::string result; - - for (const auto& reference_token : reference_tokens) + return std::accumulate(reference_tokens.begin(), + reference_tokens.end(), std::string{}, + [](const std::string & a, + const std::string & b) { - result += "/" + escape(reference_token); - } - - return result; + return a + "/" + escape(b); + }); } /// @copydoc to_string() From a0609b2da311ab68978e136eac770bc7aed4bd95 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 29 Jun 2016 09:53:48 +0200 Subject: [PATCH 2/3] fixed coverage bug --- src/json.hpp | 3 +-- src/json.hpp.re2c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index fcb5e733d..78c5c54ee 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -8773,8 +8773,7 @@ basic_json_parser_63: { return std::accumulate(reference_tokens.begin(), reference_tokens.end(), std::string{}, - [](const std::string & a, - const std::string & b) + [](const std::string & a, const std::string & b) { return a + "/" + escape(b); }); diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index dea0f51c5..c484c5e8e 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -8083,8 +8083,7 @@ class basic_json { return std::accumulate(reference_tokens.begin(), reference_tokens.end(), std::string{}, - [](const std::string & a, - const std::string & b) + [](const std::string & a, const std::string & b) { return a + "/" + escape(b); }); From 52cbda80484d112d2af352ddd608ea3cb76d73db Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 29 Jun 2016 12:47:29 +0200 Subject: [PATCH 3/3] using std::advance where possible --- src/json.hpp | 12 ++++++------ src/json.hpp.re2c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 78c5c54ee..57618dd08 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -6606,13 +6606,13 @@ class basic_json { case basic_json::value_t::object: { - ++m_it.object_iterator; + std::advance(m_it.object_iterator, 1); break; } case basic_json::value_t::array: { - ++m_it.array_iterator; + std::advance(m_it.array_iterator, 1); break; } @@ -6643,13 +6643,13 @@ class basic_json { case basic_json::value_t::object: { - --m_it.object_iterator; + std::advance(m_it.object_iterator, -1); break; } case basic_json::value_t::array: { - --m_it.array_iterator; + std::advance(m_it.array_iterator, -1); break; } @@ -6761,7 +6761,7 @@ class basic_json case basic_json::value_t::array: { - m_it.array_iterator += i; + std::advance(m_it.array_iterator, i); break; } @@ -6835,7 +6835,7 @@ class basic_json case basic_json::value_t::array: { - return *(m_it.array_iterator + n); + return *std::next(m_it.array_iterator, n); } case basic_json::value_t::null: diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index c484c5e8e..cf0d4df83 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -6606,13 +6606,13 @@ class basic_json { case basic_json::value_t::object: { - ++m_it.object_iterator; + std::advance(m_it.object_iterator, 1); break; } case basic_json::value_t::array: { - ++m_it.array_iterator; + std::advance(m_it.array_iterator, 1); break; } @@ -6643,13 +6643,13 @@ class basic_json { case basic_json::value_t::object: { - --m_it.object_iterator; + std::advance(m_it.object_iterator, -1); break; } case basic_json::value_t::array: { - --m_it.array_iterator; + std::advance(m_it.array_iterator, -1); break; } @@ -6761,7 +6761,7 @@ class basic_json case basic_json::value_t::array: { - m_it.array_iterator += i; + std::advance(m_it.array_iterator, i); break; } @@ -6835,7 +6835,7 @@ class basic_json case basic_json::value_t::array: { - return *(m_it.array_iterator + n); + return *std::next(m_it.array_iterator, n); } case basic_json::value_t::null: