Boost logo

Boost :

Subject: [boost] Design question SafeFloat
From: Damian Vicino (damian_at_[hidden])
Date: 2018-07-27 03:25:22


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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk