mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 21:36:11 +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:
parent
19279250e8
commit
003960dc90
@ -11,8 +11,6 @@
|
|||||||
// Try to detect if the current compiler supports SFINAE
|
// Try to detect if the current compiler supports SFINAE
|
||||||
#include "catch_compiler_capabilities.h"
|
#include "catch_compiler_capabilities.h"
|
||||||
|
|
||||||
#ifdef CATCH_SFINAE
|
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
|
||||||
struct TrueType {
|
struct TrueType {
|
||||||
@ -26,6 +24,8 @@ namespace Catch {
|
|||||||
char sizer[2];
|
char sizer[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CATCH_SFINAE
|
||||||
|
|
||||||
template<bool> struct NotABooleanExpression;
|
template<bool> struct NotABooleanExpression;
|
||||||
|
|
||||||
template<bool c> struct If : NotABooleanExpression<c> {};
|
template<bool c> struct If : NotABooleanExpression<c> {};
|
||||||
@ -36,9 +36,9 @@ namespace Catch {
|
|||||||
template<> struct SizedIf<sizeof(TrueType)> : TrueType {};
|
template<> struct SizedIf<sizeof(TrueType)> : TrueType {};
|
||||||
template<> struct SizedIf<sizeof(FalseType)> : FalseType {};
|
template<> struct SizedIf<sizeof(FalseType)> : FalseType {};
|
||||||
|
|
||||||
} // end namespace Catch
|
|
||||||
|
|
||||||
#endif // CATCH_SFINAE
|
#endif // CATCH_SFINAE
|
||||||
|
|
||||||
|
} // end namespace Catch
|
||||||
|
|
||||||
#endif // TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED
|
#endif // TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED
|
||||||
|
|
||||||
|
@ -20,11 +20,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Catch {
|
namespace Catch {
|
||||||
|
namespace Detail {
|
||||||
|
|
||||||
#ifdef CATCH_SFINAE
|
#ifdef CATCH_SFINAE
|
||||||
|
|
||||||
namespace Detail {
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class IsStreamInsertableHelper {
|
class IsStreamInsertableHelper {
|
||||||
template<int N> struct TrueIfSizeable : TrueType {};
|
template<int N> struct TrueIfSizeable : TrueType {};
|
||||||
@ -40,53 +39,47 @@ namespace Detail {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
struct IsStreamInsertable : IsStreamInsertableHelper<T>::type {};
|
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
|
#else
|
||||||
|
|
||||||
namespace Detail {
|
struct BorgType {
|
||||||
|
template<typename T> BorgType( T const& );
|
||||||
|
};
|
||||||
|
|
||||||
struct NonStreamable {
|
TrueType& testStreamable( std::ostream& );
|
||||||
template<typename T> NonStreamable( const T& ){}
|
FalseType testStreamable( FalseType );
|
||||||
|
|
||||||
|
FalseType operator<<( std::ostream const&, BorgType const& );
|
||||||
|
|
||||||
|
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
|
} // 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>
|
template<typename T>
|
||||||
struct StringMaker {
|
struct StringMaker :
|
||||||
static std::string convert( T const& value ) {
|
Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {};
|
||||||
std::ostringstream oss;
|
|
||||||
oss << value;
|
|
||||||
return oss.str();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -342,11 +342,9 @@ struct Awkward
|
|||||||
operator int() const { return 7; }
|
operator int() const { return 7; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// This now works with GCC/ Clang usinh SFINAE
|
TEST_CASE( "non streamable - with conv. op", "" )
|
||||||
// Uncomment when it works on all compilers that are tested
|
{
|
||||||
//TEST_CASE( "non streamable", "" )
|
Awkward awkward;
|
||||||
//{
|
std::string s = Catch::toString( awkward );
|
||||||
// Awkward awkward;
|
REQUIRE( s == "7" );
|
||||||
// std::string s = Catch::toString( awkward );
|
}
|
||||||
// REQUIRE( s == "7" ); // This is ambiguous without SFINAE
|
|
||||||
//}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user