|
Boost : |
Subject: [boost] [outcome] New proposed factory API as per review feedback
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-05-24 21:11:49
>> Earlier rounds of feedback from Reddit convinced me that customising
>> basic_monad is a very niche enterprise. Very, very few users of Outcome
>> will want to do that.
>
> I agree with this assumption. But if this is the case, I think you should
> not expose in the reference section of the documentation that outcome<> has
> a base class. As per your explanation, it is just an implementation detail.
> I am referring to this page:
> https://ned14.github.io/boost.outcome/classboost_1_1outcome_1_1v1__xxx_1_1outcome.html
I didn't want to be accused of misrepresenting the reference
documentation. Actually, I am surprised nobody has yet accused me of
doing so as the doxygen reference docs refer to classes which don't
exist as classes e.g. outcome, result, option.
>> How about these for the narrow contract editions of outcome<T>,
>> result<T> and option<T>:
>>
>> - outcome_u<T>
>> - result_u<T>
>> - option_u<T>
>
> But I mistakenly took it as saying "do it yourself". You were proposing
> more of precooked "transports". Sorry.
Yes I was.
In fact, I am increasingly thinking that a consensus position could be
this type factory template:
// What to default construct to
enum class default_to
{
none,
T,
EC,
E
};
// How much empty state to implement
enum class emptiness
{
never, // imposes restrictions on T, EC, E
formal, // formal empty state
tolerant // empty state iff EC and E don't have nothrow move construction
};
// How narrow or wide the observers will be
enum class observers
{
narrow, // accessing not the current state = reinterpret_cast
wide, // default actions already described earlier this review
single_shot // you can observe state precisely once only
};
// Replacement for basic_monad
template<
class T, // what .value() returns, or void
class EC, // what .error() returns, or void
class E, // what .exception() returns, or void
default_to default_to_config,
emptiness empty_config,
observers observers_config
> class outcome_impl;
// Outcome as apparently desired by reviewers
template<class T> using outcome = outcome_impl<
T,
error_code_extended,
std::exception_ptr,
default_to::none, // default constructed instance =
reinterpret_cast uninitialised memory
emptiness::never, // Never possible to be empty, not ever
observers::narrow // reinterpret_cast all observers
>;
// Result as apparently desired by reviewers
template<class T> using result = outcome_impl<
T,
error_code_extended,
void, // there is still a .exception(), but it returns
void and is not usable
default_to::none, // default constructed instance =
reinterpret_cast uninitialised memory
emptiness::never, // Never possible to be empty, not ever
observers::narrow // reinterpret_cast all observers
>;
> Regarding your suggestion to use `expected<>`, I could use `expected<T,
> error_code_extended>` and this would get me close to `result<T>`, but I get
> no counterpart for `outcome<T>`. Or are you really proposing to add
> `outcome_u<T>` to collection?
Yes I was.
See what you think of the proposed API above. We supply a precanned
outcome<T> and result<T> template alias, but end users can template
alias any configuration they like.
>> If that's the consensus opinion, that's a fair bit of work to implement
>> and I'm fairly sure it will affect compile times, but I am open to it.
>> The single implementation-many personality design I chose is very
>> amenable to such knobs for twiddling.
I may be able to keep compile times low using extern template and
supplying a static library to be linked against. But I believe the above
will punish header only usage badly. I'll do my best.
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