Skip to content

qzminsky/cpp-result

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 

Repository files navigation

cpp-result

version license cpp-version

The Result monad implementation in C++

Installation

  1. Download the library source;
  2. #include the result.hpp (or result.inl) file in your C++ project;
  3. Enjoy!

⚠️ Note that the library requires C++17 support

result.inl

The file result.inl contains two pretty constructors that duplicate corresponding static member functions in the result class. Just compare:

return result<>::ok(0);
if (func() == result<>::error(1)) { ... }

and

return Ok(0);
if (func() == Error(1)) { ... }

The short form looks much prettier, isn't it? Sadly, these functions has very short names in global scope, so, they were brought into a separate optional header.

Usage example

// Divide x by y or return an error if y == 0
auto div (int x, int y) -> result<int, std::runtime_error>
{
  using namespace std::string_literals;
  
// return (y == 0) ? Error(...) : Ok(...);  // Wrong: different types!
  
  if (y != 0) {
    return Ok(x / y);
  }
  return Error("Zero division!"s);
  //
  // The result type is based on std::variant and can't take arrays
}

auto main () -> int
{
  // Check a result state and extract its value if appropriate
  if (auto res = div(1, 2); res.is_ok()) {
    std::cout << res.unwrap() << std::endl;
  }
  
  // Combined state-value checking
  assert(div(10, 3).is_ok(3));
  assert(div(10, 3) == Ok(3));
  
  // "Silent" error handling
  assert(div(1, 0).unwrap_or(-1), -1);
}

Improvements

As you might have noticed, a returned result must be stored in separate object to operate with it further. Fortunately, the result class provides special helpers to simplify some use cases:

div(1, 2).if_ok([](int res){ std::cout << "Division result is " << res; })
         .if_error([]{ std::cerr << "Division error!"; });

These helpers — if_ok and if_error — takes a functional parameter with own optional parameter. If the exact value is not important, this parameter can be omitted.

License

See the LICENSE file for license rights and limitations (MIT).