Promise

API reference

rili::Context and rili::TaskGuard usage example

#include <memory>
#include <rili/Context.hpp>
#include <rili/TaskGuard.hpp>

namespace working_but_ugly_solution {
struct Something {};
void async_makeSomething(std::function<void(Something const&)> const& callback) noexcept;

void doSomething(std::function<void(Something const&)> jobToBeDone) {
    rili::Context& context = rili::Context::get();
    context.reserve();
    /* here we inform Context about background operation which will be scheduled
    (this is correct as long as async_makeSomething will not throw) */

    async_makeSomething( /* here we start background action */
      [&context, jobToBeDone](Something const& something) {
        /* But we can't be sure that provided lambda will be executed in current
        thread scope(probably not...), so we can use "schedule" for this purpose */

        context.schedule([something, jobToBeDone]() { jobToBeDone(something); });
        // schedule is not throwing
        context.release();
        // so we can be preatty sure that release will have place
    });
}
}  // namespace working_but_ugly_solution

namespace much_better_solution {
struct SomethingElse {};
void async_makeSomethingElse(std::function<void(SomethingElse const&)> const& callback);  // no noexcpet here

void doSomethingElse(std::function<void(SomethingElse const&)> jobToBeDone) {
    std::shared_ptr<rili::TaskGuard> guard(std::make_shared<rili::TaskGuard>(
        rili::Context::get()));  // here Context will be informed about incoming background operation (TaskGuard Ctor)
    async_makeSomethingElse(
        /*here we start async operation*/ [guard, jobToBeDone](SomethingElse const& somethingElse) {
            guard->context().schedule([somethingElse, jobToBeDone]() { jobToBeDone(somethingElse); });
            /* Here (out of scope of current lambda function) Context will be informed about release of task
             * (TaskGuard DCtor) in case when exception will not be thrown by async_makeSomethingElse*/
        });

    // Here(out of doSomethingElse scope) Context will be informed about release of task (TaskGuard DCtor) in case of
    // exception thrown by async_makeSomethingElse
}
}  // namespace much_better_solution

rili::ComplexException usage example

#include <iostream>
#include <rili/ComplexException.hpp>

int operation1(int const& data);
int operation2(int const& data);

int complexOperation(int const& data) {
    rili::ComplexException exception("complexOperation(int const&)", "Operation cannot be completed!");
    int result = data;
    try {
        result += operation1(result);
    } catch (...) {
        exception.addException(std::current_exception());
        try {
            result += operation2(result);
        } catch (...) {
            exception.addException(std::current_exception());
        }
    }

    if (exception.size() > 1) /* If both operations failed */ {
        throw exception;
    }
    return result;
}

void use() {
    try {
        std::cout << complexOperation(5) << std::endl;
    } catch (rili::ComplexException const& err) {
        std::cerr << err.what() << std::endl;
        for (auto const& e : err) {
            try {
                std::rethrow_exception(e);
            } catch (std::exception const& exception) {
                std::cout << exception.what() << std::endl;
            } catch (...) {
                std::cout << "unknown exception" << std::endl;
            }
        }
    } catch (std::exception const& err) {
        std::cerr << err.what() << std::endl;
    }
}