On 3/10/17 8:29 PM, John McFarlane via Boost wrote:
On Fri, Mar 10, 2017 at 11:59 AM Robert Ramey via Boost < <snip>
I'm all ears. One thing I do NOT see is saturate. I've seen it mentioned in several places - but I'm not convinced.
You mean you don't see the need for it? It comes up quite often as a strategy for dealing with overflow and a safe integer type seems like a good place to house it. Even it it isn't implemented now, a policy interface which allows users to implement it is going to give the library more users who use it to make their integers safe - surely the point of the exercise here.
My major concern was that it pollute the currently elegant design (my characterization) but mucking things up with some that is orthogonal to the unitary goal of the library - program correctness. In the mean time, Stephan Watanabee's post describes how small tweaks in the ExceptionPolicy concept would permit this functionality to be implemented as an exception policy. Looked at in his manner, I would love to see an exception policy crafted to implement this. It would be an excellent demo for the documentation.
The goal of making `safe<int>` a drop-in replacement for int is essential. Agreed
This alludes to a wider issue with the API of this library: it tries to do too much. Conversion from integers to real numbers is not so much *unsafe* as *lossy*. Users intuitively understand that `int n = 0.5;` will not define a variable with value 0.5 and this is often exactly what they intend, e.g.:
your example includes ++historgram[v] where v is a double. My version would choke on that- as I think it should.
That is where we disagree.
And if one wishes to catch risky narrowing conversions, they already have tools to do this, e.g. GCC's `-Wconversion`. In short, it's a separate concern. This isn't portable and (I believe results in a compile time error). Limited utility as far as I'm concerned.
Not if the conversion uses `static_cast`: https://godbolt.org/g/13aaO3
LOL - that is very interesting - looks like someone is introducing
Another example of overreach of the API is in governing the results of arithmetic operations. Via policy choice, `safe<int>` can produce auto-widening functionality, e.g. returning a 16-bit result from a multiply operation with 8-bit operands. This behavior belongs in a whole different class. It achieves overlapping safety wins but it complicates the interface. I believe that the correct approach is to produce a type which is dedicated to performing run-time overflow checks and another type which performs automatic widening and to combine them, e.g.:
// simplified for clarity, see: wg21.link/p0554#composition-safe_elastic_integer template<typename Rep> class auto_widening_integer; template<typename Rep> class safe_integer; template<typename Rep> using extra_safe_integer = safe_integer
;
Looking at this I see:
template<class Rep>
using auto_widening_integer = safe
My conclusion after looking at the papers is that we're all attempting to address the same important problem in different ways. My way places high priority in handling legacy code. The other way seems more appropriate for use in creating new code which is meant to support correctness from the start - building in quality rather than trying to add it on as I do.
I draw the opposite conclusion but I'm glad we both have the same aim to provide a low-resistance path to safe arithmetic.
Having said this, I recall that a GSOC project has implemented the Crowle proposal. I'll try to track this down an see if we can get it added to the boost library incubator Robert Ramey PS Looks like the over quoting nannie is on vacation. I think posts are improved by <snip> where points previously address which are not being added to are removed. It makes this easier to find. RR