Custom Errors in Cilk

Here’s the translation of the custom errors example from Go to Cilk:

#include <cilk/cilk.h>
#include <iostream>
#include <string>
#include <stdexcept>
#include <memory>

// A custom error type usually has the suffix "Exception".
class ArgException : public std::runtime_error {
public:
    int arg;
    std::string message;

    ArgException(int a, const std::string& msg) 
        : std::runtime_error(std::to_string(a) + " - " + msg), arg(a), message(msg) {}
};

std::pair<int, std::unique_ptr<std::exception>> f(int arg) {
    if (arg == 42) {
        // Return our custom error.
        return {-1, std::make_unique<ArgException>(arg, "can't work with it")};
    }
    return {arg + 3, nullptr};
}

int main() {
    auto [result, err] = f(42);
    
    // In Cilk, we use dynamic_cast for type checking and conversion
    if (auto* ae = dynamic_cast<ArgException*>(err.get())) {
        std::cout << ae->arg << std::endl;
        std::cout << ae->message << std::endl;
    } else {
        std::cout << "err doesn't match ArgException" << std::endl;
    }

    return 0;
}

This example demonstrates how to implement custom errors in Cilk. Here’s a breakdown of the changes and explanations:

  1. We define a custom exception class ArgException that inherits from std::runtime_error. This is similar to implementing the error interface in the original example.

  2. The Error() method is replaced by the constructor of ArgException, which formats the error message.

  3. The f function now returns a std::pair with the result and a std::unique_ptr to an exception. This is similar to returning a value and an error in the original example.

  4. In the main function, we use structured binding to get the result and error from f.

  5. Instead of errors.As, we use dynamic_cast to check if the error is of type ArgException. This is the C++ way of checking for specific exception types.

  6. The error handling is done using a simple if-else statement, similar to the original example.

To compile and run this Cilk program:

$ cilk++ custom_errors.cilk -o custom_errors
$ ./custom_errors
42
can't work with it

This example showcases how to create and use custom errors in Cilk, providing a similar functionality to the original Go example.