LEAF is a small C++11 error handling library (the acronym stands for Low-latency Error Augmentation Framework). Features: - Header-only, NO dependencies. - No dynamic memory allocations. - Associate objects of arbitrary types with any failure — when it is initially reported or at a later time. - Compatible with std::error_code, errno and any other error handling API. - Use with or without exception handling. - Support for multi-thread programming. Official documentation: https://zajo.github.io/leaf. LEAF is designed for use in low-latency environments without exception handling, but it also works with exception handling; in that case it is a better, more optimal replacement for Boost Exception. This link can be helpful for refactoring existing Boost Exception code: https://zajo.github.io/leaf/#boost_exception.
On Tue, Dec 18, 2018 at 9:00 PM Emil Dotchevski via Boost
LEAF is a small C++11 error handling library (the acronym stands for Low-latency Error Augmentation Framework).
Features:
- Header-only, NO dependencies. - No dynamic memory allocations. - Associate objects of arbitrary types with any failure — when it is initially reported or at a later time. - Compatible with std::error_code, errno and any other error handling API. - Use with or without exception handling. - Support for multi-thread programming.
Official documentation: https://zajo.github.io/leaf.
LEAF is designed for use in low-latency environments without exception handling, but it also works with exception handling; in that case it is a better, more optimal replacement for Boost Exception. This link can be helpful for refactoring existing Boost Exception code: https://zajo.github.io/leaf/#boost_exception.
I reviewed your Travis CI results. If possible, consider providing the following as well to improve overall quality. It would be nice for all new libraries to meet these requirements to help ensure better quality of components entering the suite. * code coverage, for example codecov.io, specifically branch coverage numbers * static analysis, for example cppcheck and/or coverity scan * UBSAN and valgrind * AppVeyor results for MSVC 2010 - 2017, MinGW 32-bit and 64-bit, and cygwin 32-bit and 64-bit Examples of these can be found in: https://github.com/boostorg/boost-ci Thanks! - Jim
Got AppVeyor working only for Visual Studio 2015-2017, because at this time LEAF requires C++11 for lambda and variadic templates. It is probably possible to port it to older C++ versions if there is demand. On Tue, Dec 18, 2018 at 7:54 PM James E. King III via Boost < boost@lists.boost.org> wrote:
On Tue, Dec 18, 2018 at 9:00 PM Emil Dotchevski via Boost
wrote: LEAF is a small C++11 error handling library (the acronym stands for Low-latency Error Augmentation Framework).
Features:
- Header-only, NO dependencies. - No dynamic memory allocations. - Associate objects of arbitrary types with any failure — when it is initially reported or at a later time. - Compatible with std::error_code, errno and any other error handling API. - Use with or without exception handling. - Support for multi-thread programming.
Official documentation: https://zajo.github.io/leaf.
LEAF is designed for use in low-latency environments without exception handling, but it also works with exception handling; in that case it is a better, more optimal replacement for Boost Exception. This link can be helpful for refactoring existing Boost Exception code: https://zajo.github.io/leaf/#boost_exception.
I reviewed your Travis CI results. If possible, consider providing the following as well to improve overall quality. It would be nice for all new libraries to meet these requirements to help ensure better quality of components entering the suite.
* code coverage, for example codecov.io, specifically branch coverage numbers * static analysis, for example cppcheck and/or coverity scan * UBSAN and valgrind * AppVeyor results for MSVC 2010 - 2017, MinGW 32-bit and 64-bit, and cygwin 32-bit and 64-bit
Examples of these can be found in:
https://github.com/boostorg/boost-ci
Thanks!
- Jim
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Em qua, 19 de dez de 2018 às 00:00, Emil Dotchevski via Boost < boost@lists.boost.org> escreveu:
Official documentation: https://zajo.github.io/leaf.
Could you add a section specifically comparing LEAF to Boost.Outcome? -- Vinícius dos Santos Oliveira https://vinipsmaker.github.io/
śr., 19 gru 2018 o 03:00 Emil Dotchevski via Boost
LEAF is a small C++11 error handling library (the acronym stands for Low-latency Error Augmentation Framework).
Features:
- Header-only, NO dependencies. - No dynamic memory allocations. - Associate objects of arbitrary types with any failure — when it is initially reported or at a later time. - Compatible with std::error_code, errno and any other error handling API. - Use with or without exception handling. - Support for multi-thread programming.
Official documentation: https://zajo.github.io/leaf.
LEAF is designed for use in low-latency environments without exception handling, but it also works with exception handling; in that case it is a better, more optimal replacement for Boost Exception. This link can be helpful for refactoring existing Boost Exception code: https://zajo.github.io/leaf/#boost_exception.
Hi Emil, Thank you for sharing the library. I only had a look at the documentation (which is really high standard) to try to determine the difference between LEAF and Boost.Outcome. It is my understanding that the main difference is that LEAF allows heap-free type erasure of error-related data at the expense of exploiting thread-local storage. Is this a fair summary? Regards, &rzej;
On Fri, Jan 4, 2019 at 6:07 AM Andrzej Krzemienski via Boost < boost@lists.boost.org> wrote:
śr., 19 gru 2018 o 03:00 Emil Dotchevski via Boost
napisał(a): LEAF is a small C++11 error handling library (the acronym stands for Low-latency Error Augmentation Framework).
Features:
- Header-only, NO dependencies. - No dynamic memory allocations. - Associate objects of arbitrary types with any failure — when it is initially reported or at a later time. - Compatible with std::error_code, errno and any other error handling API. - Use with or without exception handling. - Support for multi-thread programming.
Official documentation: https://zajo.github.io/leaf.
LEAF is designed for use in low-latency environments without exception handling, but it also works with exception handling; in that case it is a better, more optimal replacement for Boost Exception. This link can be helpful for refactoring existing Boost Exception code: https://zajo.github.io/leaf/#boost_exception.
Hi Emil, Thank you for sharing the library. I only had a look at the documentation (which is really high standard) to try to determine the difference between LEAF and Boost.Outcome. It is my understanding that the main difference is that LEAF allows heap-free type erasure of error-related data at the expense of exploiting thread-local storage. Is this a fair summary?
LEAF does not store the error objects in thread-local storage, they are moved from error-reporting functions directly into a std::tuple stored locally in the error-handling function. This is entirely static and type-safe. I know there are people who want to focus on LEAF using thread-local storage, but 1) this is limited to static pointers (no dynamic initialization or destruction of TLS objects) and 2) it doesn't do justice to the design. I've included in the documentation what I believe is a fair analysis of the different design choices made by LEAF and Boost Outcome: https://zajo.github.io/leaf/#_comparison_to_boost_outcome.
I've included in the documentation what I believe is a fair analysis of the different design choices made by LEAF and Boost Outcome: https://zajo.github.io/leaf/#_comparison_to_boost_outcome.
Firstly, I like this library much more than your preceding design. Well done on this design! Secondly, thanks for the fair comparison. I've added an issue to do the same from the opposite perspective at https://github.com/ned14/outcome/issues/163. (Minor niggle: `EP` refers to an "exception" object, not a "pointer" object. It doesn't need to be a pointer) Other differences not in your comparison: 1. Outcome doesn't do matchers because I strongly think a separate Boost library should implement them in a generic way. I would urge you to split your matchers from LEAF into a standalone library. I think such a thing would be an *amazing* standalone library, and if you add it, Outcome will reuse it. And for the record, lovely matcher design. I think probably optimal given the current language. 2. Outcome pushes the choice of how to do type erasure and polymorphic matching onto the end user through their choice of a common E type. std::error is the poor man's implementation, but probably sufficient for most users. P1028 https://github.com/ned14/status-code is markedly superior. LEAF implements in-house what Outcome outsources. I'm not convinced of the value add here. If you split off the matchers into a standalone library, and Outcome adds support for those, the difference remaining between LEAF and Outcome turns into one of how parameters are in the result<> type. As Outcome using code will almost certainly be typedefing the underlying type into something more readable, I find the remaining difference unconvincing of a separate library personally. 3. I get that by not specifying error types in the type one causes interoperability between disparate libraries to appear to improve in that everything compiles. But you've really just hidden the potential misoperation by turning it into a runtime problem. I deliberately didn't choose that for Outcome for the same reasons that dynamic exception specifications are a bad idea. I personally think LEAF's choice on this too close to that terrible design mistake, now thankfully deprecated from the standard. You probably now have a gist of my review if your library came to review. I do love the matchers. Great job. I like most of the rest of the design, apart from the hiding of ABI incompatibilities into the (unpredictable) runtime. But I also recognise that the same hiding of incompatibility affects std::error, and P1028 status code. I just think that by allowing the user to choose an E type not affected by these issues, one offers the option to users to avoid that devil's nest. Meanwhile LEAF *builds in* that devil's nest as a design feature. I find that problematic. Otherwise great job, and much improved on before. Thanks for the library! (And FYI, Herb is not against static exception specifications, your Design Rationale makes it seem he is. In fact, his main opposition to them was that the committee would never agree to them due to them looking too much like dynamic exception specifications. However we got WG14 to agree to them in the Pittsburgh meeting, and that seems to have had a big effect on WG21's opinion. But WG21 has yet to debate them, maybe at Kona, definitely at Cologne. Still, I personally wouldn't claim what you do in your docs, it's too strong, the guy who has been working on exceptions support for C for the past thirty years agreed to static exception specifications. And he *really* knows his stuff on this - C hasn't added exceptions because the design isn't fully baked yet, not because they haven't been actively worked upon for decades now) (Second aside: you appear to assume that thread local storage does not dynamically allocate memory. The standard specifically allows implementations to do this, even for a stupid type like int. I think you can make the claim that no dynamic memory allocation occurs for TLS only on named architectures and compilers. GPUs currently do not implement TLS. I think you need to mention that more loudly, as native C++ on GPUs is becoming real world use case) Niall
pt., 4 sty 2019 o 20:55 Emil Dotchevski via Boost
On Fri, Jan 4, 2019 at 6:07 AM Andrzej Krzemienski via Boost < boost@lists.boost.org> wrote:
śr., 19 gru 2018 o 03:00 Emil Dotchevski via Boost < boost@lists.boost.org> napisał(a):
LEAF is a small C++11 error handling library (the acronym stands for Low-latency Error Augmentation Framework).
Features:
- Header-only, NO dependencies. - No dynamic memory allocations. - Associate objects of arbitrary types with any failure — when it is initially reported or at a later time. - Compatible with std::error_code, errno and any other error handling API. - Use with or without exception handling. - Support for multi-thread programming.
Official documentation: https://zajo.github.io/leaf.
LEAF is designed for use in low-latency environments without exception handling, but it also works with exception handling; in that case it is a better, more optimal replacement for Boost Exception. This link can be helpful for refactoring existing Boost Exception code: https://zajo.github.io/leaf/#boost_exception.
Hi Emil, Thank you for sharing the library. I only had a look at the documentation (which is really high standard) to try to determine the difference between LEAF and Boost.Outcome. It is my understanding that the main difference is that LEAF allows heap-free type erasure of error-related data at the expense of exploiting thread-local storage. Is this a fair summary?
LEAF does not store the error objects in thread-local storage, they are moved from error-reporting functions directly into a std::tuple stored locally in the error-handling function. This is entirely static and type-safe.
I know there are people who want to focus on LEAF using thread-local storage, but 1) this is limited to static pointers (no dynamic initialization or destruction of TLS objects) and 2) it doesn't do justice to the design. I've included in the documentation what I believe is a fair analysis of the different design choices made by LEAF and Boost Outcome: https://zajo.github.io/leaf/#_comparison_to_boost_outcome.
Thanks for the clarification. The reason for the interest in TLS usage is that accessing any globals (TLS being a global in this sense), including ints and pointers, makes functions not refrentially transparent and inhibits optimizations such as common subexpression elimination. I guess this concern will be addressed when some benchmarking is performed. I acknowledge that this is not the only difference between the two libraries. I guess it is just my bias towards performance that makes me overlook other aspects. Regards, &rzej;
The reason for the interest in TLS usage is that accessing any globals (TLS being a global in this sense), including ints and pointers, makes functions not refrentially transparent and inhibits optimizations such as common subexpression elimination.
I guess this concern will be addressed when some benchmarking is performed.
I acknowledge that this is not the only difference between the two libraries. I guess it is just my bias towards performance that makes me overlook other aspects.
It's definitely the case that thread_local storage is currently poorly optimised on any major compiler. See https://godbolt.org/z/eDiIV0 for just how badly (this should optimise down to 'puts("boo\n")'). But it *could* be the case that compilers wouldn't suck so bad in the future. That said, Outcome was specifically designed for today's compilers with all their failings. It was not designed for hypothetical future compilers. (In case anyone is wondering, Outcome is into the boost superproject for the 1.70 release. I am currently writing the Python scripting to replicate, perfectly, the commit history from Outcome into Boost.Outcome for master and develop branches) Niall
On Wed, Jan 9, 2019 at 4:41 AM Niall Douglas via Boost < boost@lists.boost.org> wrote:
But it *could* be the case that compilers wouldn't suck so bad in the future. That said, Outcome was specifically designed for today's compilers with all their failings. It was not designed for hypothetical future compilers.
I have not done benchmarking on LEAF but there are probably many toy examples where LEAF will work a lot faster than Outcome, and others that would be the other way around. If we are fair, we'd admit that none of them matter if a library in practice doesn't cause performance problems (read: doesn't show up high in the profile.) (If you doubt this, consider that when an error object is transported over many stack frames, LEAF does exactly one move, which is always done statically regardless of the function signature, except when it isn't done at all, which is the case when the program doesn't need that particular error object in that particular case. Best case for returning errors coupled with the return object is O(N).
participants (5)
-
Andrzej Krzemienski
-
Emil Dotchevski
-
James E. King III
-
Niall Douglas
-
Vinícius dos Santos Oliveira