From 7ab3b5aefb87d5193b69a3666abf3ee30b4ee102 Mon Sep 17 00:00:00 2001 From: Phil Nash Date: Tue, 30 Jun 2015 08:41:55 +0100 Subject: [PATCH] Added compiler feature suppression macros _NO_ forms to disable detection of features - particularly C++11 features. Also removed SFINAE detection (and use in tostring) --- docs/configuration.md | 14 ++- .../internal/catch_compiler_capabilities.h | 100 ++++++++---------- include/internal/catch_sfinae.hpp | 44 -------- include/internal/catch_tostring.h | 28 +---- 4 files changed, 59 insertions(+), 127 deletions(-) delete mode 100644 include/internal/catch_sfinae.hpp diff --git a/docs/configuration.md b/docs/configuration.md index f12ec68e3d..d1788c3442 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -52,14 +52,18 @@ This can be useful on certain platforms that do not provide ```std::cout``` and # C++ conformance toggles - CATCH_CONFIG_CPP11_NULLPTR - CATCH_CONFIG_CPP11_NOEXCEPT - CATCH_CONFIG_SFINAE // Basic, C++03, support for SFINAE - CATCH_CONFIG_VARIADIC_MACROS // Usually pre-C++11 compiler extensions are sufficient - CATCH_CONFIG_NO_VARIADIC_MACROS // Suppress if Catch is too eager to enable it + CATCH_CONFIG_CPP11_NULLPTR // nullptr is supported? + CATCH_CONFIG_CPP11_NOEXCEPT // noexcept is supported? + CATCH_CONFIG_CPP11_GENERATED_METHODS // delete and default keywords for methods + CATCH_CONFIG_CPP11_IS_ENUM // std::is_enum is supported? + CATCH_CONFIG_CPP11_TUPLE // std::tuple is supported + CATCH_CONFIG_VARIADIC_MACROS // Usually pre-C++11 compiler extensions are sufficient Catch has some basic compiler detection that will attempt to select the appropriate mix of these macros. However being incomplete - and often without access to the respective compilers - this detection tends to be conservative. So overriding control is given to the user. If a compiler supports a feature (and Catch does not already detect it) then one or more of these may be defined to enable it (or suppress it, in some cases). If you do do this please raise an issue, specifying your compiler version (ideally with an idea of how to detect it) and stating that it has such support. +You may also suppress any of these features by using the `_NO_` form, e.g. `CATCH_CONFIG_CPP11_NO_NULLPTR`. + +All C++11 support can be disabled with `CATCH_CONFIG_NO_CPP11` --- diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h index 7ebd0e39bd..20528c2991 100644 --- a/include/internal/catch_compiler_capabilities.h +++ b/include/internal/catch_compiler_capabilities.h @@ -19,20 +19,24 @@ // CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? -// CATCH_CONFIG_SFINAE : is basic (C++03) SFINAE supported? // CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? -// A lot of this code is based on Boost (1.53) +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 #ifdef __clang__ # if __has_feature(cxx_nullptr) -# define CATCH_CONFIG_CPP11_NULLPTR +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif # if __has_feature(cxx_noexcept) -# define CATCH_CONFIG_CPP11_NOEXCEPT +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # endif #endif // __clang__ @@ -41,9 +45,6 @@ // Borland #ifdef __BORLANDC__ -#if (__BORLANDC__ > 0x582 ) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif #endif // __BORLANDC__ @@ -51,9 +52,6 @@ // EDG #ifdef __EDG_VERSION__ -#if (__EDG_VERSION__ > 238 ) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif #endif // __EDG_VERSION__ @@ -61,9 +59,6 @@ // Digital Mars #ifdef __DMC__ -#if (__DMC__ > 0x840 ) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif #endif // __DMC__ @@ -71,21 +66,8 @@ // GCC #ifdef __GNUC__ -#if __GNUC__ < 3 - -#if (__GNUC_MINOR__ >= 96 ) -//#define CATCH_CONFIG_SFINAE -#endif - -#elif __GNUC__ >= 3 - -// #define CATCH_CONFIG_SFINAE // Taking this out completely for now - -#endif // __GNUC__ < 3 - #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) ) - -#define CATCH_CONFIG_CPP11_NULLPTR +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR #endif @@ -95,17 +77,13 @@ // Visual C++ #ifdef _MSC_VER -#if (_MSC_VER >= 1310 ) // (VC++ 7.0+) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif - #if (_MSC_VER >= 1600) -#define CATCH_CONFIG_CPP11_NULLPTR +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR #endif #if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) -#define CATCH_CONFIG_CPP11_NOEXCEPT -#define CATCH_CONFIG_CPP11_GENERATED_METHODS +#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS #endif #endif // _MSC_VER @@ -116,9 +94,7 @@ ( defined __GNUC__ && __GNUC__ >= 3 ) || \ ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) -#ifndef CATCH_CONFIG_NO_VARIADIC_MACROS -#define CATCH_CONFIG_VARIADIC_MACROS -#endif +#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS #endif @@ -130,36 +106,53 @@ # define CATCH_CPP11_OR_GREATER -# ifndef CATCH_CONFIG_CPP11_NULLPTR -# define CATCH_CONFIG_CPP11_NULLPTR -# endif - -# ifndef CATCH_CONFIG_CPP11_NOEXCEPT -# define CATCH_CONFIG_CPP11_NOEXCEPT +# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) +# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR # endif -# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS -# define CATCH_CONFIG_CPP11_GENERATED_METHODS +# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT # endif -# ifndef CATCH_CONFIG_CPP11_IS_ENUM -# define CATCH_CONFIG_CPP11_IS_ENUM +# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS +# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS # endif -# ifndef CATCH_CONFIG_CPP11_TUPLE -# define CATCH_CONFIG_CPP11_TUPLE +# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM +# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM # endif -# ifndef CATCH_CONFIG_SFINAE -//# define CATCH_CONFIG_SFINAE // Don't use, for now +# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE +# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE # endif -# ifndef CATCH_CONFIG_VARIADIC_MACROS -# define CATCH_CONFIG_VARIADIC_MACROS +# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS # endif #endif // __cplusplus >= 201103L +// Now set the actual defines based on the above + anything the user has configured +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NULLPTR +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_NOEXCEPT +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_GENERATED_METHODS +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_IS_ENUM +#endif +#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) +# define CATCH_CONFIG_CPP11_TUPLE +#endif +#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) +#define CATCH_CONFIG_VARIADIC_MACROS +#endif + + // noexcept support: #if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) # define CATCH_NOEXCEPT noexcept @@ -169,5 +162,6 @@ # define CATCH_NOEXCEPT_IS(x) #endif + #endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED diff --git a/include/internal/catch_sfinae.hpp b/include/internal/catch_sfinae.hpp deleted file mode 100644 index b3bc22789f..0000000000 --- a/include/internal/catch_sfinae.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Created by Phil on 15/04/2013. - * Copyright 2013 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_SFINAE_HPP_INCLUDED -#define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED - -// Try to detect if the current compiler supports SFINAE -#include "catch_compiler_capabilities.h" - -namespace Catch { - - struct TrueType { - static const bool value = true; - typedef void Enable; - char sizer[1]; - }; - struct FalseType { - static const bool value = false; - typedef void Disable; - char sizer[2]; - }; - -#ifdef CATCH_CONFIG_SFINAE - - template struct NotABooleanExpression; - - template struct If : NotABooleanExpression {}; - template<> struct If : TrueType {}; - template<> struct If : FalseType {}; - - template struct SizedIf; - template<> struct SizedIf : TrueType {}; - template<> struct SizedIf : FalseType {}; - -#endif // CATCH_CONFIG_SFINAE - -} // end namespace Catch - -#endif // TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED - diff --git a/include/internal/catch_tostring.h b/include/internal/catch_tostring.h index 2043f99f93..120619be2a 100644 --- a/include/internal/catch_tostring.h +++ b/include/internal/catch_tostring.h @@ -9,7 +9,6 @@ #define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED #include "catch_common.h" -#include "catch_sfinae.hpp" #include #include @@ -68,32 +67,13 @@ namespace Detail { extern std::string unprintableString; -// SFINAE is currently disabled by default for all compilers. -// If the non SFINAE version of IsStreamInsertable is ambiguous for you -// and your compiler supports SFINAE, try #defining CATCH_CONFIG_SFINAE -#ifdef CATCH_CONFIG_SFINAE - - template - class IsStreamInsertableHelper { - template struct TrueIfSizeable : TrueType {}; - - template - static TrueIfSizeable dummy(T2*); - static FalseType dummy(...); - - public: - typedef SizedIf type; - }; - - template - struct IsStreamInsertable : IsStreamInsertableHelper::type {}; - -#else - struct BorgType { template BorgType( T const& ); }; + struct TrueType { char sizer[1]; }; + struct FalseType { char sizer[2]; }; + TrueType& testStreamable( std::ostream& ); FalseType testStreamable( FalseType ); @@ -106,8 +86,6 @@ namespace Detail { enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; }; -#endif - #if defined(CATCH_CONFIG_CPP11_IS_ENUM) template::value