Question

I have some C-style functions that return 0 to indicate success, and != 0 on error.
I'd like to "wrap" them into void functions that throw instead of returning a value.

I have written this helper:

void checkStatus(int status) {
  if (status != 0)
    // throw an error object
}

Then, to wrap a determinate function int tilt(float degrees), I use boost::bind:

function<void(float)> ntilt = bind(checkStatus, bind(tilt, _1));
ntilt(30); // this will call checkStatus(tilt(30))

And it works great. But I'd like to have a dedicate wrapper function, so I can just do:

function<void(float)> ntilt = wrap(tilt);
ntilt(30); // this will call checkStatus(tilt(30))

It should work for any function/signature that returns an int.
What would be the best way to do it using Boost?

Was it helpful?

Solution

You could create several overloads to handle the different amount of parameters that your wrapped functions might take:

// handles 1 parameter functions
template<typename Ret, typename T0>
function<void(T0)> wrap(Ret (*fun)(T0)) {
    return bind(checkStatus, bind(fun, _1));
}

// handles 2 parameters functions    
template<typename Ret, typename T0, typename T1>
function<void(T0, T1)> wrap(Ret (*fun)(T0, T1)) {
    return bind(checkStatus, bind(fun, _1, _2));
}

// ... add more

Here's a C++11 implementation. You could avoid some stuff if you didn't want an std::function, but well, it works:

#include <functional>
#include <stdexcept>

template<typename Ret, typename... Args>
struct wrapper {
    typedef Ret (*function_type)(Args...);

    void operator()(Args&&... args) {
        if(fun(std::forward<Args>(args)...) != 0)
            throw std::runtime_error("Error");
    }

    function_type fun;
};

template<typename Ret, typename... Ts>
std::function<void(Ts...)> wrap(Ret (*fun)(Ts...)) {
    return std::function<void(Ts...)>(wrapper<Ret, Ts...>{fun});
}

Here is a live demo.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top