// A custom definition allows to output exception messages in case BOOST_XXX_NO_THROW does throw.
// Taken from https://stackoverflow.com/a/16701468/4859183 and expanded for Tango

#define BOOST_CHECK_THROW_IMPL_OVERRIDE(S, E, TL, Ppassed, Mpassed, Pcaught, Mcaught)                   \
    do                                                                                                  \
    {                                                                                                   \
        try                                                                                             \
        {                                                                                               \
            BOOST_TEST_PASSPOINT();                                                                     \
            S;                                                                                          \
            BOOST_TEST_TOOL_DIRECT_IMPL(Ppassed, TL, Mpassed);                                          \
        }                                                                                               \
        catch(const Tango::DevFailed &e)                                                                \
        {                                                                                               \
            std::stringstream ss;                                                                       \
            ss << std::endl                                                                             \
               << "-----------------------------------------------" << std::endl                        \
               << "test case: " << boost::unit_test::framework::current_test_case().p_name << std::endl \
               << std::endl                                                                             \
               << "exception message: " << std::endl                                                    \
               << e.errors[0].reason << std::endl                                                       \
               << e.errors[0].desc << std::endl                                                         \
               << e.errors[0].origin << std::endl;                                                      \
            BOOST_TEST_MESSAGE(ss.str());                                                               \
            BOOST_TEST_TOOL_DIRECT_IMPL(Pcaught, TL, Mcaught);                                          \
        }                                                                                               \
        catch(const std::exception &e)                                                                  \
        {                                                                                               \
            std::stringstream ss;                                                                       \
            ss << std::endl                                                                             \
               << "-----------------------------------------------" << std::endl                        \
               << "test case: " << boost::unit_test::framework::current_test_case().p_name << std::endl \
               << std::endl                                                                             \
               << "exception message: " << e.what() << std::endl;                                       \
            BOOST_TEST_MESSAGE(ss.str());                                                               \
            BOOST_TEST_TOOL_DIRECT_IMPL(Pcaught, TL, Mcaught);                                          \
        }                                                                                               \
        catch(...)                                                                                      \
        {                                                                                               \
            std::stringstream ss;                                                                       \
            ss << std::endl                                                                             \
               << "-----------------------------------------------" << std::endl                        \
               << "test case: " << boost::unit_test::framework::current_test_case().p_name << std::endl \
               << std::endl                                                                             \
               << "exception message : <unknown exception>" << std::endl;                               \
            BOOST_TEST_MESSAGE(ss.str());                                                               \
            BOOST_TEST_TOOL_DIRECT_IMPL(Pcaught, TL, Mcaught);                                          \
        }                                                                                               \
        /**/                                                                                            \
    } while(0) /**/

#undef BOOST_WARN_NO_THROW
#undef BOOST_CHECK_NO_THROW
#undef BOOST_REQUIRE_NO_THROW

#define BOOST_WARN_NO_THROW(S)                                                     \
    BOOST_CHECK_THROW_IMPL_OVERRIDE(S,                                             \
                                    ...,                                           \
                                    WARN,                                          \
                                    true,                                          \
                                    "no exceptions thrown by " BOOST_STRINGIZE(S), \
                                    false,                                         \
                                    "exception thrown by " BOOST_STRINGIZE(S))     \
/**/
#define BOOST_CHECK_NO_THROW(S)                                                    \
    BOOST_CHECK_THROW_IMPL_OVERRIDE(S,                                             \
                                    ...,                                           \
                                    CHECK,                                         \
                                    true,                                          \
                                    "no exceptions thrown by " BOOST_STRINGIZE(S), \
                                    false,                                         \
                                    "exception thrown by " BOOST_STRINGIZE(S))     \
/**/
#define BOOST_REQUIRE_NO_THROW(S)                                                  \
    BOOST_CHECK_THROW_IMPL_OVERRIDE(S,                                             \
                                    ...,                                           \
                                    REQUIRE,                                       \
                                    true,                                          \
                                    "no exceptions thrown by " BOOST_STRINGIZE(S), \
                                    false,                                         \
                                    "exception thrown by " BOOST_STRINGIZE(S))

BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<std::string>::iterator)
