1 /*
2  *  Created by Phil on 20/04/2011.
3  *  Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 #ifndef TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
9 #define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
10 
11 #include <string>
12 #include <vector>
13 
14 #include "catch_interfaces_registry_hub.h"
15 
16 namespace Catch {
17 
18     typedef std::string(*exceptionTranslateFunction)();
19 
20     struct IExceptionTranslator;
21     typedef std::vector<const IExceptionTranslator*> ExceptionTranslators;
22 
23     struct IExceptionTranslator {
24         virtual ~IExceptionTranslator();
25         virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;
26     };
27 
28     struct IExceptionTranslatorRegistry {
29         virtual ~IExceptionTranslatorRegistry();
30 
31         virtual std::string translateActiveException() const = 0;
32     };
33 
34     class ExceptionTranslatorRegistrar {
35         template<typename T>
36         class ExceptionTranslator : public IExceptionTranslator {
37         public:
38 
ExceptionTranslator(std::string (* translateFunction)(T &))39             ExceptionTranslator( std::string(*translateFunction)( T& ) )
40             : m_translateFunction( translateFunction )
41             {}
42 
translate(ExceptionTranslators::const_iterator it,ExceptionTranslators::const_iterator itEnd)43             virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const CATCH_OVERRIDE {
44                 try {
45                     if( it == itEnd )
46                         throw;
47                     else
48                         return (*it)->translate( it+1, itEnd );
49                 }
50                 catch( T& ex ) {
51                     return m_translateFunction( ex );
52                 }
53             }
54 
55         protected:
56             std::string(*m_translateFunction)( T& );
57         };
58 
59     public:
60         template<typename T>
ExceptionTranslatorRegistrar(std::string (* translateFunction)(T &))61         ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {
62             getMutableRegistryHub().registerTranslator
63                 ( new ExceptionTranslator<T>( translateFunction ) );
64         }
65     };
66 }
67 
68 ///////////////////////////////////////////////////////////////////////////////
69 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \
70     static std::string translatorName( signature ); \
71     namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); }\
72     static std::string translatorName( signature )
73 
74 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
75 
76 #endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED
77