Topic: Range type (Proposal: New types in C++0x)


Author: tigrisek@interia.pl (Robert Kawulak)
Date: Wed, 6 Oct 2004 14:43:00 GMT
Raw View
Hi,

> After finished writing my (long) post I realized that this may be not
> the right newsgroup for that. Why don't we move to Boost instead?

Well, I thought this is the right group since we're discussing a
feature we want to be added to C++ standard, aren't we? But if, for
some reason, it's an inappropriate group, then we could change it.

Best regards,
Robert Kawulak

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tigrisek@interia.pl (Robert Kawulak)
Date: Fri, 8 Oct 2004 18:28:10 GMT
Raw View
Hi,

> >     I see that some people here have already written such a class template.
> > All the authors - maybe you could post your work here, so we can compare and
> > contrast features and different approaches you've used, and choose the best
> > solutions?
>
> After finished writing my (long) post I realized that this may be not
> the right newsgroup for that. Why don't we move to Boost instead?

  Have you already posted it in Boost newsgroups? I can't find it
there, nor I can see it in c.s.c++... And the discussion seems to be
stuck - anyone, write something! ;-)

Best regards,
Robert Kawulak

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Sun, 10 Oct 2004 23:55:25 GMT
Raw View
Robert Kawulak wrote:
> Hi,
>
>
>>>    I see that some people here have already written such a class template.
>>>All the authors - maybe you could post your work here, so we can compare and
>>>contrast features and different approaches you've used, and choose the best
>>>solutions?
>>
>>After finished writing my (long) post I realized that this may be not
>>the right newsgroup for that. Why don't we move to Boost instead?
>
>
>   Have you already posted it in Boost newsgroups? I can't find it
> there, nor I can see it in c.s.c++... And the discussion seems to be
> stuck - anyone, write something! ;-)
>

I just started a thread "Bounded type (was: Re: Range type)" in
comp.lang.c++.moderated.

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tigrisek@interia.pl ("Robert Kawulak")
Date: Wed, 29 Sep 2004 20:54:52 GMT
Raw View
Hi all,

At first, this post was intended only to be an answer for another post in
"Proposal: New types in C++0x" thread at c.l.c++.m, but as it proposes a
feature many people could possibly be interested in, I've decided to create
a new thread for it in c.s.c++.

> > Will there ever be something as uniform and simple in C++ as
> >
> > int -3000...2000  year ;
> >
> > and
> >
> > typedef int 1...12 month ;
>
> I'd much prefer having an std::range class template in the standard
> library. I see no advantage in a core language solution for this
> issue, even though I also would like to see it addressed.

    That's right. This is one of the features C++ IMO lacks. Of course it's
not so hard to make such a template class on one's own, but standarising it
and recommending to use it instead of built-in types would decrease the
number of errors that happen to many C++ programmers, even to the
experienced ones. Furthermore, it would make the code more
self-documenting and closer to the modelled problem.

    Maybe the class template could look like this:

/************************************************/

template <typename T, T smallest, T biggest>
class bounded { //or limited or ranged

    SATIC_ASSERT( !(biggest < smallest) );

  public:

    bounded(const T & = T(smallest)) /*throw(out_of_bounds, ...)*/;

    bounded & operator = (const T &) /*throw(out_of_bounds, ...)*/;

    operator const T & () const throw();

    //maybe operators ++, += etc...

}; //class bounded<>

/************************************************/

Examples of usage:

  bounded<int, 0, 15> i; // i == 0
  //! bounded<int, 1, 56> j(i); // throws: assignment of 0
  bounded<int, 1, 56> j(27); // j == 27
  i = 10; // i == 10
  j = i; // j == 10
  int k = i + j; // k == 20;
  //! i = k; // throws: assignment of 20

    Operator < must be defined for operands of type T, and it must preserve
linear order. But because of the STATIC_ASSERT, only built-in types could be
used. Possible solutions to this problem are:
1. Remove the STATIC_ASSERT - then constructor will always throw if
biggest < smallest (very ugly, I admit), because for any x we have:
(smallest <= x <= biggest) == false,
2. Add a static member to bounded class and check the condition during its
initialisation and eventually throw (even worse...),
3. Require that operator < is inline function with no side effects and allow
calls of such functions in compile-time expressions (not ideal, but my
favourite).

Is there any proposal to the commettee yet? And if no, is it worth making
then?

Best regards,
Robert Kawulak


















---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Wed, 29 Sep 2004 22:36:20 GMT
Raw View
Robert Kawulak wrote:

> Hi all,
>
> At first, this post was intended only to be an answer for another post in
> "Proposal: New types in C++0x" thread at c.l.c++.m, but as it proposes a
> feature many people could possibly be interested in, I've decided to create
> a new thread for it in c.s.c++.
>

I had exactly the same thought ;-)

>     Maybe the class template could look like this:
>
> /************************************************/
>
> template <typename T, T smallest, T biggest>
> class bounded { //or limited or ranged
>
>     SATIC_ASSERT( !(biggest < smallest) );
>

I like it. Especially the way you can use a UDT for the underlying type.
The static assert is not a big problem because you could use some
template machinery to impose that restriction only if T is a basic type.

I was thinking about a completely different approach:

struct least_sized_type; // see below

template <
   boost::intmax_t Min,
   boost::intmax_t Max,
   typename ImplType = least_sized_type>
class bounded
{
   // ...
};

The underlying type is specified last so it can be omitted. If it's
omitted, it will be automatically detected using some template
machinery. This would be used like this:

void foo()
{
   bounded<0, 1000, int>   i; // use int
   bounded<0, 1000, short> s; // use short
   bounded<0, 1000> s1;       // use the least-sized integral type
                              // than can represent both 0 and 1000
}

I'm not an MPL expert, but I think the auto-detect feature can easily be
accomplished by finding in a suitably ordered typelist like:

typedef mpl::list<
   signed char, unsigned char,
   short, unsigned short,
   int, unsigned,
   long, unsigned long,
   boost::intmax_t> TypeList;

the first type that satisfies a condition built upon
boost::integer_traits<T>::const_min and
boost::integer_traits<T>::const_max.

Notice that by changing the TypeList you can have different detection
policies, for example:

   bounded<0, 1000, least_signed_type>   // least-sized *and* signed
   bounded<0, 1000, least_unsigned_type> // least-sized *and* unsigned

The two main drawbacks of this approach are:

1) only basic integral types
2) uintmax_t can never be chosen

Point 2) could be mitigated by providing a second template (with a
different name) taking uintmax_t Min and Max... not very elegant ;-)

Just my thoughts,

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: invalid@bigfoot.com (Bob Hairgrove)
Date: Wed, 29 Sep 2004 23:06:50 GMT
Raw View
On Wed, 29 Sep 2004 20:54:52 GMT, tigrisek@interia.pl ("Robert
Kawulak") wrote:

>Hi all,
>
>At first, this post was intended only to be an answer for another post in
>"Proposal: New types in C++0x" thread at c.l.c++.m, but as it proposes a
>feature many people could possibly be interested in, I've decided to create
>a new thread for it in c.s.c++.
>
>> > Will there ever be something as uniform and simple in C++ as
>> >
>> > int -3000...2000  year ;
>> >
>> > and
>> >
>> > typedef int 1...12 month ;
>>
>> I'd much prefer having an std::range class template in the standard
>> library. I see no advantage in a core language solution for this
>> issue, even though I also would like to see it addressed.
>
>    That's right. This is one of the features C++ IMO lacks. Of course it's
>not so hard to make such a template class on one's own, but standarising it
>and recommending to use it instead of built-in types would decrease the
>number of errors that happen to many C++ programmers, even to the
>experienced ones. Furthermore, it would make the code more
>self-documenting and closer to the modelled problem.
>
>    Maybe the class template could look like this:
>
>/************************************************/
>
>template <typename T, T smallest, T biggest>
>class bounded { //or limited or ranged
>
>    SATIC_ASSERT( !(biggest < smallest) );
>
>  public:
>
>    bounded(const T & = T(smallest)) /*throw(out_of_bounds, ...)*/;
>
>    bounded & operator = (const T &) /*throw(out_of_bounds, ...)*/;
>
>    operator const T & () const throw();
>
>    //maybe operators ++, += etc...
>
>}; //class bounded<>
>
>/************************************************/
>
>Examples of usage:
>
>  bounded<int, 0, 15> i; // i == 0
>  //! bounded<int, 1, 56> j(i); // throws: assignment of 0
>  bounded<int, 1, 56> j(27); // j == 27
>  i = 10; // i == 10
>  j = i; // j == 10
>  int k = i + j; // k == 20;
>  //! i = k; // throws: assignment of 20
>
>    Operator < must be defined for operands of type T, and it must preserve
>linear order. But because of the STATIC_ASSERT, only built-in types could be
>used. Possible solutions to this problem are:
>1. Remove the STATIC_ASSERT - then constructor will always throw if
>biggest < smallest (very ugly, I admit), because for any x we have:
>(smallest <= x <= biggest) == false,
>2. Add a static member to bounded class and check the condition during its
>initialisation and eventually throw (even worse...),
>3. Require that operator < is inline function with no side effects and allow
>calls of such functions in compile-time expressions (not ideal, but my
>favourite).
>
>Is there any proposal to the commettee yet? And if no, is it worth making
>then?

There is a Boost interval library as well as a graph programming
library, the latter of these having objects such as directed
graphs/edges. Have you seen these?

I think the concept of the assertion !(biggest < smallest) is not
always desirable if one wishes to implement a directed range. I did my
own template class for some scheduling work, but it has additional
features similar to set operations (such as intersection, complement,
coalesce unions) which aren't generally applicable to other problem
domains. I think it's very hard to cover all the bases.

--
Bob Hairgrove
NoSpamPlease@Home.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Thu, 30 Sep 2004 00:26:58 GMT
Raw View
Bob Hairgrove wrote:
> There is a Boost interval library as well as a graph programming
> library, the latter of these having objects such as directed
> graphs/edges. Have you seen these?
>
> I think the concept of the assertion !(biggest < smallest) is not
> always desirable if one wishes to implement a directed range. I did my
> own template class for some scheduling work, but it has additional
> features similar to set operations (such as intersection, complement,
> coalesce unions) which aren't generally applicable to other problem
> domains. I think it's very hard to cover all the bases.
>

I think you're missing the point. The Boost interval library is about a
*objects* that represents ranges of values. On such objects it makes
sense to do set-theoretic operations like intersection, etc.

Here we are discussing about *types* that represents a range of values.
Objects of any such type would represent only one value in the allotted
range. That is if x is of type bounded<0, 100>, then x can take any
*one* value like 0, 1, 2, 33 or 100. Set-theoretic operations makes no
sense on x, but arithmetic operations do: for example you can increment
x, possibly throwing an exception on overflow if x is already 100.

In this case there's no point in having directed ranges, therefore the
idea of having the !(smallest > biggest) test as a diagnostic for empty
ranges also makes sense.

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pavnic@sbox.tugraz.at (Nicolas Pavlidis)
Date: Thu, 30 Sep 2004 17:13:33 GMT
Raw View
tigrisek@interia.pl ("Robert Kawulak") writes:

> /************************************************/
>
> template <typename T, T smallest, T biggest>

I wrote such a class and the header of the template was nearly the same
but still there was a little difference:
template<typenane T,
         T smallest = std::numeric_limits<T>::min
         T biggest = std::numeric_limits<T>::max>


>     Operator < must be defined for operands of type T, and it must preserve
> linear order. But because of the STATIC_ASSERT, only built-in types
> could be

I don't think that tis is a problem, because ranges make only sense for
build in types. But if you wish support for non build in types it's IMHO
better to use the assert - macro in the constructor instade of an
exception.

Kind regards,
Nicolas


--
|     Nicolas Pavlidis       |       Elvis Presly:    |\ |__      |
|   Student of SE  & KM      |      "Into the goto"   | \|__|     |
|  pavnic@sbox.tugraz.at     |       ICQ #320057056      |        |
|-------------------University of Technology, Graz----------------|

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pavnic@sbox.tugraz.at (Nicolas Pavlidis)
Date: Fri, 1 Oct 2004 16:59:06 GMT
Raw View
pavnic@sbox.tugraz.at (Nicolas Pavlidis) writes:

> tigrisek@interia.pl ("Robert Kawulak") writes:
>
> > /************************************************/
> >
> > template <typename T, T smallest, T biggest>
>
> I wrote such a class and the header of the template was nearly the same
> but still there was a little difference:
> template<typenane T,
>          T smallest = std::numeric_limits<T>::min
>          T biggest = std::numeric_limits<T>::max>

This is bulshit, sorry. I don't know what I've done, because I did't
find the file anymore, but there was certainly no call to
std::numeric_limits<t>::min / max, because these are functions :-(.

I'm sorry for my wrong code.

Kind regards,
Nicolas



--
|     Nicolas Pavlidis       |       Elvis Presly:    |\ |__      |
|   Student of SE  & KM      |      "Into the goto"   | \|__|     |
|  pavnic@sbox.tugraz.at     |       ICQ #320057056      |        |
|-------------------University of Technology, Graz----------------|

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Nicola.Musatti@ObjectWay.it (Nicola Musatti)
Date: Sat, 2 Oct 2004 04:55:05 GMT
Raw View
AlbertoBarbati@libero.it (Alberto Barbati) wrote in message news:<FHG6d.15202$H11.463970@twister1.libero.it>...

[...]
> struct least_sized_type; // see below
>
> template <
>    boost::intmax_t Min,
>    boost::intmax_t Max,
>    typename ImplType = least_sized_type>
> class bounded
> {
>    // ...
> };
>
> The underlying type is specified last so it can be omitted. If it's
> omitted, it will be automatically detected using some template
> machinery.

I posted a very similar idea on c.l.c++.m a few moments ago, so I
obviously favour your solution.

[...]
> I'm not an MPL expert, but I think the auto-detect feature can easily be
> accomplished by finding in a suitably ordered typelist [...]
> the first type that satisfies a condition built upon
> boost::integer_traits<T>::const_min and
> boost::integer_traits<T>::const_max.
>
> Notice that by changing the TypeList you can have different detection
> policies, for example:
>
>    bounded<0, 1000, least_signed_type>   // least-sized *and* signed
>    bounded<0, 1000, least_unsigned_type> // least-sized *and* unsigned
>
> The two main drawbacks of this approach are:
>
> 1) only basic integral types
> 2) uintmax_t can never be chosen
>
> Point 2) could be mitigated by providing a second template (with a
> different name) taking uintmax_t Min and Max... not very elegant ;-)

Why? We could have integral_bounded and unsigned_bounded. Once exact
floating point constants make it into the language it will be
reasonable to extend non type template parameters to floating point
types and we'll be able to add floating_unbounded.

Cheers,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dont.spam.me@pool.domainsite.com (Xenos)
Date: Sat, 2 Oct 2004 04:55:07 GMT
Raw View
"Nicolas Pavlidis" <pavnic@sbox.tugraz.at> wrote in message
news:2s21uvF1f1b5vU1@uni-berlin.de...
> tigrisek@interia.pl ("Robert Kawulak") writes:
>
> template<typenane T,
>          T smallest = std::numeric_limits<T>::min
>          T biggest = std::numeric_limits<T>::max>
>
I usually do this:

class default_type{};
template<typename T, T lo, T hi, typename U = default_type>

so I can recreate "unique" types, so that if I have two different types with
the same T and range, the compiler will still see them as different types if
I prefer.

> I don't think that tis is a problem, because ranges make only sense for
> build in types. But if you wish support for non build in types it's IMHO
> better to use the assert - macro in the constructor instade of an
> exception.

Except (no pun intended) in a fault tolerent system that must recover from
the bounds error an not abort or ignore it.  You can say that you should
have caught it in testing, but realistically bugs will still exist in
validated production code that must not terminate because of an error.





---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tigrisek@interia.pl ("Robert Kawulak")
Date: Sat, 2 Oct 2004 04:55:10 GMT
Raw View
Hi,

> template<typenane T,
>         T smallest = std::numeric_limits<T>::min
>         T biggest = std::numeric_limits<T>::max>

Nice! ;-)

> ranges make only sense for
> build in types.

I must disagree here. Range makes sense for any type for which a linear
order relation is defined (for example an infinite precision numbers class).

> But if you wish support for non build in types it's IMHO
> better to use the assert - macro in the constructor instade of an
> exception.

    Unfortunately I've missed one thing - because of 'smallest' and
'biggest' template parameters of type T, the T can only be an integral type
(I must had been really sleepy when writing the post at night to forget
about this ;-). It's a pity, because one can't use any user-defined type or
even std::bounded<double, 0.0, 1.0>. But at least this solves the problem of
STATIC_CAST...
    We can try to use some template metaprogramming to create a class for
those cases, but is it possible to make and does somebody know how to make
it?

Thanks for your reply!
Best regards,
Robert Kawulak




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Sat, 2 Oct 2004 16:27:43 GMT
Raw View
Nicola Musatti wrote:
> AlbertoBarbati@libero.it (Alberto Barbati) wrote in message news:<FHG6d.15202$H11.463970@twister1.libero.it>...
>
> I posted a very similar idea on c.l.c++.m a few moments ago, so I
> obviously favour your solution.
>

:-)

I also wrote a sample implementation, but I still don't see yours in the
newsgroup. If you want to, feel free to send me yours privately. Can I
send you mine?

>>
>>The two main drawbacks of this approach are:
>>
>>1) only basic integral types

In fact I realized that this is not a drawback... Only basic integral
types can be used in non-type template parameters. So no UDTs and no
floating point (yet) can ever be used. Allowing UDTs would require the
use of pointers to values as the template parameters, so it may still be
done, but the syntax would become quite cumbersome.

>>2) uintmax_t can never be chosen
>>
>>Point 2) could be mitigated by providing a second template (with a
>>different name) taking uintmax_t Min and Max... not very elegant ;-)
>
> Why? We could have integral_bounded and unsigned_bounded.

Maybe it's not that bad, after all. But as you can write (at least you
can with my implementation):

   integral_bounded<0, 1000, least_unsigned>

why should I bother using:

   unsigned_bounded<0, 1000> ?

Moreover what should we do in this case:

   unsigned_bounded<0, 1000, least_signed> ?

I don't feel like disallowing it, yet it is counter-intuitive to have a
type named unsigned_bounded be... signed. In a certain sense,
unsigned_bounded is only needed if your range really won't fit in a
intmax_t, a very limited use, so we might decide to dump it altogether.

> Why? We could have integral_bounded and unsigned_bounded. Once exact
> floating point constants make it into the language it will be
> reasonable to extend non type template parameters to floating point
> types and we'll be able to add floating_unbounded.

Yep :-P

Ciao,

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pavnic@sbox.tugraz.at (Nicolas Pavlidis)
Date: Sat, 2 Oct 2004 16:27:52 GMT
Raw View
dont.spam.me@pool.domainsite.com (Xenos) writes:

> "Nicolas Pavlidis" <pavnic@sbox.tugraz.at> wrote in message
> news:2s21uvF1f1b5vU1@uni-berlin.de...

> > I don't think that tis is a problem, because ranges make only sense for
> > build in types. But if you wish support for non build in types it's IMHO
> > better to use the assert - macro in the constructor instade of an
> > exception.
>
> Except (no pun intended) in a fault tolerent system that must recover from
> the bounds error an not abort or ignore it.  You can say that you should
> have caught it in testing, but realistically bugs will still exist in
> validated production code that must not terminate because of an error.

But the upper and the lower bouds are given at compile time, so if there
are wrong number passed it's definitely a wrong ese of the class, IMHO

Kind regrads,
Nicolas

--
|     Nicolas Pavlidis       |       Elvis Presly:    |\ |__      |
|   Student of SE  & KM      |      "Into the goto"   | \|__|     |
|  pavnic@sbox.tugraz.at     |       ICQ #320057056      |        |
|-------------------University of Technology, Graz----------------|

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tslettebo@hotmail.com ("Terje Sletteb ")
Date: Sun, 3 Oct 2004 02:50:15 GMT
Raw View
"Nicolas Pavlidis" <pavnic@sbox.tugraz.at> wrote in message
news:2s4j3eF1f25hhU1@uni-berlin.de...
> pavnic@sbox.tugraz.at (Nicolas Pavlidis) writes:
>
> > tigrisek@interia.pl ("Robert Kawulak") writes:
> >
> > > /************************************************/
> > >
> > > template <typename T, T smallest, T biggest>
> >
> > I wrote such a class and the header of the template was nearly the same
> > but still there was a little difference:
> > template<typenane T,
> >          T smallest = std::numeric_limits<T>::min
> >          T biggest = std::numeric_limits<T>::max>
>
> This is bulshit, sorry. I don't know what I've done, because I did't
> find the file anymore, but there was certainly no call to
> std::numeric_limits<t>::min / max, because these are functions :-(.

Try boost/integer_traits.hpp
(http://www.boost.org/libs/integer/integer_traits.html), which addresses
just this problem:

template<typenane T,
         T smallest = boost::integer_traits<T>::const_min,
         T biggest = boost::integer_traits<T>::const_max>
..

Regards,

Terje


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Nicola.Musatti@ObjectWay.it (Nicola Musatti)
Date: Mon, 4 Oct 2004 15:16:16 GMT
Raw View
AlbertoBarbati@libero.it (Alberto Barbati) wrote in message news:<OIv7d.20029$N45.508594@twister2.libero.it>...
> Nicola Musatti wrote:
[...]
> I also wrote a sample implementation, but I still don't see yours in the
> newsgroup. If you want to, feel free to send me yours privately. Can I
> send you mine?

Oh, I don't have a complete implementation. Mine was only a very rough
proof of concept.

[...]
> > Why? We could have integral_bounded and unsigned_bounded.
>
> Maybe it's not that bad, after all. But as you can write (at least you
> can with my implementation):
>
>    integral_bounded<0, 1000, least_unsigned>
>
> why should I bother using:
>
>    unsigned_bounded<0, 1000> ?
>
> Moreover what should we do in this case:
>
>    unsigned_bounded<0, 1000, least_signed> ?
>
> I don't feel like disallowing it, yet it is counter-intuitive to have a
> type named unsigned_bounded be... signed. In a certain sense,
> unsigned_bounded is only needed if your range really won't fit in a
> intmax_t, a very limited use, so we might decide to dump it altogether.

Hold it. unsigned_bounded is quite a different beast from
integer_bounded in that it should support modulo arithmetic! We (I, at
least) tend to consider unsigned as an integer subset, but it really
is a different type, with different semantics. So integer_bounded and
unsigned_bounded shouldn't share the set of valid base types.

Another issue to consider is whether a signed range should simply be
represented by the smallest type that can represent both extremes or
if the extremes should be traslated to an interval symmetric around
zero, so as to use the smallest base type possible, at the expense of
inverting the traslation on most operations.

Cheers,
Nicola Musatti

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tigrisek@interia.pl ("Robert Kawulak")
Date: Mon, 4 Oct 2004 18:24:15 GMT
Raw View
Hi,

    I see that some people here have already written such a class template.
All the authors - maybe you could post your work here, so we can compare and
contrast features and different approaches you've used, and choose the best
solutions?
    For a start, here's improved interface of the class template from the
opening post:

/**************************************************************/

template <typename T, T S, T B>
class bounded {

  public:

    // Remember the template's actual parameters
    typedef T value_type;
    static const T smallest = S;
    static const T biggest = B;

    // Constructor (also default)
    bounded(value_type = smallest) throw(std::range_error);

    // Assignment operator
    bounded & operator = (value_type) throw(std::range_error);

    // No need to define copy constructor nor destructor

    // Operator for conversion to value_type
    operator value_type () const throw();

    // Other mutating operators
    value_type operator ++ () throw(std::range_error);
    value_type operator -- () throw(std::range_errornds);
    value_type operator ++ (int) throw(std::range_error);
    value_type operator -- (int) throw(std::range_error);
    value_type operator += (value_type) throw(std::range_error);
    value_type operator -= (value_type) throw(std::range_error);
    value_type operator *= (value_type) throw(std::range_error);
    value_type operator /= (value_type) throw(std::range_error);
    value_type operator %= (value_type) throw(std::range_error);

  private:

    // To prevent instantiation with incorrect parameters:
    SATIC_ASSERT( smallest <= biggest );

}; //class bounded<>

/**************************************************************/


    Here are also some reflections of mine:

1. Name of the class template: so far, these seem reasonable to me:
    bounded
    ranged
    limited

2. I think that trying to instantiate the template with invalid range should
cause a compile-time error. STATIC_ASSERT is not in the standard yet, but
there are several proposals concerning it. Even if it is not added to the
language, it can be easily replaced with template metaassertion with no side
effects (like namespace pollution - it may be whole contained in the private
section of the class template).

3. There are two possible approaches for implementing mutating operators
like ++, --, +=, *=, etc.: ignore possible overflow and throw only when the
(possibly wrapped) result doesn't fit in the range or check whether the
operation would cause overflow and throw if yes. I'd choose the latter,
because for signed types overflow entails undefined behavior and because
ignoring the overflow might hide bugs and errors.

4. I also wonder if the following operators should be included: ^=, &=, |=,
 >>=, <<=.

5. Should there be a separate excepion class or std::range_error is OK?

Best regards,
Robert Kawulak




---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Tue, 5 Oct 2004 15:27:27 GMT
Raw View
Robert Kawulak wrote:
> Hi,
>
>     I see that some people here have already written such a class template.
> All the authors - maybe you could post your work here, so we can compare and
> contrast features and different approaches you've used, and choose the best
> solutions?

After finished writing my (long) post I realized that this may be not
the right newsgroup for that. Why don't we move to Boost instead?

Just my opinion,

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]