exception_test.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 244 行

HPP
244
字号
// Copyright 2006-2008 Daniel James.// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)#if !defined(BOOST_UNORDERED_EXCEPTION_TEST_HEADER)#define BOOST_UNORDERED_EXCEPTION_TEST_HEADER#include "./test.hpp"#if defined(BOOST_UNORDERED_FULL_TEST)#   define BOOST_TEST_MAIN#   include <boost/test/exception_safety.hpp>#   include <boost/test/unit_test.hpp>#endif#include <boost/preprocessor/seq/for_each_product.hpp>#include <boost/preprocessor/seq/elem.hpp>#include <boost/preprocessor/cat.hpp>#if defined(BOOST_UNORDERED_FULL_TEST)#   define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \        UNORDERED_AUTO_TEST(name) \        { \            test_func< type > fixture; \            ::test::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \        }#    define UNORDERED_EPOINT_IMPL BOOST_ITEST_EPOINT#else#   define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \        UNORDERED_AUTO_TEST(name) \        { \            test_func< type > fixture; \            ::test::lightweight::exception_safety(fixture, BOOST_STRINGIZE(test_func<type>)); \        }#    define UNORDERED_EPOINT_IMPL ::test::lightweight::epoint#endif#define UNORDERED_EXCEPTION_TEST_POSTFIX RUN_TESTS()#define RUN_EXCEPTION_TESTS(test_seq, param_seq) \    BOOST_PP_SEQ_FOR_EACH_PRODUCT(RUN_EXCEPTION_TESTS_OP, (test_seq)(param_seq)) \    RUN_TESTS()#define RUN_EXCEPTION_TESTS_OP(r, product) \    UNORDERED_EXCEPTION_TEST_CASE( \        BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, product), \            BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(1, product)) \        ), \        BOOST_PP_SEQ_ELEM(0, product), \        BOOST_PP_SEQ_ELEM(1, product) \    )#define UNORDERED_SCOPE(scope_name) \    for(::test::scope_guard unordered_test_guard( \            BOOST_STRINGIZE(scope_name)); \        !unordered_test_guard.dismissed(); \        unordered_test_guard.dismiss())#define UNORDERED_EPOINT(name) \    if(::test::exceptions_enabled) { \        UNORDERED_EPOINT_IMPL(name); \    }#define ENABLE_EXCEPTIONS \    ::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(true)#define DISABLE_EXCEPTIONS \    ::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(false)namespace test {    static char const* scope = "";    bool exceptions_enabled = false;    class scope_guard {        scope_guard& operator=(scope_guard const&);        scope_guard(scope_guard const&);        char const* old_scope_;        char const* scope_;        bool dismissed_;    public:        scope_guard(char const* name)            : old_scope_(scope),            scope_(name),            dismissed_(false)        {            scope = scope_;        }        ~scope_guard() {            if(dismissed_) scope = old_scope_;        }        void dismiss() {            dismissed_ = true;        }        bool dismissed() const {            return dismissed_;        }    };    class exceptions_enable    {        exceptions_enable& operator=(exceptions_enable const&);        exceptions_enable(exceptions_enable const&);        bool old_value_;    public:        exceptions_enable(bool enable)            : old_value_(exceptions_enabled)        {            exceptions_enabled = enable;        }        ~exceptions_enable()        {            exceptions_enabled = old_value_;        }    };    struct exception_base {        struct data_type {};        struct strong_type {            template <class T> void store(T const&) {}            template <class T> void test(T const&) const {}        };        data_type init() const { return data_type(); }        void check() const {}    };    template <class T, class P1, class P2, class T2>    inline void call_ignore_extra_parameters(void (T::*fn)() const, T2 const& obj,            P1&, P2&)    {        (obj.*fn)();    }    template <class T, class P1, class P2, class T2>    inline void call_ignore_extra_parameters(void (T::*fn)(P1&) const, T2 const& obj,            P1& p1, P2&)    {        (obj.*fn)(p1);    }    template <class T, class P1, class P2, class T2>    inline void call_ignore_extra_parameters(void (T::*fn)(P1&, P2&) const, T2 const& obj,            P1& p1, P2& p2)    {        (obj.*fn)(p1, p2);    }    template <class T>    T const& constant(T const& x) {        return x;    }    template <class Test>    class test_runner    {        Test const& test_;    public:        test_runner(Test const& t) : test_(t) {}        void operator()() const {            DISABLE_EXCEPTIONS;            test::scope = "";            BOOST_DEDUCED_TYPENAME Test::data_type x(test_.init());            BOOST_DEDUCED_TYPENAME Test::strong_type strong;            strong.store(x);            try {                ENABLE_EXCEPTIONS;                call_ignore_extra_parameters<Test, BOOST_DEDUCED_TYPENAME Test::data_type, BOOST_DEDUCED_TYPENAME Test::strong_type>(&Test::run, test_, x, strong);            }            catch(...) {                call_ignore_extra_parameters<Test, BOOST_DEDUCED_TYPENAME Test::data_type const, BOOST_DEDUCED_TYPENAME Test::strong_type const>(&Test::check, test_,                        constant(x), constant(strong));                throw;            }        }    };        #if defined(BOOST_UNORDERED_FULL_TEST)    template <class Test>    void exception_safety(Test const& f, char const* name) {        test_runner<Test> runner(f);        ::boost::itest::exception_safety(runner, name);    }#else    // Quick exception testing based on lightweight test    namespace lightweight {        static int iteration;        static int count;        struct test_exception {            char const* name;            test_exception(char const* n) : name(n) {}        };        struct test_failure {        };        void epoint(char const* name) {            ++count;            if(count == iteration) {                throw test_exception(name);            }        }        template <class Test>        void exception_safety(Test const& f, char const* /*name*/) {            test_runner<Test> runner(f);            iteration = 0;            bool success = false;            do {                ++iteration;                count = 0;                try {                    runner();                    success = true;                }                catch(test_failure) {                    BOOST_ERROR("test_failure caught.");                    break;                }                catch(test_exception) {                    continue;                }                catch(...) {                    BOOST_ERROR("Unexpected exception.");                    break;                }            } while(!success);        }    }#endif}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?