|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2003-02-14 17:31:13
"Rozental, Gennadiy" <gennadiy.rozental_at_[hidden]> writes:
>> > I could do something along following lines:
>> >
>> > #include <iostream>
>> > using namespace std;
>> >
>> > void
>> > unknown_exception_handler()
>> > {
>> > try {
>> > throw;
>> > }
>> > catch( int i ) {
>> > cout << "int caught\n";
>> > }
>> > }
>> >
>> >
>> > int main()
>> > {
>> > try {
>> > throw 1;
>> > }
>> > catch( ... ) {
>> > try {
>> > unknown_exception_handler();
>> > } catch( ... ) {
>> > cout << "unknown exception\n";
>> > }
>> > }
>> > }
>> >
>> > and provide a way to configure unknown_exception_handler.
>> > Dave, do you have something different in mind?
>>
>> Yes; check out
>> http://www.boost.org/libs/python/doc/v2/exception_translator.html
>>
>> This allows multiple independently registered exception handlers.
>> Whether or not that's overkill for your purposes is another matter.
>
> If I understand the code properly, you proposing something along the
> following lines:
>
> struct exception_handler {
> exception_handler( exception_handler* next = 0 ) : m_next( next ) {}
> virtual ~exception_handler() {}
>
> virtual void run( test_case, test_case_method ) = 0;
^^^^^^^^^^^^^^^^^^^^^^^^^^^
If we are going to generalize this there should be a single
boost::function0<void> argument, and if you're going to go down this
path we should /definitely/ generalize it. Replicating this design
pattern in two separate libraries would be a big mistake.
>
> boost::scoped_ptr<exception_handler> m_next;
> };
>
> template<typename Exception, typename Translator>
> struct concreate_exception_handler :
struct concrete_exception_handler : exception_handler
> {
> concreate_exception_handler( Translator tr, exception_handler next = 0 )
> : exception_handler( next ), m_translator( tr ) {}
>
> virtual void run( test_case, test_case_method )
> {
> try {
> if( m_next )
> m_next->run( test_case, test_case_method );
> else
> test_case->*test_case_method();
> }
> catch(Exception const& e) {
> m_translator( e );
> }
> }
>
> Translator m_translator;
> };
Yes, something along these lines, though I don't like the naming; I
think the code from Boost.Python could almost be used as-is.
> Now unit test monitor could have member
> boost::scoped_ptr<exception_handler> m_eh and following logic
>
> a) in function
> if( m_eh )
> m_eh->handle( test_case, method );
> else
> test_case->*method()
This should be generalized into a static function of exception_handler
which takes a single function0<void> argument.
> b) add somehow register method
>
> template<typename Exception, typename Translator>
> void register_exception_handler( Translator tr )
> {
> m_eh = new concreate_exception_handler<Exception,Translator>( m_eh );
> }
>
> It seems a little bit too complex in comparison with my solution, though
> implementable.
It's already implemented in Boost.Python.
>> note however that the try { throw; } idiom breaks on many popular
>> compilers that are still in use, which is why my code doesn't use it.
>
> What standard says about it?
> I just checked. MSVC6, bcc 5.5.1, gcc 2.95, gcc 3.2, SunPro 4.2 works as
> expected. What compilers do I really need to bother about?
MSVC6 does *not* work as expected (double-destruction of exception
objects), nor does gcc 2.95 (semi-random EH bugs and interactions with
optimization crop up). This is not an idiom that's been
well-excercised in compiler vendors' test suites, it seems.
-- Dave Abrahams Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk