Caches iterators instead of invoking function calls on every iteration.
This caches iterators, i.e. especially the end iterator when possible.
The problem:
for (auto it = begin(seq); it != end(seq); ++it)
this has to call `end(seq)` on every iteration, since the compiler is
not able to reason about the call's site effects (to bad, huh).
Instead do it like this:
for (auto it = begin(seq), end = end(seq); it != end; ++it)
caching the end iterator.
Of course, still better would be:
for (auto&& each : seq)
if all you want is value semantics.
Why `auto&&` you may ask? Because it binds to everything and never copies!
Skim the referenced proposal (that was rejected, but nevertheless) for a
detailed explanation on range-based for loops and why `auto&&` is great.
Reference:
- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3853.htm
This commit is contained in:
+14
-20
@@ -61,12 +61,11 @@ struct Renderer : mapbox::util::static_visitor<>
|
||||
void operator()(const Object &object) const
|
||||
{
|
||||
out << "{";
|
||||
auto iterator = object.values.begin();
|
||||
while (iterator != object.values.end())
|
||||
for (auto it = object.values.begin(), end = object.values.end(); it != end;)
|
||||
{
|
||||
out << "\"" << (*iterator).first << "\":";
|
||||
mapbox::util::apply_visitor(Renderer(out), (*iterator).second);
|
||||
if (++iterator != object.values.end())
|
||||
out << "\"" << it->first << "\":";
|
||||
mapbox::util::apply_visitor(Renderer(out), it->second);
|
||||
if (++it != end)
|
||||
{
|
||||
out << ",";
|
||||
}
|
||||
@@ -77,12 +76,10 @@ struct Renderer : mapbox::util::static_visitor<>
|
||||
void operator()(const Array &array) const
|
||||
{
|
||||
out << "[";
|
||||
std::vector<Value>::const_iterator iterator;
|
||||
iterator = array.values.begin();
|
||||
while (iterator != array.values.end())
|
||||
for (auto it = array.values.cend(), end = array.values.cend(); it != end;)
|
||||
{
|
||||
mapbox::util::apply_visitor(Renderer(out), *iterator);
|
||||
if (++iterator != array.values.end())
|
||||
mapbox::util::apply_visitor(Renderer(out), *it);
|
||||
if (++it != end)
|
||||
{
|
||||
out << ",";
|
||||
}
|
||||
@@ -121,16 +118,15 @@ struct ArrayRenderer : mapbox::util::static_visitor<>
|
||||
void operator()(const Object &object) const
|
||||
{
|
||||
out.push_back('{');
|
||||
auto iterator = object.values.begin();
|
||||
while (iterator != object.values.end())
|
||||
for (auto it = object.values.begin(), end = object.values.end(); it != end;)
|
||||
{
|
||||
out.push_back('\"');
|
||||
out.insert(out.end(), (*iterator).first.begin(), (*iterator).first.end());
|
||||
out.insert(out.end(), it->first.begin(), it->first.end());
|
||||
out.push_back('\"');
|
||||
out.push_back(':');
|
||||
|
||||
mapbox::util::apply_visitor(ArrayRenderer(out), (*iterator).second);
|
||||
if (++iterator != object.values.end())
|
||||
mapbox::util::apply_visitor(ArrayRenderer(out), it->second);
|
||||
if (++it != end)
|
||||
{
|
||||
out.push_back(',');
|
||||
}
|
||||
@@ -141,12 +137,10 @@ struct ArrayRenderer : mapbox::util::static_visitor<>
|
||||
void operator()(const Array &array) const
|
||||
{
|
||||
out.push_back('[');
|
||||
std::vector<Value>::const_iterator iterator;
|
||||
iterator = array.values.begin();
|
||||
while (iterator != array.values.end())
|
||||
for (auto it = array.values.cbegin(), end = array.values.cend(); it != end;)
|
||||
{
|
||||
mapbox::util::apply_visitor(ArrayRenderer(out), *iterator);
|
||||
if (++iterator != array.values.end())
|
||||
mapbox::util::apply_visitor(ArrayRenderer(out), *it);
|
||||
if (++it != end)
|
||||
{
|
||||
out.push_back(',');
|
||||
}
|
||||
|
||||
@@ -132,9 +132,10 @@ inline std::string escape_JSON(const std::string &input)
|
||||
inline std::size_t URIDecode(const std::string &input, std::string &output)
|
||||
{
|
||||
auto src_iter = std::begin(input);
|
||||
const auto src_end = std::end(input);
|
||||
output.resize(input.size() + 1);
|
||||
std::size_t decoded_length = 0;
|
||||
for (decoded_length = 0; src_iter != std::end(input); ++decoded_length)
|
||||
for (decoded_length = 0; src_iter != src_end; ++decoded_length)
|
||||
{
|
||||
if (src_iter[0] == '%' && src_iter[1] && src_iter[2] && isxdigit(src_iter[1]) &&
|
||||
isxdigit(src_iter[2]))
|
||||
|
||||
+8
-13
@@ -56,38 +56,33 @@ struct XMLToArrayRenderer : mapbox::util::static_visitor<>
|
||||
|
||||
void operator()(const Object &object) const
|
||||
{
|
||||
auto iterator = object.values.begin();
|
||||
while (iterator != object.values.end())
|
||||
for (auto &&each : object.values)
|
||||
{
|
||||
if (iterator->first.at(0) != '_')
|
||||
if (each.first.at(0) != '_')
|
||||
{
|
||||
out.push_back('<');
|
||||
out.insert(out.end(), (*iterator).first.begin(), (*iterator).first.end());
|
||||
out.insert(out.end(), each.first.begin(), each.first.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
out.push_back(' ');
|
||||
out.insert(out.end(), ++(*iterator).first.begin(), (*iterator).first.end());
|
||||
out.insert(out.end(), ++(each).first.begin(), each.first.end());
|
||||
out.push_back('=');
|
||||
}
|
||||
mapbox::util::apply_visitor(XMLToArrayRenderer(out), (*iterator).second);
|
||||
if (iterator->first.at(0) != '_')
|
||||
mapbox::util::apply_visitor(XMLToArrayRenderer(out), each.second);
|
||||
if (each.first.at(0) != '_')
|
||||
{
|
||||
out.push_back('/');
|
||||
out.push_back('>');
|
||||
}
|
||||
++iterator;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const Array &array) const
|
||||
{
|
||||
std::vector<Value>::const_iterator iterator;
|
||||
iterator = array.values.begin();
|
||||
while (iterator != array.values.end())
|
||||
for (auto &&each : array.values)
|
||||
{
|
||||
mapbox::util::apply_visitor(XMLToArrayRenderer(out), *iterator);
|
||||
++iterator;
|
||||
mapbox::util::apply_visitor(XMLToArrayRenderer(out), each);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user