ned14 / status-code

Proposed SG14 status_code for the C++ standard

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

A few questions about the usage/implementation

zomgrolf opened this issue · comments

Hi,

I'm trying to better understand how it all works and how I can use status_code in my projects.

  1. Is the expectation that any library/application that wants to define custom error codes (using enum classes) will always need to define one or more matching custom error domains?

  2. Is there a safe way to recover the non-erased status_code from system_code, assuming I know exactly what type the system_code value was constructed with? What if I need to transport status_code through a layer of code that does not understand this machinery (say, C or C++98/03)? Is system_code the best I can have after going through such a layer? If not, what is the recommended pattern for recovering the underlying system_code?

  3. The type-erased system_code looks like a very useful type, especially in public API -- and looking at the source code, documentation and the examples, it looks like it's typically constructed from a non-type erased status_code (either by returning from a function or some form of copy-initialisation/assignment). Looking at the source code some more, it seems there is a constructor for creating a type-erased system_code directly from arguments, if there is a suitable overload of make_status_code, that can be found by the ADL. Is that make_status_code supposed to always return some non-erased status_code type or is there a way to create a type erased status_code implicitly? The SFINAE condition on the implicit constructor for status_code<erased> looks a bit confusing to me, especially the bit that seems to forbid constructing from T (!std::is_same<typename std::decay<T>::type, value_type>::value), even though T ends up being the type of the value stored in the erased status_code.

  4. I struggle a bit trying to think of any scenarios where I would want/need to consider using type-erased status_code with type other than intptr_t. Am I right in thinking that one possible use case is when I absolutely need a bigger payload than the default (and willing to accept that it will no longer fit in two CPU registers)? Any point in using a type-erased status_code with a smaller type (e.g. int)?

Is there any significance as to what the T in status_code<erased> is, other than its size?

Sorry, if these questions are dumb/obvious, just trying to get it to 'click' and, apart from a few concepts, I feel I'm not that far off...

Thanks!

Is the expectation that any library/application that wants to define custom error codes (using enum classes) will always need to define one or more matching custom error domains?

It is the same as for error_code, so if you want to preserve the original error coding exactly, then yes you need to make a custom error domain to represent it to the wider system.

Is there a safe way to recover the non-erased status_code from system_code, assuming I know exactly what type the system_code value was constructed with? What if I need to transport status_code through a layer of code that does not understand this machinery (say, C or C++98/03)? Is system_code the best I can have after going through such a layer? If not, what is the recommended pattern for recovering the underlying system_code?

If a status code is not erased, then it knows its type, and its .value() will retrieve the original payload.

If you erased to status_code<void>, use static cast to put it back to its original type.

If you erased to status_code<erased<>>, there is an explicit constructor available to convert it back into its typed form.

Is that make_status_code supposed to always return some non-erased status_code type or is there a way to create a type erased status_code implicitly?

If you provide an ADL discovered make_status_code() free function which consumes say a custom enum type, and produces an appropriate status code which is erasable to system_code, then you can return your custom enum from a function returning system_code directly. This saves a bit of typing, and complexity on the screen.

I struggle a bit trying to think of any scenarios where I would want/need to consider using type-erased status_code with type other than intptr_t.

I had in mind crypto hashes specifically, so a crypto hash of an error detail object stored elsewhere. Also extended precision pointers, if we end up adding those to C++.

Is there any significance as to what the T in status_code is, other than its size?

So long as it is move relocating (possibly being added to the language in the future), we don't care, it's just a bunch of bits.