Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Range types

44 views
Skip to first unread message

Alf P. Steinbach

unread,
Apr 14, 2017, 5:57:46 PM4/14/17
to
On 14-Apr-17 10:38 PM, Stefan Ram wrote:
> Some other languages (like Pascal or COBOL) provide types
> for ranges and enumerations, and I wonder to which extend
> one can create such types in C++.
>
> For example,
>
> struct example { range<2'000'000'000,2'000'000'010> i; };
>
> . The implementation should emit an error message (a
> compile-time error message if possible) when one tries to
>
> instance.i = 0;
>
> , and, if possible,
>
> sizeof instance.i
>
> should be just 1, because one byte is enough to store
> one out of 10 values.

The problem is just all the boilerplate code to support arithmetic and
comparisons.

Boost has a little macro-based (I think it was) thing to generate that code.


Cheers!,

- Alf


Robert Wessel

unread,
Apr 15, 2017, 1:47:49 AM4/15/17
to
On 14 Apr 2017 20:38:29 GMT, r...@zedat.fu-berlin.de (Stefan Ram)
wrote:

> Some other languages (like Pascal or COBOL) provide types
> for ranges and enumerations, and I wonder to which extend
> one can create such types in C++.
>
> For example,
>
>struct example { range<2'000'000'000,2'000'000'010> i; };
>
> . The implementation should emit an error message (a
> compile-time error message if possible) when one tries to
>
>instance.i = 0;
>
> , and, if possible,
>
>sizeof instance.i
>
> should be just 1, because one byte is enough to store
> one out of 10 values.


While only a rough outline, a template with conversion operators, like
the following, should provide a start. This does require the actual
storage type to be explicitly specified, I'm not sure how you'd
generate that automatically from the range.


#include <stdexcept>
template<typename T, long MN, long MX>
class rangetype
{
T v;
void setv(long a)
{
if (a < MN || a > MX)
throw std::out_of_range("blah");
v=a-MN;
}

public:
rangetype& operator=(long a) {setv(a); return *this;}
operator long() {return v+MN;}
};


int main()
{
int a;
char b;
rangetype<char, 100, 200> q;
rangetype<int, 100, 2000> r;

q = 3;
q = 3.14;

a = q;
b = q;

r = q;
}

Bonita Montero

unread,
Apr 15, 2017, 4:43:19 AM4/15/17
to
> template<typename T, long MN, long MX>

template<typename T, T MN, T MX>

> void setv(long a)

void setv(T a)
...

> rangetype& operator=(long a) {setv(a); return *this;}

rangetype& operator=(T a) {setv(a); return *this;}

> operator long() {return v+MN;}

operator T() {return v+MN;}

Winfied Valentin

unread,
Apr 15, 2017, 2:03:52 PM4/15/17
to
> v=a-MN;
> ...
> operator long() {return v+MN;}

Why Du you substract MN? That's useless.

Vir Campestris

unread,
Apr 16, 2017, 4:14:58 PM4/16/17
to
On 14/04/2017 21:38, Stefan Ram wrote:
> should be just 1, because one byte is enough to store
> one out of 10 values.

That depends on whether you want "maximum speed" or "minimum size". IIRC
an enum tends to be an int under the hood.

Andy

Robert Wessel

unread,
Apr 17, 2017, 3:08:33 AM4/17/17
to
The OP wanted to store the range [2000000000..2000000010] in a single
byte.
0 new messages