
// Copyright 2006-2009 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"

#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/cat.hpp>

#   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

#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 BOOST_PREVENT_MACRO_SUBSTITUTION() 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_;

        test_runner(test_runner const&);
        test_runner& operator=(test_runner const&);
    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;
            }
        }
    };

    // 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
