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