Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Data or Exception

But a more natural API for a function that obtains data is to return only the data on success, throwing an exception on error.

As with write() above, it’s certainly possible to code a read() wrapper in terms of read_ec(). But since a given application is unlikely to need both, let’s code read() from scratch, leveraging promise::set_exception():

std::string read( AsyncAPI & api) {
    boost::fibers::promise< std::string > promise;
    boost::fibers::future< std::string > future( promise.get_future() );
    // Both 'promise' and 'future' will survive until our lambda has been
    // called.
#if ! defined(BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES)
    api.init_read([&promise]( AsyncAPI::errorcode ec, std::string const& data) mutable {
                           if ( ! ec) {
                               promise.set_value( data);
                           } else {
                               promise.set_exception(
                                       std::make_exception_ptr(
                                           make_exception("read", ec) ) );
                           }
                  });
#else // defined(BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES)
    api.init_read(
            std::bind([]( boost::fibers::promise< std::string > & promise,
                          AsyncAPI::errorcode ec, std::string const& data) mutable {
                           if ( ! ec) {
                               promise.set_value( data);
                           } else {
                               promise.set_exception(
                                       std::make_exception_ptr(
                                           make_exception("read", ec) ) );
                           }
                  },
                  std::move( promise),
                  std::placeholders::_1,
                  std::placeholders::_2) );
#endif // BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES
    return future.get();
}

future::get() will do the right thing, either returning std::string or throwing an exception.


PrevUpHomeNext