/* * Created by Phil on 29/10/2010. * Copyright 2010 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_CATCH_COMMON_H_INCLUDED #define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED #define INTERNAL_CATCH_UNIQUE_NAME_COUNTER2( name, counter ) name##counter #define INTERNAL_CATCH_UNIQUE_NAME_COUNTER( name, counter ) INTERNAL_CATCH_UNIQUE_NAME_COUNTER2( name, counter ) #define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_COUNTER( name, __LINE__ ) // try to define truly unique name independent of line it has been introduced #if defined(_MSC_VER) && (_MSC_VER >= 1300) // __COUNTER__ introduced in VS 7 (VS.NET 2002) #define INTERNAL_CATCH_TRUE_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_COUNTER( name, __COUNTER__ ) #elif defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3) // __COUNTER__ introduced in gcc 4.3 // http://gcc.gnu.org/gcc-4.3/changes.html #define INTERNAL_CATCH_TRUE_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_COUNTER( name, __COUNTER__ ) #elif defined(__clang__) && (__clang_major__ >= 3) // really haven't found when __COUNTER__ was introduced in clang, but 3.0 definetely have it #define INTERNAL_CATCH_TRUE_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_COUNTER( name, __COUNTER__ ) #else // since there's no __COUNTER__ use __LINE__ as a more or less reasonable substitute #define INTERNAL_CATCH_TRUE_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_COUNTER( name, __LINE__ ) #endif #define INTERNAL_CATCH_STRINGIFY2( expr ) #expr #define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) #include #include #include #include "catch_compiler_capabilities.h" namespace Catch { class NonCopyable { NonCopyable( NonCopyable const& ); void operator = ( NonCopyable const& ); protected: NonCopyable() {} virtual ~NonCopyable(); }; class SafeBool { public: typedef void (SafeBool::*type)() const; static type makeSafe( bool value ) { return value ? &SafeBool::trueValue : 0; } private: void trueValue() const {} }; template inline void deleteAll( ContainerT& container ) { typename ContainerT::const_iterator it = container.begin(); typename ContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) delete *it; } template inline void deleteAllValues( AssociativeContainerT& container ) { typename AssociativeContainerT::const_iterator it = container.begin(); typename AssociativeContainerT::const_iterator itEnd = container.end(); for(; it != itEnd; ++it ) delete it->second; } template inline void forEach( ContainerT& container, Function function ) { std::for_each( container.begin(), container.end(), function ); } template inline void forEach( ContainerT const& container, Function function ) { std::for_each( container.begin(), container.end(), function ); } inline bool startsWith( std::string const& s, std::string const& prefix ) { return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix; } inline bool endsWith( std::string const& s, std::string const& suffix ) { return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix; } inline bool contains( std::string const& s, std::string const& infix ) { return s.find( infix ) != std::string::npos; } inline void toLowerInPlace( std::string& s ) { std::transform( s.begin(), s.end(), s.begin(), ::tolower ); } inline std::string toLower( std::string const& s ) { std::string lc = s; toLowerInPlace( lc ); return lc; } struct pluralise { pluralise( std::size_t count, std::string const& label ) : m_count( count ), m_label( label ) {} friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { os << pluraliser.m_count << " " << pluraliser.m_label; if( pluraliser.m_count != 1 ) os << "s"; return os; } std::size_t m_count; std::string m_label; }; struct SourceLineInfo { SourceLineInfo() : line( 0 ){} SourceLineInfo( std::string const& _file, std::size_t _line ) : file( _file ), line( _line ) {} SourceLineInfo( SourceLineInfo const& other ) : file( other.file ), line( other.line ) {} bool empty() const { return file.empty(); } bool operator == ( SourceLineInfo const& other ) const { return line == other.line && file == other.file; } std::string file; std::size_t line; }; inline std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { #ifndef __GNUG__ os << info.file << "(" << info.line << ")"; #else os << info.file << ":" << info.line; #endif return os; } // This is just here to avoid compiler warnings with macro constants and boolean literals inline bool isTrue( bool value ){ return value; } inline void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { std::ostringstream oss; oss << locationInfo << ": Internal Catch error: '" << message << "'"; if( isTrue( true )) throw std::logic_error( oss.str() ); } } #define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) #define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); #endif // TWOBLUECUBES_CATCH_COMMON_H_INCLUDED