1 /* 2 * Created by Phil on 18/10/2010. 3 * Copyright 2010 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_TEST_REGISTRY_HPP_INCLUDED 9 #define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED 10 11 #include "catch_common.h" 12 #include "catch_interfaces_testcase.h" 13 #include "catch_compiler_capabilities.h" 14 #include "catch_stringref.h" 15 #include "catch_preprocessor.hpp" 16 #include "catch_meta.hpp" 17 18 namespace Catch { 19 20 template<typename C> 21 class TestInvokerAsMethod : public ITestInvoker { 22 void (C::*m_testAsMethod)(); 23 public: TestInvokerAsMethod(void (C::* testAsMethod)())24 TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {} 25 invoke()26 void invoke() const override { 27 C obj; 28 (obj.*m_testAsMethod)(); 29 } 30 }; 31 32 auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*; 33 34 template<typename C> 35 auto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* { 36 return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod ); 37 } 38 39 struct NameAndTags { 40 NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept; 41 StringRef name; 42 StringRef tags; 43 }; 44 45 struct AutoReg : NonCopyable { 46 AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept; 47 ~AutoReg(); 48 }; 49 50 } // end namespace Catch 51 52 #if defined(CATCH_CONFIG_DISABLE) 53 #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \ 54 static void TestName() 55 #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \ 56 namespace{ \ 57 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \ 58 void test(); \ 59 }; \ 60 } \ 61 void TestName::test() 62 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \ 63 INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature)) 64 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \ 65 namespace{ \ 66 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \ 67 INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\ 68 } \ 69 } \ 70 INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature)) 71 72 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 73 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ 74 INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) 75 #else 76 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \ 77 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) 78 #endif 79 80 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 81 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ 82 INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) 83 #else 84 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \ 85 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) 86 #endif 87 88 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 89 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ 90 INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) 91 #else 92 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \ 93 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) 94 #endif 95 96 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 97 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ 98 INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) 99 #else 100 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \ 101 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) 102 #endif 103 #endif 104 105 /////////////////////////////////////////////////////////////////////////////// 106 #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \ 107 static void TestName(); \ 108 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 109 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 110 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ 111 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 112 static void TestName() 113 #define INTERNAL_CATCH_TESTCASE( ... ) \ 114 INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), __VA_ARGS__ ) 115 116 /////////////////////////////////////////////////////////////////////////////// 117 #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ 118 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 119 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 120 namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \ 121 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION 122 123 /////////////////////////////////////////////////////////////////////////////// 124 #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ 125 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 126 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 127 namespace{ \ 128 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \ 129 void test(); \ 130 }; \ 131 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ 132 } \ 133 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 134 void TestName::test() 135 #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \ 136 INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), ClassName, __VA_ARGS__ ) 137 138 /////////////////////////////////////////////////////////////////////////////// 139 #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \ 140 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 141 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 142 Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ 143 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION 144 145 /////////////////////////////////////////////////////////////////////////////// 146 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\ 147 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 148 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 149 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ 150 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ 151 INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\ 152 namespace {\ 153 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\ 154 INTERNAL_CATCH_TYPE_GEN\ 155 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\ 156 INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\ 157 template<typename...Types> \ 158 struct TestName{\ 159 TestName(){\ 160 int index = 0; \ 161 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\ 162 using expander = int[];\ 163 (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \ 164 }\ 165 };\ 166 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ 167 TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\ 168 return 0;\ 169 }();\ 170 }\ 171 }\ 172 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 173 INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature)) 174 175 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 176 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ 177 INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) 178 #else 179 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ 180 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename TestType, __VA_ARGS__ ) ) 181 #endif 182 183 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 184 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ 185 INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) 186 #else 187 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \ 188 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) 189 #endif 190 191 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \ 192 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 193 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 194 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ 195 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ 196 template<typename TestType> static void TestFuncName(); \ 197 namespace {\ 198 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) { \ 199 INTERNAL_CATCH_TYPE_GEN \ 200 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature)) \ 201 template<typename... Types> \ 202 struct TestName { \ 203 void reg_tests() { \ 204 int index = 0; \ 205 using expander = int[]; \ 206 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ 207 constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ 208 constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ 209 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */\ 210 } \ 211 }; \ 212 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ 213 using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \ 214 TestInit t; \ 215 t.reg_tests(); \ 216 return 0; \ 217 }(); \ 218 } \ 219 } \ 220 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 221 template<typename TestType> \ 222 static void TestFuncName() 223 224 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 225 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ 226 INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T,__VA_ARGS__) 227 #else 228 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\ 229 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, typename T, __VA_ARGS__ ) ) 230 #endif 231 232 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 233 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ 234 INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__) 235 #else 236 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\ 237 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, Signature, __VA_ARGS__ ) ) 238 #endif 239 240 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\ 241 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 242 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 243 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ 244 template<typename TestType> static void TestFunc(); \ 245 namespace {\ 246 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\ 247 INTERNAL_CATCH_TYPE_GEN\ 248 template<typename... Types> \ 249 struct TestName { \ 250 void reg_tests() { \ 251 int index = 0; \ 252 using expander = int[]; \ 253 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */\ 254 } \ 255 };\ 256 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \ 257 using TestInit = typename convert<TestName, TmplList>::type; \ 258 TestInit t; \ 259 t.reg_tests(); \ 260 return 0; \ 261 }(); \ 262 }}\ 263 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 264 template<typename TestType> \ 265 static void TestFunc() 266 267 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \ 268 INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, TmplList ) 269 270 271 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \ 272 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 273 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 274 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ 275 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ 276 namespace {\ 277 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \ 278 INTERNAL_CATCH_TYPE_GEN\ 279 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\ 280 INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\ 281 INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\ 282 template<typename...Types> \ 283 struct TestNameClass{\ 284 TestNameClass(){\ 285 int index = 0; \ 286 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\ 287 using expander = int[];\ 288 (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++, 0)... };/* NOLINT */ \ 289 }\ 290 };\ 291 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ 292 TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\ 293 return 0;\ 294 }();\ 295 }\ 296 }\ 297 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 298 INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature)) 299 300 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 301 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ 302 INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) 303 #else 304 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ 305 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) ) 306 #endif 307 308 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 309 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ 310 INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) 311 #else 312 #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \ 313 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) ) 314 #endif 315 316 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\ 317 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 318 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 319 CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ 320 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ 321 template<typename TestType> \ 322 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \ 323 void test();\ 324 };\ 325 namespace {\ 326 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\ 327 INTERNAL_CATCH_TYPE_GEN \ 328 INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\ 329 template<typename...Types>\ 330 struct TestNameClass{\ 331 void reg_tests(){\ 332 int index = 0;\ 333 using expander = int[];\ 334 constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\ 335 constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\ 336 constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\ 337 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + "<" + std::string(types_list[index % num_types]) + ">", Tags } ), index++, 0)... };/* NOLINT */ \ 338 }\ 339 };\ 340 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ 341 using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\ 342 TestInit t;\ 343 t.reg_tests();\ 344 return 0;\ 345 }(); \ 346 }\ 347 }\ 348 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 349 template<typename TestType> \ 350 void TestName<TestType>::test() 351 352 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 353 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ 354 INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T, __VA_ARGS__ ) 355 #else 356 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\ 357 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) ) 358 #endif 359 360 #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR 361 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ 362 INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature, __VA_ARGS__ ) 363 #else 364 #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\ 365 INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) ) 366 #endif 367 368 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \ 369 CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ 370 CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ 371 CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ 372 template<typename TestType> \ 373 struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \ 374 void test();\ 375 };\ 376 namespace {\ 377 namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \ 378 INTERNAL_CATCH_TYPE_GEN\ 379 template<typename...Types>\ 380 struct TestNameClass{\ 381 void reg_tests(){\ 382 int index = 0;\ 383 using expander = int[];\ 384 (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + " - " + std::to_string(index), Tags } ), index++, 0)... };/* NOLINT */ \ 385 }\ 386 };\ 387 static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ 388 using TestInit = typename convert<TestNameClass, TmplList>::type;\ 389 TestInit t;\ 390 t.reg_tests();\ 391 return 0;\ 392 }(); \ 393 }}\ 394 CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \ 395 template<typename TestType> \ 396 void TestName<TestType>::test() 397 398 #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \ 399 INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), ClassName, Name, Tags, TmplList ) 400 401 402 #endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED 403