GithubHelp home page GithubHelp logo

jkhoogland / cpp11-range Goto Github PK

View Code? Open in Web Editor NEW

This project forked from klmr/cpp11-range

0.0 2.0 0.0 13 KB

Range-based for loops to iterate over a range of numbers or values

License: Other

Makefile 1.83% C++ 98.17%

cpp11-range's Introduction

Re-imagining the for loop

C++11 now knows two distinct types of for loops: the classic loop over an “index” and the range-based for loop which vastly simplifies the iteration over a range specified by a pair of iterators.

By contrast, Python knows only one loop type – roughly equivalent to the range-based for loop. In fact, loops over indices are exceedingly rare, but made possible by the use of the range method:

for i in range(10):
    print i

Which does what it promises – although Python version < 3.0 does the “wrong” thing and actually instantiates the whole collection in memory at once; a remedy is xrange which yields values lazily as they are consumed by the loop.

C++11 effortlessly allows the same but there is no standard library function to provide this. Boost.Range provides part of the functionality via irange which only works on integers, and not for unlimited ranges (this will make sense in a second).

The header range.hpp provides a very basic implementation for this. It allows running the following code:

for (auto i : range(1, 5))
    cout << i << "\n";

for (auto u : range(0u))
    if (u == 3u) break;
    else         cout << u << "\n";

for (auto c : range('a', 'd'))
    cout << c << "\n";

for (auto i : range(100).step(-3))
    if (i < 90) break;
    else        cout << i << "\n";

range with a single argument deviates from the Python semantic and creates an endless loop, unless it’s interrupted manually. This is an interesting use-case that cannot be modelled in Python using range.

Iterating over container indices

In Python, the one-argument version of range is often used to iterate over the indices of a container via range(len(container)). Because that overload creates an infinite range in our C++ library, we cannot use this idiom.

But we can do better anyway. For those few cases where we actually want to iterate over a container’s indices, we just use the indices function:

std::vector<int> x{1, 2, 3};
for (auto i : indices(x))
    cout << i << '\n';

This works as expected for any type which has a member function size() const that returns some integral type. It also works with initializer_lists and C-style fixed-size arrays.1

Adding .step(…) to the end of either range or indices specifies a step size instead of the default, 1.

The construct works for arbitrary types which fulfil the interface requirements (incrementing, copying, equality comparison, default construction in the case of infinite ranges).

1 This includes string literals, which are C-style strings that include null termination; this may lead to surprising results, because indices("test") results in 0, 1, 2, 3, 4, whereas indices(std::string{"test"}) results in 0, 1, 2, 3.

Performance (the cost of beauty)

When compiling with optimisations enabled (and why wouldn’t you?), using the range function yield very similar output compared with a manual for loop. In fact, on g++ 4.8 with -O2 or higher, the following two loops yield identical assembly.

for (int i = 0; i < n; ++i)
    cout << i;

for (int i : range(0, n))
    cout << i;

Even though the range function creates a proxy container and an iterator wrapper, those are completely elided from the resulting code.

☞ Beauty is free.

cpp11-range's People

Contributors

klmr avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.