Home > c# > Yet another Pythonic range implementation for C++

Yet another Pythonic range implementation for C++

June 11Hits:6
Advertisement

I recently had the need to loop from zero to some limit only known at runtime. Instead of writing:

for(int i = 0; i < limit; ++i) {     // Some repetitive thing } 

I wanted to write something similar to what I often use in Python and D:

for i in range(0, limit):     # Some repetitive thing  foreach(i; 0 .. limit) {     // Some repetitive thing } 

So I ended up with the following:

#include <iterator>  namespace detail {     template< typename T >     class basic_range     {     public:         explicit basic_range(T const last, int const step = 1)             : basic_range(T{ 0 }, last, step)         {}          explicit basic_range(T const first, T const last, int const step = 1)             : first{ first, last, step }, last{ last, last, step }         {}          basic_range(basic_range const& other) = delete;         basic_range(basic_range && other) = default;         basic_range operator=(basic_range const& other) = delete;         basic_range operator=(basic_range && other) = delete;      public:         struct iterator : std::iterator< std::forward_iterator_tag, T >         {             explicit iterator(T const from, T const to, int const step = T{ 1 })                 : from{ from }, to{ to }, step{ step }             {}              iterator(iterator const& other) = default;             iterator(iterator && other) = delete;             iterator operator=(iterator const& other) = delete;             iterator operator=(iterator && other) = delete;              T const operator*() const { return from; }              bool operator==(iterator const& other) const { return from == other.from; }             bool operator!=(iterator const& other) const { return from != other.from; }              void operator++()             {                 from += step;                 check_limit();             }          private:             void check_limit()             {                 if (step > 0)                 {                     if (from > to)                     {                         from = to;                     }                 }                 else                 {                     if (from < to)                     {                         from = to;                     }                 }             }          private:             T         from;             T   const to;             int const step;         };          typedef iterator       iterator;         typedef iterator const const_iterator;          const_iterator begin() const { return first; }         const_iterator end()   const { return last; }      private:         const_iterator first;         const_iterator last;     };      template< typename T, bool is_enum = std::is_enum< T >::value >     struct get_integral_type     {         typedef std::underlying_type_t< T > type;     };      template< typename T >     struct get_integral_type< T, false >     {         typedef T type;     };      template< typename T, bool is_enum = std::is_enum< T >::value >     using get_integral_type_t = typename get_integral_type< T >::type; } 

With some supporting functions to aid in constructing a range:

template< typename T > auto range(T const begin, T const end, int const step = 1) {     typedef detail::get_integral_type_t< T > type;      static_assert(std::is_integral< type >::value,                   "Only integer-based types allowed!");      return detail::basic_range< type >{         static_cast<type>(begin),         static_cast<type>(end),         step     }; }  template< typename T, typename U > auto range(T const begin, U const end, int const step = 1) {     typedef std::common_type_t     <         detail::get_integral_type_t< T >,         detail::get_integral_type_t< U >     > type;      static_assert(std::is_integral< type >::value,                   "Only integer-based types allowed!");      return detail::basic_range< type >{         static_cast<type>(begin),         static_cast<type>(end),         step     }; }  template< typename T > auto reverse_range(T const from, T const to, int const step = -1) {     return range(from, to, step); }  template< typename T, typename U > auto reverse_range(T const from, U const to, int const step = -1) {     return range(from, to, step); } 

This allows for syntax very close to the Python version:

for(auto const i: range(0, limit)) {     // Some repetitive task } 

I am, so far, pleased with how well it works both forwards and backwards, however, I feel that the iterator implementation is sloppy and, since documentation on correct iterator implementation is hard to come by, I turn to the community to help me further refine this design. Of course, you are free to pick holes elsewhere. For example, I should probably check the inputs to the range functions before blindly returning an object that will misbehave...

A more complete example of usage can be found here which includes some simple unit tests to help debug the code. Any insights are appreciated

Tags:c++11

Related Articles

  • Yet another Pythonic range implementation for C++June 11

    I recently had the need to loop from zero to some limit only known at runtime. Instead of writing: for(int i = 0; i < limit; ++i) { // Some repetitive thing } I wanted to write something similar to what I often use in Python and D: for i in range(0,

  • Python boids implementation January 31

    I am trying to implement a fairly basic boids simulation in python. My goal is to have a simulation with a basic predator prey setup. I found some pseudocode (can't post more than two links but it is the first result if you google boids pseudocode) a

  • Why do these Python XTEA implementations require different deltas?December 23

    I once needed to an XTEA snippet to from C++ to Python and it did not work properly. I then found a function on ActiveState.com and noticed that it looks almost exactly like mine, with one exception - for some reason, its "delta" variable was ch

  • Python Vector implementation that acts as a class and also a collection of staticmethodsJune 21

    Recently I've been wondering about ways of implementing objects in code that can be represented by other primitives. An example of this is a Vector, which can be represented by a Vector\$N\$D where \$N\$ is the dimension of vector, or it can be repre

  • Python DefaultDict implementation in JavaScriptFebruary 8

    I found Python's defaultdict and OrderedDict incredibly useful, hence I attempted an implementation in JavaScript. As JavaScript objects only supports string as key, it is not as powerful as the Python version. Can anyone suggest a way of using an ob

  • Python property() implementation that caches getter while still allowing a setterMay 31

    For a session implementation I needed a property that caches its getter (since it involves a database lookup) but still allows modifications (e.g. assigning a new user and storing that user's id in the session). To make this as comfortable as possibl

  • Use python to implement a async notification systemJanuary 18

    I have been troubled by a design question. I want to implement a small service that looks like a mail office. It will accept clients request(in the request it has the message to deliver and destination url info). After that I will help the client to

  • Python's range() analog in Common LispDecember 18

    How to create a list of consecutive numbers in Common Lisp? In other words, what is the equivalent of Python's range function in Common Lisp? In Python range(2, 10, 2) returns [2, 4, 6, 8], with first and last arguments being optional. I couldn't fin

  • What interface does python use to implement sockets?April 29

    When I programmed in python, I believe I interfaced with the transport layer using sockets. If python was programmed by humans, they must have used an interface that was "lower" than sockets, to provide us with the interface to sockets. I assume

  • Python 3 PyPy implementation? April 23

    I would like to use the PyPy Python JIT Implementation using Python 3. However I can only seem to install it using Python 2. Is there even an experimental implementation of PyPy for Python 3 I can try out? Are there plans to port it to Python 3? Or d

  • A Range object for Java that partially implements `List`July 12

    I'm writing a neural net which uses a genetic algorithm to adjust the weights. To represent the possible range of "genes" for the GA, I'm passing in a list of bases. Unfortunately, I realized after the fact that there will be a huge possible ran

  • How to implement CSPRGs in Python?November 26

    I want to implement a CSPRNG for a stream cipher. I've tried implementing the BBS, but I've heard that it needs very big seeds to be secure. Is there a function in some library for Python 3 that adds a pseudo-random number generator that is secure an

  • Range iterator in ES6 similar to Python and Ruby forJanuary 3

    Background and Purpose For those unaccustomed to Ruby, Ruby supports range literals i.e. 1..4 meaning 1, 2, 3, 4 and 1...4 meaning 1, 2, 3. This makes a Ruby for loop pretty sweet: for i in 1..3 doSomething(i) end It works for non-numeric types and t

  • Python - How to make range queries in Azure Table StorageJanuary 17

    I am stuck trying to find the right syntax for creating a range query from python to an Azure Table Storage table. The continuation token cannot help me since I want to define a specific range or RowKeys and retrieve only those. I have been trying th

  • GDAL and Python: How to get coordinates for all cells having a specific value?

    GDAL and Python: How to get coordinates for all cells having a specific value?December 1

    I've got an Arc/Info Binary Grid---specifically, an ArcGIS flow accumulation raster---and I'd like to identify all cells having a specific value (or in a range of values). Ultimately, I'd like a shapefile of points representing these cells. I can use

  • Using a Pythonesque range() generator function with the Java foreach loopMarch 27

    Now that we have the nice new foreach loop in Java, the old-style loop looks ugly be comparison. I like the way Python has a range() generator that allows the foreach construct to iterate over a range of integers. I have written a Range class which a

  • Home on the Range of ListsMarch 4

    This challenge is simply to return a list of lists of integers, similar to the Python range function, except that each successive number must be that deep in lists. Rules: Create a program or a non-anonymous function It should return or print the res

  • Project Euler 50 in PythonMay 2

    Project Euler, problem #50: The prime 41, can be written as the sum of six consecutive primes: 41 = 2 + 3 + 5 + 7 + 11 + 13 This is the longest sum of consecutive primes that adds to a prime below one-hundred. The longest sum of consecutive primes be

  • Implement functional programming paradigmsSeptember 24

    Your company is just getting started on a project, and for the first time you decided to go use a functional programming code-style. However your boss is really diffident and doesn't want to use built-in functions, and requires you to implement yours

  • What is the best data model to represent mathematical range (in database, xml, json-)?October 5

    For example, greater or equal to 50 and smaller than 100 (>=50 && < 100) smaller than 10 or greater than 40 (<10 || >40) I have been thinking about how to represent mathematical range in a file and database, the range may be input by n

Copyright (C) 2018 ceus-now.com, All Rights Reserved. webmaster#ceus-now.com 14 q. 0.600 s.