|
Boost : |
Subject: Re: [boost] safe integer library -- the scope
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2015-12-14 08:15:52
2015-12-14 14:01 GMT+01:00 Rob Stewart <rob.stewart_at_[hidden]>:
> On December 14, 2015 3:43:25 AM EST, Andrzej Krzemienski <
> akrzemi1_at_[hidden]> wrote:
> > 2015-12-12 1:18 GMT+01:00 Robert Ramey <ramey_at_[hidden]>:
> >
> > > In the context of this library the safe_range ... are important for
> > a very
> > > special reason. The bounds are carried around with type of
> > expression
> > > results. So if I write
> > >
> > > save<int> a, x, b, y;
> > > y = a * x + b;
> > >
> > > runtime checking will generally have to be performed. But if I
> > happen to
> > > know that my variables are limited to certain range.
> > >
> > > safe_integer_range<-100, 100> a, x, b, y;
> > > y = a * x + b;
> > >
> > > Then it can be known at compile time that y can never overflow so no
> > > runtime checking is required. Here we've achieved the holy grail:
> > >
> > > a) guaranteed correct arithmetic result
> > > b) no runtime overhead.
> > > c) no exception code emitted.
> > > d) no special code - we just write algebraic expressions
> > >
> > > This is the true motivation for safe_..._range
>
> Why isn't that the behavior of your safe type in the first place? That is,
> what benefit does your safe type offer that it shouldn't just be supplanted
> by the range type?
>
> > Ok, now I think I understand the scope of the library. You give me the
> > tool
> > for representing a mathematical notion of an integral number within
> > *some* limited range. The contract is:
> >
> > You guarantee:
> > 1. Either correct result or a compile time error or a run-time
> > exception.
> > 2. No memory management: you will only take the space of one scalar
> > type.
> >
> > I specify the range of the representable values. I can say:
> > 1. "From -100 to +100", or
> > 2. "Whatever range 'int' as on my machine".
> >
> > But if I got it right, I would say that the choice of the name, and
> > the
> > interface do not indicate the intent as clear as they could. Imagine
> > the following alternative interface:
> >
> > small_int<p_range<-100, 100>>; // range-based policy
> > small_int<p_type<int>>; // underlying-type-based policy
> >
> > In the first case, the user specifies the range, and the library can
> > choose the best underlying type for the job.
> >
> > In the second case, the user chooses the underlying type, and this
> > implies the range [numeric_limits<T>::min(), numeric_limits<T>::max()]
>
> That seems like a reasonable idea, but what about the latter is "small"
> and not "safe" that you think the name should be "small_int"?
>
You have "big_integer" (or "integer") to represent a mathematical notion of
integer that allocates memory.
Analogously, you would have "small_integer" that represents a mathematical
notion of integer with a reduced range of values.
"safe_int" does not convey the idea of a higher level abstraction: it
sounds like "an ordinary low-level 'int' with some modified rules".
> Once you need two types to distinguish between a user-defined range, and a
> numeric_limits-defined range, why not just use two template names, like
> safe_range and safe_int? That would eliminate your p_range and p_type
> policies.
>
> However, since min() and max() are now constexpr, that all can be
> collapsed into a single template with three parameterizing types: the
> underlying type, the minimum, and the maximum:
>
> template
> <
> class T
> , T Min = std::numeric_limits<T>::min()
> , T Max = std::numeric_limits<T>::max()
> >
> class safe;
>
Current implementation has more of these policies (e.g., for how you want
to report overflow).
Regards,
&rzej
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk