ned14 / outcome

Provides very lightweight outcome<T> and result<T> (non-Boost edition)
https://ned14.github.io/outcome
Other
704 stars 62 forks source link

Question (maybe feature request) about reducing boilerplate for using status_code and status_code_domain #226

Closed hazelnusse closed 4 years ago

hazelnusse commented 4 years ago

Would there be value in a macro that eliminates the boilerplate and lets clients define the following minimal information:

  1. the custom enum class with fields
  2. the unique 64-bit value (passed to status_code_domain constructor)
  3. a string literal describing the enum class (for status_code_domain::name())
  4. the mapping from the custom enum class fields to errc (for status_code_domain::_to_generic_code)
  5. the mapping from the custom enum class fields to a string (for status_code_domain::_do_message()).

I could imagine that 4 & 5 could be a mapper function that returns a static std::map/unorderd_map which maps enum fields to a std::pair<errc, const char *>, or perhaps instead of a mapper function an array of such pairs, with the array indices matching the static_cast(MyEnum::Field), assuming the enum fields go from 0 to N without skipping any.

For simple functions or sets of functions that might fail a handful of different ways the cost of the boilerplate could exceed the cost of the functions themselves so it would be nice to write helpers that encourage the use of the library for the common cases.

I think, but am not sure, that the _do_failure, _do_equivalent, _generic_code, _do_throw_exception, and get implementations in the derived class of status_code_domain would be completely boilerplate, and not really depend on items 2-5, but perhaps there are special cases where these would be customized? I admit my use of the library is not super extensive but from what I can tell most people are likely to simply copy-pasta from the examples, at least at first. I'm mildly curious under what conditions you would customize these functions in ways that deviate much from the example implementations you've provided.

Would it be reasonable to wrap all or almost all of the boilerplate into a macro (or maybe a couple different macros, depending on the use case), so that clients simply define the above 5 things in a way that can be easily pattern-matched from an example, so that folks are more likely to introduce their own enum error classes? It would be a gross macro, to be sure, but if it captures the common implementations, I think it could go a fair way to making the library easier to use.

What do you think?

ned14 commented 4 years ago

Isn't that already available? https://github.com/ned14/status-code#quick-synthesis-of-a-custom-status-code-domain-for-any-arbitrary-enumeration-type

hazelnusse commented 4 years ago

Wow, hadn't seen that, thanks! We are ingesting status_code from what is included under boost experimental. I don't see this in Boost 1.71 (what our codebase is currently on) nor in the latest boost 1.73. Do you intend to update what goes into to boost eventually, or do you think we would be better off depending on status_code that is independent of boost?

ned14 commented 4 years ago

It was awaiting the Boost 1.73 release to issue, should be in Boost 1.74. Until then, you can graft trunk Boost.Outcome into any Boost since 1.60, or use Standalone Outcome.

hazelnusse commented 4 years ago

Thanks @ned14, much appreciated

hazelnusse commented 4 years ago

The example in the README doesn't compile as is, I've filed a bug here: https://github.com/ned14/status-code/issues/24