Boost logo

Boost :

Subject: Re: [boost] Reforming Boost.System and <system_error> round 2
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2018-01-16 17:26:55


On 01/16/18 20:09, Peter Dimov via Boost wrote:
> Andrey Semashev wrote:
>
>> Calling (virtual) `error_category::failure` early is a waste if the
>> user doesn't want to call that function himself. For instance, he may
>> want to test specific error codes instead.
>
> It can still be worth it because it's more likely to occur in a context
> where the compiler can see what category is being used. When you have
>
>    error_code ec( r, system_category() );
>
> and system_category() is constexpr, the compiler knows with certainty
> what the call category().failed( r ) will do, so it will replace it with
> r != 0.

This will only be possible if the implementation of the category is
visible at the point of `error_code` construction. I'm assuming that
typically it is not.

If the category is supposed to be visible then there is no reason to
make that method virtual. Make it a regular function and change the
constructor like this:

   template<
     typename Category,
     enable_if_t< is_base_of_t< error_category, Category > >
>
   constexpr error_code(int v, const Category &cat)
     : _value(v), _is_failure(cat.is_failure(v)), _category(&cat) {}

Although, honestly, I don't see much point in having that function in
the category at this point. The code should be more clean if it tested
the code against the enum values instead of `int`. So instead of this:

   bool my_category::is_failure(int err)
   {
     return static_cast< my_error >(err) < my_error::min_success ||
       static_cast< my_error >(err) > my_error::max_success;
   }

I would prefer this:

   error_code make_error_code(my_error err)
   {
     return error_code(static_cast< int >(err),
       err < my_error::min_success || err > my_error::max_success,
       my_category);
   }

Note that this approach allows to generate `error_code` objects with the
same category from multiple different enums. I think, someone mentioned
a use case for this earlier in the discussion - when multiple enums
basically map onto the common error domain, which has a single error
category.


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