C/C++ 11 try-catch-finally 扩展(函数式)

提供对于标准C/C++ 11完善的SEH(结构化异常处理)处理扩展
1、try
2、catch
3、catch-when
4、finally

usage:

using ep::Try;

class exceptionA : public std::exception {
public:
    exceptionA(char const* const _Message) :exception(_Message) {}
};

class exceptionB : public exceptionA {
public:
    exceptionB(char const* const _Message) :exceptionA(_Message) {}
};

int main()
{
    Try([] {
        printf("T1: try\n");
    }).Finally([] {
        printf("T1: finally\n");
    }).Invoke();
    Try([] {
        printf("T2: throw exceptionB\n");
        throw exceptionB("123213213213");
    }).Catch<exceptionA>([](exceptionA& e) {
        printf("T2: catch: exceptionA=%s\n", e.what());
    }, [](exceptionA& e) { // when Type AS B
        exceptionB* ec = dynamic_cast<exceptionB*>(&e);
        printf("T2: catch-when: exceptionA as exceptionB=%p\n", ec);
        return NULL != ec;
    }).Catch<std::exception>([](std::exception& e) {
        printf("T2: catch: exception=%s\n", e.what());
    }).Finally([] {
        printf("T2: finally");
    }).Invoke();
    return getchar();
}

impl:

    class Try
    {
    public:
        inline Try(const std::function<void()>& block)
            : ___try(block) {
            if (!block) {
                throw std::runtime_error("The block part of the try is not allowed to be Null References");
            }
        }
        inline ~Try() {
            ___try = NULL;
            ___catch = NULL;
            ___finally = NULL;
        }

    public:
        template<typename TException>
        inline Try&                                             Catch() const {
            return Catch<TException>([](TException& e) {});
        }
        template<typename TException>
        inline Try&                                             Catch(const std::function<void(TException& e)>& block) const {
            return Catch<TException>(block, NULL);
        }
        template<typename TException>
        inline Try&                                             Catch(const std::function<void(TException& e)>& block, const std::function<bool(TException& e)>& when) const {
            if (!block) {
                throw std::runtime_error("The block part of the try-catch is not allowed to be Null References");
            }

            if (this) {
                auto previous = ___catch;
                ___catch = [block, previous, when](std::exception* e) {
                    if (previous) {
                        if (previous(e)) {
                            return true;
                        }
                    }
                    TException* exception = dynamic_cast<TException*>(e);
                    if (!exception) {
                        return false;
                    }
                    if (when) {
                        if (!when(*exception)) {
                            return false;
                        }
                    }
                    if (block) {
                        block(*exception);
                    }
                    return true;
                };
            }
            return const_cast<Try&>(*this);
        }
        inline Try&                                             Finally(const std::function<void()>& block) const {
            if (this) {
                ___finally = block;
            }
            return const_cast<Try&>(*this);
        }
        inline int                                              Invoke() const {
            if (!this) {
                return -1;
            }
            if (!___try) {
                return -2;
            }
            int ec = 0;
            std::exception* exception = NULL; // 未处理异常
            try {
                ___try();
            }
            catch (std::exception& e) {
                ec = 1;
                exception = (std::exception*)&reinterpret_cast<const char&>(e);
                if (___catch) {
                    if (___catch(exception)) {
                        exception = NULL;
                    }
                }
            }
            if (___finally) {
                ___finally();
            }
            if (exception) {
                throw *exception;
            }
            return ec;
        }

    private:
        mutable std::function<void()>                           ___try;
        mutable std::function<bool(std::exception*)>            ___catch;
        mutable std::function<void()>                           ___finally;
    };

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值