Boost logo

Boost :

Subject: Re: [boost] [review] Review of Outcome (starts Fri-19-May)
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-05-21 18:54:06


>> Totally up to the end user.
>
> I know that it's totally up to the end user. I'm asking for a few
> real-world examples of use. What do you use them for, what do your users
> use them for?

Oh, ok.

Here's an example from
https://github.com/ned14/boost.kerneltest/blob/5bf4b78569366198af745ec6b7319e0ed4d91f6e/include/boost/kerneltest/v1.0/hooks/filesystem_workspace.hpp#L440:

            // If this is empty, workspaces are identical
            result<stl1z::filesystem::path> workspaces_not_identical =
compare_directories<false, false>(current_test_kernel.working_directory,
model_workspace);
            // Propagate any error
            if(workspaces_not_identical.has_error())
              testret =
error_code_extended(make_error_code(kerneltest_errc::filesystem_comparison_internal_failure),
workspaces_not_identical.get_error().message().c_str(),
workspaces_not_identical.get_error().value());
            // Set error with extended message of the path which differs
            else if(workspaces_not_identical.has_value())
              testret =
error_code_extended(make_error_code(kerneltest_errc::filesystem_comparison_failed),
workspaces_not_identical.get().string().c_str());

So compare_directories() walks two directory structures using the
Filesystem TS and compares them for equivalence using fuzzy criteria.
Here we use the empty state to indicate "directory trees are identical",
an error state to indicate an error occurred, and a valued state to give
the path of the first item which differed.

(I know this looks like an inverted logic from traditional outcome
usage, but this shows exactly the usefulness of the three-state outcome.
Here empty is "failure to find a difference", valued is "succeeded to
find a difference")

If there was an error, we return an error code of
kerneltest_errc::filesystem_comparison_internal_failure with a payload
of the string message from the source error and its original error code
in the first 32 bit code1 integer. That is used later on to print the
exact error code returned by the system as we know it will always be
system_category.

If the directory structures differed, we return an error code of
kerneltest_errc::filesystem_comparison_failed with a payload of the
string of the path which did not match.

Is this sufficient, or would you prefer a different example?

>> >> I'll leave it to reviewers to decide on whether defaulting to the
>> C++ >> 14 STL std::error_code or to boost::error_code is the most
>> appropriate.
>> >
>> > I'm not sure you understand me here... I'm saying that there's no
>> need > to default to boost::error_code or even keep the stl11:: way of
>> choosing > between the two.
>>
>> Retaining standalone usability of Outcome is a high priority for me. A
>> lot of folk from SG14 are interested in using Outcome, and I intend to
>> submit Outcome into SG14's collection of low latency suitable libraries.
>
> I'm now sure that you don't understand, because your answer makes no
> sense. I'm telling you TO NOT USE BOOST::ERROR_CODE, and you tell me
> that you'd rather retain standalone usability. Hello?

Unless I have misunderstood your patch, you bring in error_condition
comparisons from <system_error> allowing one to compare error codes to
error conditions across both Boost and STL error categories.

This is fine, and indeed valuable. But it isn't relevant to Outcome
particularly because we cannot say what the end user is doing with their
error_code, and certainly not if whatever they are doing has any
relation to error_condition. For example, as mentioned earlier in the
thread, Chris was using a custom http_error category for the HTTP status
codes. That has no useful mapping onto error_condition except for the
identity map, and most code will therefore just go ahead and use the
error code directly and save on the boilerplate.

One could create one's own error_code implementation which uses the STL
or Boost error categories, and provide mapping into error_condition.
This would let you embed whatever payload you like into Outcome's
error_code. Indeed, if reviewers dislike error_code_extended storing the
payload into global static memory like it does, the next least worst
solution is probably one's own custom error_code implementation with
user definable payload.

But this is not a cost free design choice, you lose compatibility with
all code using std::error_code. The current design lets you do stuff
like static_cast from a passed in error_code& to an error_code_extended&
if you know the original is definitely an extended error code. I figured
that much more likely a use case in say something like ASIO which is
hard wired to use const error_code&. But maybe it's a price worth
paying. Let's see what reviews recommend.

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

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