Design question SafeFloat

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Design question SafeFloat

Boost - Dev mailing list
Hi,
I'm working in simplifying safe_float to prepare it for future review.

For now I'm focusing in a C++17 compatible version.

Currently safefloat receives 2 template parameters:

template<typename FP, typename P>
class safe_float ...

Where FP is the floating point value being made "safe", float, double, long
double ...
and P is a Policy of what to check and how to react.

The how to react is a class that I pass by template parameter to the
Policy.
So, policy looks like:

template<typename R>
class policy_x ....

I had a very complicated way of producing those policies, I used many TMP
tricks so the logic stays in the policy and combines, but now that
if-constexpr is available it may not make sense to take that path anymore.
And, I see it may be better to simplify as much as possible.

So, I'm thiking in make policy like a "config" description and put if
constexprs in the safe_float class to decide what to do based in that. I
want a bad policy to fail execution.

I'm wondering what is the best approach for defining that "config-like"
policy.

A policy check is a bidimensional matrix of the operation affected and the
flags considered (FE_ENV flags). For example, I want a policy to tell
something like "check overflow in additions and underflow in division".

These are the options I'm considering

1) define typenames for each flag and assign them tuple of affected
operations

class addition;
class division;
class multiplication;
class subtraction;

template<typename R>
struct policy_x {
using reporter=R;
using overflow=tuple<addition>;
using underflow=tuple<division>;
using invalid=tuple<>;
using inexact=tuple<>;
};

2) define typename by operation, passing class with constexprs of flags
being evaluated

struct empty_check{
static constexpr bool check_overflow=false;
static constexpr bool check_underflow=false;
static constexpr bool check_invalid=false;
static constexpr bool check_inexact=false;
};

struct check_overflow : public empty_check {
static constexpr bool check_overflow=true;
};

struct check_underflow : public empty_check {
static constexpr bool check_underflow=true;
};

template<typename R>
struct policy_x {
using reporter=R;
using addition=check_overflow;
using subtraction=empty_check;
using multiplication=empty_check;
using division=check_underflow;
};

3) similar to 2, but using true_type, and false_type in place of constexpr
variables.
struct empty_check{
using check_overflow=false_type;
using check_underflow=false_type;
using check_invalid=false_type;
using check_inexact=false_type;
};

struct check_overflow : public empty_check {
using check_overflow=true_type;
};

struct check_underflow : public empty_check {
using check_underflow=true_type;
};

template<typename R>
struct policy_x {
using reporter=R;
using addition=check_overflow;
using subtraction=empty_check;
using multiplication=empty_check;
using division=check_underflow;

4) other options?


Thanks for any comments in advance.
Damian

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Design question SafeFloat

Boost - Dev mailing list
On 7/26/18 8:25 PM, Damian Vicino via Boost wrote:

> Hi,
> I'm working in simplifying safe_float to prepare it for future review.
>
> For now I'm focusing in a C++17 compatible version.
>
> Currently safefloat receives 2 template parameters:
>
> template<typename FP, typename P>
> class safe_float ...
>
> Where FP is the floating point value being made "safe", float, double, long
> double ...
> and P is a Policy of what to check and how to react.

It might be helpful to look at how safe numerics does it.

Robert Ramey


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Design question SafeFloat

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
AMDG

On 07/26/2018 09:25 PM, Damian Vicino via Boost wrote:

> I'm working in simplifying safe_float to prepare it for future review.
>
> For now I'm focusing in a C++17 compatible version.
>
> Currently safefloat receives 2 template parameters:
>
> template<typename FP, typename P>
> class safe_float ...
>
> Where FP is the floating point value being made "safe", float, double, long
> double ...
> and P is a Policy of what to check and how to react.
>
> <snip>
> These are the options I'm considering
>
> 1) define typenames for each flag and assign them tuple of affected
> operations
>
> class addition; <snip>
>
> template<typename R>
> struct policy_x {
> using reporter=R;
> using overflow=tuple<addition>; <snip>
> };
>
> 2) define typename by operation, passing class with constexprs of flags
> being evaluated
>
> struct empty_check{
> static constexpr bool check_overflow=false; <snip>
> };
>
> <snip>
>
> 3) similar to 2, but using true_type, and false_type in place of constexpr
> variables.
> <snip>
> 4) other options?
>

What about doing this the old-fashioned way:

constexpr check_policy_t empty_check = 0;
constexpr check_policy_t check_underflow = 0x1;
constexpr check_policy_t check_overflow = 0x2;
...

// with a bit of syntactic sugar:
struct operation_id {
  check_policy_t offset;
  constexpr check_policy_t operator=(check_policy_t value) const
  { return offset * value; }
};

constexpr operation_id
  addition=0x1,
  subtraction=0x100,
  multiplication=0x10000
  ...;

// Usage:
addition=check_overflow|subtraction=empty_check

In Christ,
Steven Watanabe

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Design question SafeFloat

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
Hi Robert,
Thanks for the comment, I started following whats on safe_numerics, but I
feel it gets too complicated to use in the case of floating point where
there is so many policy combinations I want to allow. I got the feeling
something easier can be built to handle this particular case.
However, I'm exploring alternatives, if I cannot find a simple elegant
solution I will go back to similar approach to the one used in
safe_numerics.

2018-07-27 10:05 GMT-04:00 Robert Ramey via Boost <[hidden email]>:

> On 7/26/18 8:25 PM, Damian Vicino via Boost wrote:
>
>> Hi,
>> I'm working in simplifying safe_float to prepare it for future review.
>>
>> For now I'm focusing in a C++17 compatible version.
>>
>> Currently safefloat receives 2 template parameters:
>>
>> template<typename FP, typename P>
>> class safe_float ...
>>
>> Where FP is the floating point value being made "safe", float, double,
>> long
>> double ...
>> and P is a Policy of what to check and how to react.
>>
>
> It might be helpful to look at how safe numerics does it.
>
> Robert Ramey
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman
> /listinfo.cgi/boost
>

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: Design question SafeFloat

Boost - Dev mailing list
In reply to this post by Boost - Dev mailing list
Hi Steven,
Thats kind of what I would like to have, I was wondering of something like
that using "enum class" for type_safety would work.
I will give it a try and see how it goes.
Thanks for the comment.
Damian


2018-07-27 14:38 GMT-04:00 Steven Watanabe via Boost <[hidden email]>
:

> AMDG
>
> On 07/26/2018 09:25 PM, Damian Vicino via Boost wrote:
> > I'm working in simplifying safe_float to prepare it for future review.
> >
> > For now I'm focusing in a C++17 compatible version.
> >
> > Currently safefloat receives 2 template parameters:
> >
> > template<typename FP, typename P>
> > class safe_float ...
> >
> > Where FP is the floating point value being made "safe", float, double,
> long
> > double ...
> > and P is a Policy of what to check and how to react.
> >
> > <snip>
> > These are the options I'm considering
> >
> > 1) define typenames for each flag and assign them tuple of affected
> > operations
> >
> > class addition; <snip>
> >
> > template<typename R>
> > struct policy_x {
> > using reporter=R;
> > using overflow=tuple<addition>; <snip>
> > };
> >
> > 2) define typename by operation, passing class with constexprs of flags
> > being evaluated
> >
> > struct empty_check{
> > static constexpr bool check_overflow=false; <snip>
> > };
> >
> > <snip>
> >
> > 3) similar to 2, but using true_type, and false_type in place of
> constexpr
> > variables.
> > <snip>
> > 4) other options?
> >
>
> What about doing this the old-fashioned way:
>
> constexpr check_policy_t empty_check = 0;
> constexpr check_policy_t check_underflow = 0x1;
> constexpr check_policy_t check_overflow = 0x2;
> ...
>
> // with a bit of syntactic sugar:
> struct operation_id {
>   check_policy_t offset;
>   constexpr check_policy_t operator=(check_policy_t value) const
>   { return offset * value; }
> };
>
> constexpr operation_id
>   addition=0x1,
>   subtraction=0x100,
>   multiplication=0x10000
>   ...;
>
> // Usage:
> addition=check_overflow|subtraction=empty_check
>
> In Christ,
> Steven Watanabe
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/
> mailman/listinfo.cgi/boost
>

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost