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

HomeNext

Outcome 2.2 library

Niall Douglas

Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Table of Contents

Prerequisites
Build and install
Review of Error Handling Frameworks
std exception throws
std error codes
std expected
Outcome (proposed std result)
LEAF
Motivation
Exceptions
errno
Error codes
std::error_code
Plugging a library into std::error_code
Plugging a library into boost::system::error_code
Narrow contracts
Future ABI stability guarantees
Tutorial
Essential
Advanced
Recipes
ASIO/Networking TS : Boost < 1.70
ASIO/Networking TS: Boost >= 1.70
Extending BOOST_OUTCOME_TRY
Experimental
The main advantages
Approximate map between error code designs
Major differences
status_result and status_outcome
Tying it all together
Worked example: Custom domain (the short way)
Worked example: Custom domain (the long way)
Using Outcome from C code
API reference
Macros
Concepts
Converters
Traits
Policies
Types
Aliases
Functions
Frequently asked questions
Videos
Changelog
Upgrade guide v2.1 => v2.2
v2.2 major changes
History

Introduction

note

At the end of December 2021, Standalone Outcome went guaranteed future ABI stable. From v2.2.3 onwards, you get ABI compatibilty guarantees across Outcome releases.

Outcome is a set of tools for reporting and handling function failures in contexts where directly using C++ exception handling is unsuitable. Such contexts include:

Outcome addresses failure handling through returning a special type from functions, which is able to store either a successfully computed value (or void), or the information about failure. Outcome also comes with a set of idioms for dealing with such types.

Particular care has been taken to ensure that Outcome has the lowest possible impact on build times, thus making it suitable for use in the global headers of really large codebases. Storage layout is guaranteed and is C-compatible for result<T, E>1, thus making Outcome based code long term ABI-stable.

Fully deterministic all-noexcept C++ Coroutine support in Outcome is particularly strong, and we supply Outcome-optimising eager<T, Executor = void>/atomic_eager<T, Executor = void> , lazy<T, Executor = void>/atomic_lazy<T, Executor = void> and generator<T, Executor = void> awaitables which work for any user type.

Sample usage (C++)

The main workhorse in the Outcome library is result<T>: it represents either a successfully computed value of type T, or a std::error_code/boost::system::error_code2 representing the reason for failure. You use it in the function’s return type:

outcome::result<string> data_from_file(string_view path) noexcept;
View this code on Github

It is possible to inspect the state manually:

if (outcome::result<string> rslt = data_from_file("config.cfg"))
  use_string(rslt.value());                   // returns string
else
  throw LibError{rslt.error(), "config.cfg"}; // returns error_code
View this code on Github

Or, if this function is called in another function that also returns result<T>, you can use a dedicated control statement:

outcome::result<int> process(const string& content) noexcept;

outcome::result<int> int_from_file(string_view path) noexcept
{
  BOOST_OUTCOME_TRY(auto str, data_from_file(path));
  // if control gets here data_from_file() has succeeded
  return process(str);  // decltype(str) == string
}
View this code on Github

BOOST_OUTCOME_TRY is a control statement. If the returned result<T> object contains an error information, the enclosing function is immediately returned with result<U> containing the same failure information; otherwise an automatic object of type T is available in scope.

Sample usage (C)

Equivalent to the C++ API: BOOST_OUTCOME_C_DECLARE_RESULT_SYSTEM(ident, T) declares the C type, thereafter BOOST_OUTCOME_C_RESULT_SYSTEM(ident) refers to it. You use it in the function’s return type:

BOOST_OUTCOME_C_DECLARE_RESULT_SYSTEM(result_string, const char *)

BOOST_OUTCOME_C_RESULT_SYSTEM(result_string) data_from_file(const char *path);
View this code on Github

It is possible to inspect the state manually:

  BOOST_OUTCOME_C_RESULT_SYSTEM(result_string) rslt = data_from_file("config.cfg");
  if(BOOST_OUTCOME_C_RESULT_HAS_VALUE(rslt))
    use_string(rslt.value);  // returns string
  else
    fprintf(stderr, "%s\n", outcome_status_code_message(&rslt.error));
View this code on Github

Or, if this function is called in another function that also returns BOOST_OUTCOME_C_RESULT_SYSTEM(ident), you can use a dedicated control statement:

BOOST_OUTCOME_C_DECLARE_RESULT_SYSTEM(result_int, int)

BOOST_OUTCOME_C_RESULT_SYSTEM(result_int) process(const char *content);

BOOST_OUTCOME_C_RESULT_SYSTEM(result_int) int_from_file(const char *path)
{
  BOOST_OUTCOME_C_RESULT_SYSTEM_TRY(const char *str, result_int, /* cleanup on fail */, data_from_file(path));
  // if control gets here data_from_file() has succeeded
  return process(str);  // decltype(str) == string
}
View this code on Github

The C Result is guaranteed to be layout identical to its C++ equivalent. Convenience conversion functions are available, but you can reinterpret cast too.

note

This library joined the Boost C++ libraries in the 1.70 release (Spring 2019). It can be grafted into much older Boost releases if desired.


  1. If you choose a C-compatible T and E type. [return]
  2. result<T> defaults to std::error_code for Standalone Outcome, and to boost::system::error_code for Boost.Outcome. You can mandate a choice using std_result<T> or boost_result<T>. [return]

Last revised: July 16, 2024 at 21:33:35 +0100


Prev HomeNext