-3

I'd like to write a short for-loop (with or without macro) that works by guessing if the start point is smaller or bigger (or equal) to the end point, something like this:

fr(i = 0 .. 3) printf("%d ", i)
    output: 0 1 2 3

fr(i = 8 .. 3) printf("%d ", i)
    ouput: 8 7 6 5 4 3

fr(i = 3 ..< 6) printf("%d ", i)
    output: 3 4 5

fr(i = 5 ..> 1) printf("%d ", i)
    output: 5 4 3 2

In a nutshell, I'd like to write a powerful for in a short way... Is this possible?

If it isn't, is there another way?

Sergey
  • 7,985
  • 4
  • 48
  • 80
Daniel
  • 7,357
  • 7
  • 32
  • 84
  • Using `cout << i` requires less typing than a `printf`. – Thomas Matthews Jul 13 '16 at 17:31
  • 1
    Prefer inline functions to macros. Macros are evil. – Thomas Matthews Jul 13 '16 at 17:32
  • I dont need to write code to be readable, its just for me :) – Daniel Jul 13 '16 at 17:33
  • You could create your own function which takes three parameters - the two indexes to iterate between, and a function object to execute for each. Your function could determine whether it need to count up or down and perform the proper thing. This will have overhead, though... And the syntax may not be as short and sweet as you like. – Steve Jul 13 '16 at 17:34
  • Do you really want to use `fr` instead of `for`? – R Sahu Jul 13 '16 at 17:39
  • Really, ranges can already do this well: `for (int i : range(0, 3))`, `for(int i : range(8, 3))`, `for (int i : lrange(3, 6))`, `for (int i : lrange(5, 1))`, for appropriate `range` and `lrange` functions. – chris Jul 13 '16 at 17:55
  • @chris how can i do this in c++ ? – Daniel Jul 13 '16 at 18:42
  • @Daniel, There are existing range libraries that incorporate this kind of syntax. Take a look into them. – chris Jul 13 '16 at 19:17
  • 2
    I didn't expect that from myself, but I've written a whole header-only library for you that does almost what you want and probably even more: [Ranges on GitHub](https://github.com/ForceBru/Ranges). – ForceBru Jul 13 '16 at 19:57
  • @ForceBru, Interesting syntax you've got going on there, but the obvious solution is [`for (int i : 0.3_r)`](http://coliru.stacked-crooked.com/a/5180ec4ddd9f29a9) :p – chris Jul 14 '16 at 16:52
  • @chris, I was also thinking about using `double`s (and overloading `operator.`, which, sadly, is impossible), but this immediately leads to problems with negative numbers: for example, how can you loop from `-9` to `-1` with this trick? – ForceBru Jul 14 '16 at 16:56
  • @ForceBru, New operator literal, of course! Honestly, I don't recommend the syntax at all. – chris Jul 14 '16 at 17:08

2 Answers2

1

This is quite close to what you expected:

#include <iostream>
#include <algorithm>

#define LT -1 +
#define GT 1 +
#define FR(type, var, from, to) for(type dir = (from < to)? 1: -1, i = from; i != to + dir; i += dir)

int main() {
    FR(int, i, 0, 3) std::cout << i << " ";
    std::cout << std::endl;

    FR(int, i, 8, 3) std::cout << i << " ";
    std::cout << std::endl;

    FR(int, i, 3, LT 6) std::cout << i << " ";
    std::cout << std::endl;

    FR(int, i, 5, GT 1) std::cout << i << " ";
    std::cout << std::endl;
}
lorro
  • 10,687
  • 23
  • 36
  • nice solution, only the = missing... is there a way to insert it ? (i always use for with int so type is not necessary) – Daniel Jul 13 '16 at 18:39
  • @Daniel : that'd most probably need taking the body of the loop as a function parameter, something you won't really like I think. (The problem is, you need to know the loop index name. It cannot just be `i` as you might want nested loops.) Either that, or you'll introduce a type with an overloaded `operator=()` which does not do what you think. – lorro Jul 13 '16 at 19:09
0

If you assume that all values are integers, something like this might just work:

#define MYFOR(i,a,b) for (int i = (a); i != (b); i = (a)<(b)? i+1 : i-1)

Then use is this way:

MYFOR(i, 0, 10) printf("%d ", i);
MYFOR(i, 5, 0) printf("%d ", i);
rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • I had already thought of this but the problem is the = statement... – Daniel Jul 13 '16 at 18:37
  • @Daniel: I don't see why the `=` statement is a problem... I've tried and it works... Or do you mean when you use the macro? Then just do not write it. – rodrigo Jul 13 '16 at 20:20