catch_test_registry.h 27 KB

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