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 "catch_interfaces_registry_hub.h" 12 13 #if defined(CATCH_CONFIG_DISABLE) 14 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \ 15 static std::string translatorName( signature ) 16 #endif 17 18 #include <exception> 19 #include <string> 20 #include <vector> 21 22 namespace Catch { 23 using exceptionTranslateFunction = std::string(*)(); 24 25 struct IExceptionTranslator; 26 using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>; 27 28 struct IExceptionTranslator { 29 virtual ~IExceptionTranslator(); 30 virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0; 31 }; 32 33 struct IExceptionTranslatorRegistry { 34 virtual ~IExceptionTranslatorRegistry(); 35 36 virtual std::string translateActiveException() const = 0; 37 }; 38 39 class ExceptionTranslatorRegistrar { 40 template<typename T> 41 class ExceptionTranslator : public IExceptionTranslator { 42 public: 43 ExceptionTranslator(std::string (* translateFunction)(T &))44 ExceptionTranslator( std::string(*translateFunction)( T& ) ) 45 : m_translateFunction( translateFunction ) 46 {} 47 translate(ExceptionTranslators::const_iterator it,ExceptionTranslators::const_iterator itEnd)48 std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override { 49 CATCH_TRY { 50 if( it == itEnd ) 51 std::rethrow_exception(std::current_exception()); 52 else 53 return (*it)->translate( it+1, itEnd ); 54 } 55 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) 56 catch( T& ex ) { 57 return m_translateFunction( ex ); 58 } 59 #endif 60 } 61 62 protected: 63 std::string(*m_translateFunction)( T& ); 64 }; 65 66 public: 67 template<typename T> ExceptionTranslatorRegistrar(std::string (* translateFunction)(T &))68 ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { 69 getMutableRegistryHub().registerTranslator 70 ( new ExceptionTranslator<T>( translateFunction ) ); 71 } 72 }; 73 } 74 75 /////////////////////////////////////////////////////////////////////////////// 76 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ 77 static std::string translatorName( signature ); \ 78 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 79 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 80 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \ 81 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 82 static std::string translatorName( signature ) 83 84 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) 85 86 #endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED 87