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
;
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.
I am geting some contradictory information here. Is the fact that outcome<T> is built of policies part of the API which you commit to support in subsequent releases? It was my impression that you never wanted this to be exposed to the users. Now, when you use name "API" it looks like you do want to expose the policies?
Outcome was always supposed to be a *family* of Either monad varieties which had well defined interoperation semantics with one another. So the original idea was that there was a clean progression from option<T> right through to future<T> with a single common implementation, with a common DO/TRY/AWAIT mechanism, a common monadic BIND and MAP mechanism and so on. However I am personally uncomfortable supporting code I don't use in my own software, so after AFIO v1 was rejected, my personal need for such a wide family of Either monads, and the monadic operations, went away, including the promise/future specialisation. You thus got the Outcome presented for review here today which had been reduced to just outcome, result and option. During this review there are clear disagreements about what form and semantics a C++ Either monad should take. People aren't even sold on the Expected proposal. I don't get that criticism, I think the Expected proposal just fine, but there you go. Outcome's CRTP policy based implementation is very flexible. All the code to implement all the varieties of Either monad which someone has asked for at least once in this review is already in Outcome. It would be a bit of work, but not too awful, to replace the preprocessor stamping out of hard coded prefabricated specialisations for outcome, result, option and expected with a template based compile time assembly of parts to provide all the varieties mentioned above. I count: 4 x 3 x 3 x 3 combinations = 108 Either monad varieties You can't possibly hope to test all these in a test suite. It's another reason why I didn't propose this design originally. But if it's what people want, and it's not stupidly dangerous which this is not, I can give the people what they want. (BTW, originally Outcome *did* use a template based compile time assembly of parts. I replaced it with a hard coded preprocessor generated edition for lower compile time cost. But the old mechanism can be restored, and that would eliminate most of the preprocessor template based code generation which some have complained about. I personally suspect the template based system will be not particularly easier for casual reading) So do I want to expose the policies? Not really. But I can see no consensus opinion on the shape and form for Expected, let alone for Outcome, will emerge. So I propose Outcome provides all one hundred and eight varieties of Either monad, and let Boost keep its reputation for overwhelming complexity. We'll see which forms end up being used most by end users, and that would be great information for Vicente and WG21 to have to hand during standardisation. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/