views:

172

answers:

3

I have a problem that is quite common in the code that I am writing at the moment whereby I want to have an integer that can only exist inside a certain range where the range is [start, end). Basically I want to be able to do something like the following:

cyclic_int ci(4, 8);

ci = 4;
assert(ci == 4);
ci += 3;
assert(ci == 7);
ci += 2;
assert(ci == 5);
assert(ci == 13);

And that should all return true. Basically the class automatically applies modulus (%) for me and the integer acts as a cyclic integer in the range that I init it with. I could implement this class myself and overload all of the common operators to make it work nicely with normal integers but it seems like a useful class that somebody may have made before.

So my question is this, is there a common class like this out there somewhere that everyone uses or am I thinking of doing it the wrong way and is there a better simpler way. (My aim is to not have to constantly think about applying the % operator or any similar function over it) Thanks.

Edit: I decided to write my own one as well just for fun: http://github.com/robertmassaioli/wrapping_number

+2  A: 

Is not it easier to use the function normalize?

int normalize(int val, int start, int end)
{
    return (val - start) % (end - start) + start;
}


int ci = 4;   
assert(ci == 4);   
ci = normalize(ci + 3, 4, 8);   
assert(ci == 7);   
ci = normalize(ci + 2, 4, 8);   
assert(ci == 5);   
assert(ci == 13); 
Alexey Malistov
That was exactly what I was trying to avoid because I don't want to have to really think about applying the normalize function (because I will forget eventually). And the last assert will fail too I think?
Robert Massaioli
Actually, I think that the last assert should fail, because 13 isn't defined as being a range-limited number, I would use assert(ci == cyclic_int<4,8>(13)); (template is convenient here)
stefaanv
@stefaanv: I think what he's getting at is that 13 should be congruent to 5 in the cyclic_int(4, 8) (i.e. includes integers 4, 5, ... 12), which it is. I agree with the notion of a template... provides stronger typing.
andand
+1  A: 

These may not be exactly what you want, but you may be interested in one of the many Galois-field libraries out there (http://www.google.co.uk/search?q=galois+field+c%2B%2B+library). I've never used any of them, so I can't give a specific recommendation.

Oli Charlesworth
+1  A: 

I never used it and it is not yet an official Boost library, but Boost.ConstrainedValue has a wrapping_int that looks very similar to what you're looking for.

Although it is not yet a part of Boost, it was reviewed and, IIUC, conditionally accepted recently: http://lists.boost.org/boost-announce/2010/09/0265.php

The library is available at http://rk.dl.pl/f/constrained_value.zip

The documentation is at http://rk.dl.pl/r/constrained_value

Éric Malenfant
I wrote my own one as well just for fun as well: http://github.com/robertmassaioli/wrapping_number
Robert Massaioli