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 try { 50 if( it == itEnd ) 51 std::rethrow_exception(std::current_exception()); 52 else 53 return (*it)->translate( it+1, itEnd ); 54 } 55 catch( T& ex ) { 56 return m_translateFunction( ex ); 57 } 58 } 59 60 protected: 61 std::string(*m_translateFunction)( T& ); 62 }; 63 64 public: 65 template<typename T> ExceptionTranslatorRegistrar(std::string (* translateFunction)(T &))66 ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { 67 getMutableRegistryHub().registerTranslator 68 ( new ExceptionTranslator<T>( translateFunction ) ); 69 } 70 }; 71 } 72 73 /////////////////////////////////////////////////////////////////////////////// 74 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \ 75 static std::string translatorName( signature ); \ 76 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 77 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 78 namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \ 79 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 80 static std::string translatorName( signature ) 81 82 #define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature ) 83 84 #endif // TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED 85