mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-11-04 05:59:32 +01:00 
			
		
		
		
	Returned to older version of IsStreamable
- this time based on code from Martin Moene https://gist.github.com/martinmoene/5418947#file-insertionopdetector-cpp
This commit is contained in:
		@@ -11,8 +11,6 @@
 | 
			
		||||
// Try to detect if the current compiler supports SFINAE
 | 
			
		||||
#include "catch_compiler_capabilities.h"
 | 
			
		||||
 | 
			
		||||
#ifdef CATCH_SFINAE
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
    
 | 
			
		||||
    struct TrueType {
 | 
			
		||||
@@ -26,6 +24,8 @@ namespace Catch {
 | 
			
		||||
        char sizer[2];
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
#ifdef CATCH_SFINAE
 | 
			
		||||
 | 
			
		||||
    template<bool> struct NotABooleanExpression;
 | 
			
		||||
 | 
			
		||||
    template<bool c> struct If : NotABooleanExpression<c> {};
 | 
			
		||||
@@ -35,10 +35,10 @@ namespace Catch {
 | 
			
		||||
    template<int size> struct SizedIf;
 | 
			
		||||
    template<> struct SizedIf<sizeof(TrueType)> : TrueType {};
 | 
			
		||||
    template<> struct SizedIf<sizeof(FalseType)> : FalseType {};
 | 
			
		||||
 | 
			
		||||
#endif // CATCH_SFINAE
 | 
			
		||||
    
 | 
			
		||||
} // end namespace Catch
 | 
			
		||||
 | 
			
		||||
#endif // CATCH_SFINAE
 | 
			
		||||
 | 
			
		||||
#endif // TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,11 +20,10 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace Catch {
 | 
			
		||||
namespace Detail {
 | 
			
		||||
 | 
			
		||||
#ifdef CATCH_SFINAE
 | 
			
		||||
 | 
			
		||||
namespace Detail {
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    class IsStreamInsertableHelper {
 | 
			
		||||
        template<int N> struct TrueIfSizeable : TrueType {};
 | 
			
		||||
@@ -40,53 +39,47 @@ namespace Detail {
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    struct IsStreamInsertable : IsStreamInsertableHelper<T>::type {};
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    void toStream( std::ostream& os, T const& value, typename IsStreamInsertable<T>::Enable* = 0 ) {
 | 
			
		||||
        os << value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    void toStream( std::ostream& os, T const&, typename IsStreamInsertable<T>::Disable* = 0 ) {
 | 
			
		||||
        os << "{?}";
 | 
			
		||||
    }
 | 
			
		||||
   
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct StringMaker {
 | 
			
		||||
    static std::string convert( T const& value ) {
 | 
			
		||||
        std::ostringstream oss;
 | 
			
		||||
        Detail::toStream( oss, value );
 | 
			
		||||
        return oss.str();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
namespace Detail {
 | 
			
		||||
    struct BorgType {
 | 
			
		||||
        template<typename T> BorgType( T const& );
 | 
			
		||||
    };
 | 
			
		||||
  
 | 
			
		||||
    TrueType& testStreamable( std::ostream& );
 | 
			
		||||
    FalseType testStreamable( FalseType );
 | 
			
		||||
    
 | 
			
		||||
    FalseType operator<<( std::ostream const&, BorgType const& );
 | 
			
		||||
 | 
			
		||||
    struct NonStreamable {
 | 
			
		||||
        template<typename T> NonStreamable( const T& ){}
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    struct IsStreamInsertable {
 | 
			
		||||
        static std::ostream &s;
 | 
			
		||||
        static T const &t;
 | 
			
		||||
        enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) };
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    template<bool C>
 | 
			
		||||
    struct StringMakerBase {
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        static std::string convert( T const& ) { return "{?}"; }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<>
 | 
			
		||||
    struct StringMakerBase<true> {
 | 
			
		||||
        template<typename T>
 | 
			
		||||
        static std::string convert( T const& _value ) {
 | 
			
		||||
            std::ostringstream oss;
 | 
			
		||||
            oss << _value;
 | 
			
		||||
            return oss.str();
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
} // end namespace Detail
 | 
			
		||||
 | 
			
		||||
// If the type does not have its own << overload for ostream then
 | 
			
		||||
// this one will be used instead
 | 
			
		||||
inline std::ostream& operator << ( std::ostream& ss, Detail::NonStreamable ){
 | 
			
		||||
    return ss << "{?}";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct StringMaker {
 | 
			
		||||
    static std::string convert( T const& value ) {
 | 
			
		||||
        std::ostringstream oss;
 | 
			
		||||
        oss << value;
 | 
			
		||||
        return oss.str();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
struct StringMaker :
 | 
			
		||||
    Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
 
 | 
			
		||||
@@ -342,11 +342,9 @@ struct Awkward
 | 
			
		||||
    operator int() const { return 7; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// This now works with GCC/ Clang usinh SFINAE
 | 
			
		||||
// Uncomment when it works on all compilers that are tested
 | 
			
		||||
//TEST_CASE( "non streamable", "" )
 | 
			
		||||
//{
 | 
			
		||||
//    Awkward awkward;
 | 
			
		||||
//    std::string s = Catch::toString( awkward );
 | 
			
		||||
//    REQUIRE( s == "7" ); // This is ambiguous without SFINAE
 | 
			
		||||
//}
 | 
			
		||||
TEST_CASE( "non streamable - with conv. op", "" )
 | 
			
		||||
{
 | 
			
		||||
    Awkward awkward;
 | 
			
		||||
    std::string s = Catch::toString( awkward );
 | 
			
		||||
    REQUIRE( s == "7" );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user