Skip to content

Instantly share code, notes, and snippets.

@mrdomino mrdomino/noew.c++
Created Oct 30, 2015

Embed
What would you like to do?
#include <cstdio>
#include <exception>
#include <utility>
// hypothetically...
class MyException : public std::exception {
public:
const char *what() const noexcept {
return "nope";
}
};
template <typename F, typename E, typename R>
class NoexceptWrap_ {
public:
using func_type = F;
using error_type = E;
using return_type = R;
R operator()(F&& f, E&& handle, R&& fail_return) {
using std::exception;
using std::forward;
try {
return forward<F>(f)();
} catch (MyException const& e) {
try { forward<E>(handle)(e); } catch (...) {}
} catch (exception const& e) {
try { forward<E>(handle)(e); } catch (...) {}
} catch (...) {
try { forward<E>(handle)(); } catch (...) {}
}
return forward<R>(fail_return);
}
};
template <typename F, typename E>
class NoexceptWrap_<F, E, void> {
public:
using func_type = F;
using error_type = E;
using return_type = void;
void operator()(F&& f, E&& handle) {
using std::exception;
using std::forward;
try {
forward<F>(f)();
} catch (MyException const& e) {
try { forward<E>(handle)(e); } catch (...) {}
} catch (exception const& e) {
try { forward<E>(handle)(e); } catch (...) {}
} catch (...) {
try { forward<E>(handle)(); } catch (...) {}
}
}
};
class PrintError {
public:
void operator()(MyException const& e) {
printf(".%s\n", e.what());
}
void operator()(std::exception const& e) {
printf("!%s\n", e.what());
}
void operator()() {
printf("?\n");
}
};
template <typename F, typename E>
using NoexceptWrap = NoexceptWrap_<F, E, decltype(std::declval<F>()())>;
template <typename F, typename E>
auto noexcept_wrap(F&& f, E&& e, typename NoexceptWrap<F, E>::return_type&& fail_return)
-> typename NoexceptWrap<F, E>::return_type {
using std::forward;
using return_type = typename NoexceptWrap<F, E>::return_type;
static NoexceptWrap<F, E> wrap;
return wrap(forward<F>(f), forward<E>(e), forward<return_type>(fail_return));
}
template <typename F, typename E>
void noexcept_wrap(F&& f, E&& e) {
using std::forward;
static NoexceptWrap<F, E> wrap;
wrap(forward<F>(f), forward<E>(e));
}
int main() {
noexcept_wrap([] { throw MyException(); }, PrintError());
noexcept_wrap([] { throw std::exception(); }, PrintError());
printf("%d\n", noexcept_wrap([] { return 0; }, PrintError(), 1));
printf("%d\n", noexcept_wrap([] { throw "wow"; return 0; }, PrintError(), 1));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.