518 | | The third caveat is that I personally plan to write a much lighter weight monadic result transport which isn't as flexible as expected<T, E> (and probably hard coded to a T, error_code and exception_ptr outcomes) but would have negligible effects on compile times, and very deep integration with a non-allocating all-constexpr new lightweight future-promise implementation. Once implemented, my monadic transport may be disregarded by the community, evolved more towards expected<T, E>, or something else entirely may turn up. |
| 517 | The third caveat is that [https://github.com/ned14/boost.spinlock/blob/master/include/boost/spinlock/monad.hpp I have written a much lighter weight monadic result transport] which isn't as flexible as expected<T, E> (and is hard coded to a T, error_code and exception_ptr outcomes) but has negligible effects on compile times, and very deep integration with a forthcoming non-allocating all-constexpr new lightweight future-promise implementation. Once implemented, my monadic transport may be disregarded by the community, evolved more towards expected<T, E>, or something else entirely may turn up. As a quick taster: |
| 518 | |
| 519 | {{{#!c++ |
| 520 | using namespace boost::spinlock::lightweight_futures; |
| 521 | monad<std::shared_ptr<handle_type>> openfile(std::filesystem::path path) noexcept |
| 522 | { |
| 523 | int fd; |
| 524 | while(-1==(fd=::open(path.c_str(), 0)) && EINTR==errno); |
| 525 | try |
| 526 | { |
| 527 | if(-1==fd) |
| 528 | { |
| 529 | int code=errno; |
| 530 | // If a temporary failure, this is an expected unexpected outcome |
| 531 | if(EBUSY==code || EISDIR==code || ELOOP==code || ENOENT==code || ENOTDIR==code || EPERM==code || EACCES==code) |
| 532 | return std::error_code(code, std::generic_category()); |
| 533 | |
| 534 | // If a non-temporary failure, this is an unexpected outcome |
| 535 | return std::make_exception_ptr(std::system_error(code, std::generic_category(), strerror(code))); |
| 536 | } |
| 537 | return std::make_shared<handle_type>(fd); |
| 538 | } |
| 539 | catch(...) |
| 540 | { |
| 541 | // Any exception thrown is truly unexpected |
| 542 | return std::current_exception(); |
| 543 | } |
| 544 | } |
| 545 | }}} |
| 546 | |
| 547 | This lightweight monadic implementation generates about 260 x64 opcodes, not enormously more than if the monadic transport were not being used at all. This lightweight monad isn't quite ready for prime time yet though, but should be by August 2015. |