LLVM's Rich Recoverable Error Handling as a C++17 Header-Only Library.
Most of the code in this repository is not my own work. I only extracted it from the LLVM libraries in order to make it usable for 3rd-parties.
#include <iostream>
#include <sstream>
#include "llvm-expected.h"
llvm::Expected<int> to_int(const std::string &S, bool MatchWord = false) {
std::istringstream ss(S);
ss.imbue(std::locale::classic());
int result;
ss >> result;
if (LLVM_UNLIKELY(ss.fail()))
return llvm::createStringError("Failed to parse int: " + S);
if (LLVM_UNLIKELY(MatchWord && !ss.eof()))
return llvm::createStringError("Failed to parse full string as int: " + S);
return result;
}
int main(int argc, char *argv[]) {
llvm::Error Errs = llvm::Error::success();
auto QueueError = [&Errs](llvm::Error Err) {
Errs = llvm::joinErrors(std::move(Errs), std::move(Err));
};
std::cout << "Ints: ";
static constexpr bool MatchWord = true;
for (int i = 1; i < argc; i++) {
if (auto parsed_int = to_int(argv[i], MatchWord)) {
std::cout << *parsed_int << " ";
} else {
QueueError(parsed_int.takeError());
}
}
std::cout << "\n";
llvm::logAllUnhandledErrors(std::move(Errs), std::cout, "\nErrors:\n");
std::cout << "\n";
return 0;
}
$ git clone --depth 1 https://github.com/weliveindetail/llvm-expected.git
$ clang -std=c++17 -lc++ llvm-expected/example.cpp -o example
$ ./example 4
Ints: 4
$ ./example _ 42 -0 1a +4 b5
Ints: 42 0 4
Errors:
Failed to parse int from '_'
Failed to parse full string as int in '1a'
Failed to parse int from 'b5'
The current master
is based on the upcoming LLVM 7.0 Release and requires a compiler with support for C++17 Inline Variables.
Please find the old not-header-only version on the release_50 branch.
In order to use the library you can just copy the
llvm-expected.h to your project.
I will cherry-pick fixes for this release from LLVM if there are any. You may want checkout the release_70
branch
in a git submodule to easily pull. Consider a shallow clone as the repo contains the entire history of LLVM:
$ git submodule add --depth=1 --branch=release_70 https://github.com/weliveindetail/llvm-expected.git
The author Lang Hames on motivation and basic usage during the 2016 LLVM Developers’ Meeting:
https://www.youtube.com/watch?v=Wq8fNK98WGw
Great up-to-date documentation in the LLVM Programmer's Manual:
https://llvm.org/docs/ProgrammersManual.html#recoverable-errors
Some time ago I wrote a blog post with a motivation:
https://weliveindetail.github.io/blog/post/2017/10/22/llvm-expected.html
Make a recursvie clone to include gtest and run the unit tests:
$ git clone --recursive --depth 1 https://github.com/weliveindetail/llvm-expected.git
$ cd llvm-expected
$ git submodule update --init --recursive
$ mkdir ../build-test
$ cd ../build-test
$ cmake -G Ninja ../llvm-expected
$ cmake --build .
$ ./llvm-expected-test
This repository is a fork of LLVM, which makes all terms of the LLVM license apply to the code published here. Please read LICENSE.TXT for more information.