mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 12:17:11 +01:00 
			
		
		
		
	Add support for templated tests
This adds support for templated tests and test methods via `TEMPLATE_TEST_CASE` and `TEMPLATE_TEST_CASE_METHOD` macros. These work mostly just like their regular counterparts*, but take an unlimited** number of types as their last arguments. * Unlike the plain `TEST_CASE*` macros, the `TEMPLATE*` variants require a tag string. ** In practice there is limit of about 300 types.
This commit is contained in:
		 Jozef Grajciar
					Jozef Grajciar
				
			
				
					committed by
					
						 Martin Hořeňovský
						Martin Hořeňovský
					
				
			
			
				
	
			
			
			 Martin Hořeňovský
						Martin Hořeňovský
					
				
			
						parent
						
							489a41012e
						
					
				
				
					commit
					2d906a92cb
				
			| @@ -136,6 +136,13 @@ | ||||
| #    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH | ||||
| #  endif | ||||
|  | ||||
| // MSVC traditional preprocessor needs some workaround for __VA_ARGS__ | ||||
| // _MSVC_TRADITIONAL == 0 means new conformant preprocessor | ||||
| // _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor | ||||
| #  if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) | ||||
| #    define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR | ||||
| #  endif | ||||
|  | ||||
| #endif // _MSC_VER | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -254,6 +261,9 @@ | ||||
| #define CATCH_CATCH_ANON(type) catch (type) | ||||
| #endif | ||||
|  | ||||
| #if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) | ||||
| #define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR | ||||
| #endif | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED | ||||
|  | ||||
|   | ||||
							
								
								
									
										74
									
								
								include/internal/catch_preprocessor.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								include/internal/catch_preprocessor.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| /* | ||||
|  *  Created by Jozef on 12/11/2018. | ||||
|  *  Copyright 2017 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_PREPROCESSOR_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED | ||||
|  | ||||
| #define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ | ||||
| #define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) | ||||
| #define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) | ||||
| #define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) | ||||
| #define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) | ||||
| #define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) | ||||
|  | ||||
| #ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR | ||||
| #define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ | ||||
| // MSVC needs more evaluations | ||||
| #define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) | ||||
| #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) | ||||
| #else | ||||
| #define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__) | ||||
| #endif | ||||
|  | ||||
| #define CATCH_REC_END(...) | ||||
| #define CATCH_REC_OUT | ||||
|  | ||||
| #define CATCH_EMPTY() | ||||
| #define CATCH_DEFER(id) id CATCH_EMPTY() | ||||
|  | ||||
| #define CATCH_REC_GET_END2() 0, CATCH_REC_END | ||||
| #define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 | ||||
| #define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 | ||||
| #define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT | ||||
| #define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) | ||||
| #define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) | ||||
|  | ||||
| #define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) | ||||
| #define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) | ||||
| #define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) | ||||
|  | ||||
| #define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) | ||||
| #define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) | ||||
| #define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...)   f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) | ||||
|  | ||||
| // Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, | ||||
| // and passes userdata as the first parameter to each invocation, | ||||
| // e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) | ||||
| #define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) | ||||
|  | ||||
| #define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) | ||||
|  | ||||
| #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) | ||||
| #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ | ||||
| #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ | ||||
| #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF | ||||
|  | ||||
| #define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) | ||||
|  | ||||
| #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name, __VA_ARGS__) | ||||
| #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR | ||||
| #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " - " #__VA_ARGS__ | ||||
| #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name,...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) | ||||
| #else | ||||
| // MSVC is adding extra space and needs more calls to properly remove () | ||||
| #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " -" #__VA_ARGS__ | ||||
| #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, __VA_ARGS__) | ||||
| #define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) | ||||
| #endif | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED | ||||
| @@ -12,6 +12,8 @@ | ||||
| #include "catch_interfaces_testcase.h" | ||||
| #include "catch_compiler_capabilities.h" | ||||
| #include "catch_stringref.h" | ||||
| #include "catch_type_traits.hpp" | ||||
| #include "catch_preprocessor.hpp" | ||||
|  | ||||
| namespace Catch { | ||||
|  | ||||
| @@ -47,22 +49,28 @@ struct AutoReg : NonCopyable { | ||||
|  | ||||
| } // end namespace Catch | ||||
|  | ||||
| #define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) | ||||
| #define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ | ||||
| #define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ | ||||
| #define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF | ||||
|  | ||||
| #if defined(CATCH_CONFIG_DISABLE) | ||||
|     #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \ | ||||
|         static void TestName() | ||||
|     #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \ | ||||
|         namespace{                        \ | ||||
|             struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ | ||||
|             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \ | ||||
|                 void test();              \ | ||||
|             };                            \ | ||||
|         }                                 \ | ||||
|         void TestName::test() | ||||
|  | ||||
|     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... )  \ | ||||
|         template<typename TestType>                                             \ | ||||
|         static void TestName() | ||||
|     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... )    \ | ||||
|         namespace{                                                                                  \ | ||||
|             template<typename TestType>                                                             \ | ||||
|             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) {     \ | ||||
|                 void test();                                                                        \ | ||||
|             };                                                                                      \ | ||||
|         }                                                                                           \ | ||||
|         template<typename TestType>                                                                 \ | ||||
|         void TestName::test() | ||||
| #endif | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -85,7 +93,7 @@ struct AutoReg : NonCopyable { | ||||
|     #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ | ||||
|         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ | ||||
|         namespace{ \ | ||||
|             struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ | ||||
|             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \ | ||||
|                 void test(); \ | ||||
|             }; \ | ||||
|             Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ | ||||
| @@ -101,5 +109,75 @@ struct AutoReg : NonCopyable { | ||||
|         Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ | ||||
|         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS | ||||
|  | ||||
|     /////////////////////////////////////////////////////////////////////////////// | ||||
|     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\ | ||||
|         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ | ||||
|         template<typename TestType> \ | ||||
|         static void TestFunc();\ | ||||
|         namespace {\ | ||||
|             template<typename...Types> \ | ||||
|             struct TestName{\ | ||||
|                 template<typename...Ts> \ | ||||
|                 TestName(Ts...names){\ | ||||
|                     CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \ | ||||
|                     using expander = int[];\ | ||||
|                     (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \ | ||||
|                 }\ | ||||
|             };\ | ||||
|             INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \ | ||||
|         }\ | ||||
|         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ | ||||
|         template<typename TestType> \ | ||||
|         static void TestFunc() | ||||
|  | ||||
| #if defined(CATCH_CPP17_OR_GREATER) | ||||
| #define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case"); | ||||
| #else | ||||
| #define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case"); | ||||
| #endif | ||||
|  | ||||
| #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR | ||||
|     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ | ||||
|         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, __VA_ARGS__ ) | ||||
| #else | ||||
|     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ | ||||
|         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, __VA_ARGS__ ) ) | ||||
| #endif | ||||
|  | ||||
|     #define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\ | ||||
|         static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ | ||||
|             TestName<CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)>(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\ | ||||
|             return 0;\ | ||||
|         }(); | ||||
|  | ||||
|     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \ | ||||
|         CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ | ||||
|         namespace{ \ | ||||
|             template<typename TestType> \ | ||||
|             struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \ | ||||
|                 void test();\ | ||||
|             };\ | ||||
|             template<typename...Types> \ | ||||
|             struct TestNameClass{\ | ||||
|                 template<typename...Ts> \ | ||||
|                 TestNameClass(Ts...names){\ | ||||
|                     CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \ | ||||
|                     using expander = int[];\ | ||||
|                     (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \ | ||||
|                 }\ | ||||
|             };\ | ||||
|             INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\ | ||||
|         }\ | ||||
|         CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\ | ||||
|         template<typename TestType> \ | ||||
|         void TestName<TestType>::test() | ||||
|  | ||||
| #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR | ||||
|     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ | ||||
|         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, __VA_ARGS__ ) | ||||
| #else | ||||
|     #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ | ||||
|         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, __VA_ARGS__ ) ) | ||||
| #endif | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED | ||||
|   | ||||
							
								
								
									
										38
									
								
								include/internal/catch_type_traits.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								include/internal/catch_type_traits.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| /* | ||||
|  *  Created by Jozef on 12/11/2018. | ||||
|  *  Copyright 2017 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_TYPE_TRAITS_HPP_INCLUDED | ||||
| #define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED | ||||
|  | ||||
| namespace Catch{ | ||||
|  | ||||
| #ifdef CATCH_CPP17_OR_GREATER | ||||
| 	template <typename...> | ||||
| 	inline constexpr auto is_unique = std::true_type{}; | ||||
|  | ||||
| 	template <typename T, typename... Rest> | ||||
| 	inline constexpr auto is_unique<T, Rest...> = std::bool_constant< | ||||
| 		(!std::is_same_v<T, Rest> && ...) && is_unique<Rest...> | ||||
| 	>{}; | ||||
| #else | ||||
|  | ||||
| template <typename...> | ||||
| struct is_unique : std::true_type{}; | ||||
|  | ||||
| template <typename T0, typename T1, typename... Rest> | ||||
| struct is_unique<T0, T1, Rest...> : std::integral_constant | ||||
| <bool, | ||||
|      !std::is_same<T0, T1>::value  | ||||
|      && is_unique<T0, Rest...>::value  | ||||
|      && is_unique<T1, Rest...>::value | ||||
| >{}; | ||||
|  | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #endif // TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED | ||||
		Reference in New Issue
	
	Block a user