Comments (14)
It appears that this did still work with 2.1.5, but not with 2.2.0.
from outcome.
I have to say, I would be surprised if this worked in 2.1.5, or at least if it was supposed to. In 2.1.5, the default error type is system_code
, which is a move only type with a non-trivial destructor. Therefore, any basic_result
with a non-trivially destructible error type would itself be non-trivially destructible, and thus not possible to be a literal type.
I suppose what could have happened here is that you were compiling with C++ 20, whereby if a non-trivial destructor is constexpr, now that works in constexpr?
from outcome.
Indeed, the original code that I discovered this is C++20, and this is what I care about.
However, I have to admit that I don't fully understand the rules that make up a literal type, and how that interacts with returning from constexpr functions.
In my code-base, the error type is outcome::errored_status_code
over a custom domain that is derived from outcome::status_code_domain
, whose value type is a custom enum. If I recall correctly, the system_code
implicitly used in my MVE is an erased int-sized status - does that make system_code
non-trivially destructible, while mine is?
In any case, with 2.1.5 I am able to return status_result<std::size_t, errored_status_code<my_domain>>
from constexpr functions, but with 2.2.1, I get that above error. Is there a simple error code in outcome which is a literal type and thus would allow for a quick test?
from outcome.
It was pure luck that system_code
happened to work in constexpr if in C++ 20 in your use case. I certainly never intended it to do so, I was writing for C++ 11 (for status code) and C++ 14 (for Outcome) and I was always thinking that the non-trivial destructor made system_code
unavailable to any constexpr code. This is the case for all erased status codes, because they may be carrying an erased move only type. So they have to have move only semantics, and therefore non-trivial destructors.
(The pertinent rule for literal types in this situation is that before C++ 20, the type had to have a trivial destructor, but from C++ 20 onwards, the destructor merely needs to be constexpr. Because Outcome v2.1 just happened to default destructors, by happy accident your use case worked)
In any case, with 2.1.5 I am able to return status_result<std::size_t, errored_status_code<my_domain>> from constexpr functions, but with 2.2.1, I get that above error. Is there a simple error code in outcome which is a literal type and thus would allow for a quick test?
Most if not all of the non-erased status codes are literal types, if the payload is a literal type, so will be its status code.
I am minded however to try to fix this for you because status code is before LEWG for standardisation, and LEWG I expect would prefer to see all of status code available to constexpr. I honestly don't know if it's possible however, but I intend to try.
from outcome.
Thanks for looking into this!
I think it makes perfectly sense for non-trivial status types not to be available for constexpr use. My own experience with constexpr and type-erasure is that they don't go well together: The reinterpret_cast
you'll likely need somewhere is a hard no. Maybe the new std::bit_cast
might help here, but my compiler doesn't support it yet, so I have little experience.
from outcome.
Here is a more accurate minimal failing example (godbolt):
#include <exception>
#include <outcome-experimental.hpp>
namespace outcome = OUTCOME_V2_NAMESPACE;
enum class Status {
success,
failure
};
class _status_domain : public outcome::experimental::status_code_domain {
// We permit status code to call our protected functions
template <class DomainType>
friend class system_error2::status_code;
using _base = outcome::experimental::status_code_domain;
public:
// Our value type is Status
using value_type = Status;
using _base::string_ref;
// Always use https://www.random.org/cgi-bin/randbyte?nbytes=8&format=h to
// create a unique 64 bit value for every unique domain you create!
_status_domain() noexcept : _base(0x8f9f78114be043e4) {}
// Default all the copy, move and destruct. This makes the type 100% constexpr
// in every way which in turns allows the compiler to assume it will not be
// instantiated at runtime.
_status_domain(const _status_domain &) = default;
_status_domain(_status_domain &&) = default;
_status_domain &operator=(const _status_domain &) = default;
_status_domain &operator=(_status_domain &&) = default;
~_status_domain() = default;
// Fetch a constexpr instance of this domain
static inline constexpr const _status_domain &get();
// Return the name of this domain
virtual _base::string_ref name() const noexcept override final {
return _base::string_ref("_status_domain");
}
};
using errored_status_code = outcome::experimental::errored_status_code<_status_domain>;
constexpr outcome::experimental::status_result<void, errored_status_code> foo(int) {
return outcome::success();
}
If I understood correctly, the errored_status_code
in this example should be a literal type (Status
is), though the derived status_result<void, errored_status_code>
is not.
from outcome.
Sorry to not have gotten onto this yet. Awaiting an unoccupied morning before work slot to turn up.
from outcome.
No worries, this is open-source, I wasn't expecting priority support. If it were an urgent need for me, I ought to try to provide a PR myself. Its not urgent though, so I just wanted to make sure that I understand if this is even possible and intended to be supported, or if I better start refactoring my code.
from outcome.
Try the commit above and let me know how you get on.
from outcome.
Any news on the above?
from outcome.
Hey @ned14, sorry for the delay. Unfortunately, on my internal code-base, that commit with GCC 10.2 still complains with invalid return type outcome::basic_result<...,system_error2::errored_status_code<my_status_domain>,...>
of 'constexpr' function, where my_status_domain
has a simple enum class
value_type
. I'll try to run my minimal failing example locally later today.
from outcome.
Indeed, the above minimal example does compile now. I'll have to dig deeper then to see where the problem in my code is...
from outcome.
It could be as little as a single missing constexpr
anywhere in my code or yours. I find using latest versions of GCC, clang and MSVC can help generate a useful diagnostic. Good luck in finding it!
from outcome.
I'm going to go ahead and mark this closed. Thanks for the BR!
from outcome.
Related Issues (20)
- `__cpp_modules` now defined in latest MSVC (version > 16.9) HOT 11
- OUTCOME_TRY does not propagate spare storage HOT 1
- Add check that `basic-outcome.hpp` never includes headers it is documented to not include
- warning: the 'bool' keyword is not allowed in a C++20 concept definition HOT 5
- error C2230: could not find module 'BOOST_OUTCOME_V2_BOOST_OUTCOME_C_MODULE_NAME' HOT 1
- Outcome failed to build due to error C2230 C7568 C2955 C2057 on windows with MSVC HOT 3
- Worked example for experimental features failed to compile on g++-7 HOT 6
- Example doesn't compile HOT 7
- checked<T,E> is not move assignable if T is not copy constructible HOT 5
- Problem with void value type and nontrivial assignment operators HOT 2
- change of no-error path behavior leading to maybe-uninitialized warning HOT 2
- Build fails with ninja generator HOT 2
- Build fails with MSVC HOT 2
- Build fails with GCC 10 HOT 4
- Errors with non-embedded status code HOT 3
- .
- msvc 2022 C2027, compilation error HOT 3
- hooks.cpp, expected-pass.cpp fail on msvc-14.2; expected-pass.cpp fails on msvc-14.3 HOT 22
- WG21-P1886 errors HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from outcome.