C++ boost::leaf examples
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

130 lines
3.5 KiB

// leaf_on_error_example.cpp
#include <boost/leaf.hpp>
#include <ctime>
#include <iostream>
#include <string>
#include <utility>
namespace leaf = boost::leaf;
struct error_tag {};
struct open_error {};
struct write_error {};
struct file_context {
std::string path;
};
struct user_context {
std::string name;
int privileges;
};
struct chunk_context {
int chunk;
std::size_t size;
std::time_t timestamp;
};
leaf::result<void> write_chunk(int chunk, std::size_t size)
{
chunk_context cc{chunk, size, std::time(nullptr)};
// Registers cc to be captured only if an error unwinds this scope.
// On success the registration is discarded.
[[maybe_unused]] auto ctx = leaf::on_error(cc);
if (chunk == 3)
// The context registered above rides along with this error
// even though handlers live several frames up.
return leaf::new_error(write_error{});
return {};
}
leaf::result<void> process_file(std::string path, std::string user)
{
error_tag tag;
file_context fc{std::move(path)};
user_context uc{std::move(user), 0600};
[[maybe_unused]] auto tag_ctx = leaf::on_error(tag);
[[maybe_unused]] auto file_ctx = leaf::on_error(fc);
[[maybe_unused]] auto user_ctx = leaf::on_error(uc);
// write_chunk knows nothing about the contexts registered here;
// LEAF attaches them automatically to any error it propagates.
for (int i = 0; i != 5; ++i) {
auto r = write_chunk(i, 4096);
if (!r)
return r;
}
return {};
}
int main()
{
return leaf::try_handle_all(
[]() -> leaf::result<int> {
// Try block and handlers must return the same type.
BOOST_LEAF_CHECK(process_file("data.bin", "alice"));
return 0;
},
// A handler runs only if the error carries every type it
// requests; handlers below with fewer parameters match the
// same errors when richer contexts were never registered.
[](write_error const&,
error_tag const&,
file_context const& f,
user_context const& u,
chunk_context const& c) {
std::cerr << "write failed: "
<< "file=" << f.path
<< ", user=" << u.name
<< ", chunk=" << c.chunk
<< ", size=" << c.size
<< ", time=" << c.timestamp
<< '\n';
return 1;
},
[](open_error const&,
error_tag const&,
file_context const& f,
user_context const& u) {
std::cerr << "open failed: "
<< "file=" << f.path
<< ", user=" << u.name
<< '\n';
return 2;
},
[](error_tag const&,
file_context const& f,
user_context const& u,
chunk_context const& c) {
std::cerr << "unknown error: "
<< "file=" << f.path
<< ", user=" << u.name
<< ", chunk=" << c.chunk
<< '\n';
return 3;
},
[](error_tag const&,
file_context const& f,
user_context const& u) {
std::cerr << "unknown error: "
<< "file=" << f.path
<< ", user=" << u.name
<< '\n';
return 4;
},
[] {
std::cerr << "unknown error before file context\n";
return 5;
}
);
}