C++11/14/17 std::expected with functional-style extensions
Clone or download
Permalink
Failed to load latest commit information.
docs Docs Nov 27, 2017
tests Fix #34 Sep 3, 2018
tl Merge branch 'master' of github.com:TartanLlama/expected Sep 6, 2018
.appveyor.yml CI Oct 26, 2017
.clang-format Add clang format file Oct 27, 2017
.gitignore gitignore Oct 27, 2017
.travis.yml Add test for issue 23 Aug 22, 2018
CMakeLists.txt Play nice with CMake add_subdirectory (#25) Jun 8, 2018
COPYING License Oct 28, 2017
README.md Update readme Jun 6, 2018
standardese.config Update docs Nov 27, 2017

README.md

expected

Single header implementation of std::expected with functional-style extensions.

Clang + GCC: Linux Build Status MSVC: Windows Build Status

std::expected is proposed as the preferred way to represent object which will either have an expected value, or an unexpected value giving information about why something failed. Unfortunately, chaining together many computations which may fail can be verbose, as error-checking code will be mixed in with the actual programming logic. This implementation provides a number of utilities to make coding with expected cleaner.

For example, instead of writing this code:

std::expected<image,fail_reason> get_cute_cat (const image& img) {
    auto cropped = crop_to_cat(img);
    if (!cropped) {
      return cropped;
    }

    auto with_tie = add_bow_tie(*cropped);
    if (!with_tie) {
      return with_tie;
    }

    auto with_sparkles = make_eyes_sparkle(*with_tie);
    if (!with_sparkles) {
       return with_sparkles;
    }

    return add_rainbow(make_smaller(*with_sparkles));
}

You can do this:

tl::expected<image,fail_reason> get_cute_cat (const image& img) {
    return crop_to_cat(img)
           .and_then(add_bow_tie)
           .and_then(make_eyes_sparkle)
           .map(make_smaller)
           .map(add_rainbow);
}

Full documentation available at expected.tartanllama.xyz

The interface is the same as std::expected as proposed in p0323r3, but the following member functions are also defined. Explicit types are for clarity.

  • map: carries out some operation on the stored object if there is one.
    • tl::expected<std::size_t,std::error_code> s = exp_string.map(&std::string::size);
  • map_error: carries out some operation on the unexpected object if there is one.
    • my_error_code translate_error (std::error_code);
    • tl::expected<int,my_error_code> s = exp_int.map_error(translate_error);
  • and_then: like map, but for operations which return a tl::expected.
    • tl::expected<ast, fail_reason> parse (const std::string& s);
    • tl::expected<ast, fail_reason> exp_ast = exp_string.and_then(parse);
  • or_else: calls some function if there is no value stored.
    • exp.or_else([] { throw std::runtime_error{"oh no"}; });

Compiler support

Tested on:

  • Linux
    • clang 6.0.1
    • clang 5.0.2
    • clang 4.0.1
    • clang 3.9
    • clang 3.8
    • clang 3.7
    • clang 3.6
    • clang 3.5
    • g++ 8.0.1
    • g++ 7.3
    • g++ 6.4
    • g++ 5.5
    • g++ 4.9
    • g++ 4.8
  • Windows
    • MSVC 2015
    • MSVC 2017

Dependencies

Requires Standardese for generating documentation.

Requires Catch for testing. This is bundled in the test directory.

Acknowledgements

Thanks to Kévin Alexandre Boissonneault and Björn Fahller for various bug fixes.


CC0

To the extent possible under law, Simon Brand has waived all copyright and related or neighboring rights to the expected library. This work is published from: United Kingdom.