Subject: Re: [boost] [safe_numerics] review
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2017-03-11 15:42:10


AMDG

On 03/10/2017 09:29 PM, John McFarlane via Boost wrote:
> On Fri, Mar 10, 2017 at 11:59 AM Robert Ramey via Boost <
> boost_at_[hidden]> wrote:
>
>>
>> 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.
>

It should be possible to handle saturation
with the following extension:
- If the ExceptionPolicy returns non-void,
  then the value it returns will be converted
  to the result type (the safe type, that is,
  not the stored type).

This requires two additional pieces to work:
- The ExceptionPolicy needs to distinguish
  between positive and negative overflow.
- There need to be special values that can
  convert to the min and max values of safe_base.

// Hypothetical saturate ExceptionPolicy:

template<class T>
struct min_value_t {
  constexpr T operator()() const
  { return std::numeric_limits<T>::min(); }
};

template<class T>
struct max_value_t {
  constexpr T operator()() const
  { return std::numeric_limits<T>::max(); }
};

template<template<class> class F>
struct special_value_t {
  template<class T,
    class = typename enable_if_c<is_safe<T>::value, void>::type>
  constexpr operator T() const { return F<T>()(); }
};

constexpr const special_value_t<min_value_t> min_value;
constexpr const special_value_t<max_value_t> max_value;

struct saturate {
  static auto overflow_error(const char *) { return max_value; }
  // ...
};

>
>> Note that I'm not a saint. I DO permit n to be uninitialized. I did
>> this because it's so common and I want the library to be useful on
>> legacy and embedded code. I've got a lot of reservations about this and
>> could change my mind.
>>
>
> <snip>. And of the list of things that makes fundamental
> scalar types unsafe, indeterminate value of default-initialized instances
> ranks higher than either overflow or divide-by-zero in my experience.
>

  Why not let the ExceptionPolicy decide?
Just add an uninitialized_error(const char*)
to ExceptionPolicy. Combined with my hypothetical
extension above, this would also allow automatic
zero-initialization.

  Incidentally, I'm not personally very concerned
about indeterminate values, as valgrind works quite
nicely for flushing out such problems and they're
usually easy to fix.

In Christ,
Steven Watanabe