#ifndef INCG_IRIS_IUTEST_HPP_
#define INCG_IRIS_IUTEST_HPP_
#define IUTEST_VER 0x1170100u
#define IUTEST_MAJORVER 1u
#define IUTEST_MINORVER 0x17u
#define IUTEST_MICROVER 1u
#define IUTEST_REVISION 0u
#define IUTEST_BUILD IUTEST_MICROVER
#define IUTEST_OS_LINUX 1
#define IUTEST_PLATFORM "LINUX"
#define IUTEST_CPLUSPLUS_CXX11 201103L
#define IUTEST_CPLUSPLUS_CXX14 201402L
#define IUTEST_CPLUSPLUS_CXX17 201703L
#if defined(__cplusplus)
#define IUTEST_CPLUSPLUS __cplusplus
#else
#define IUTEST_CPLUSPLUS 0
#endif
#ifndef IUTEST_HAS_CXX2A
#if IUTEST_CPLUSPLUS>IUTEST_CPLUSPLUS_CXX17
#define IUTEST_HAS_CXX2A 1
#endif
#endif
#ifndef IUTEST_HAS_CXX2A
#define IUTEST_HAS_CXX2A 0
#endif
#ifndef IUTEST_HAS_CXX17
#if IUTEST_CPLUSPLUS>=IUTEST_CPLUSPLUS_CXX17
#define IUTEST_HAS_CXX17 1
#endif
#endif
#ifndef IUTEST_HAS_CXX17
#define IUTEST_HAS_CXX17 0
#endif
#ifndef IUTEST_HAS_CXX1Z
#if IUTEST_CPLUSPLUS>IUTEST_CPLUSPLUS_CXX14
#define IUTEST_HAS_CXX1Z 1
#endif
#endif
#ifndef IUTEST_HAS_CXX1Z
#define IUTEST_HAS_CXX1Z 0
#endif
#ifndef IUTEST_HAS_CXX14
#if IUTEST_CPLUSPLUS>=IUTEST_CPLUSPLUS_CXX14
#define IUTEST_HAS_CXX14 1
#endif
#endif
#ifndef IUTEST_HAS_CXX14
#define IUTEST_HAS_CXX14 0
#endif
#ifndef IUTEST_HAS_CXX11
#if(IUTEST_CPLUSPLUS>=IUTEST_CPLUSPLUS_CXX11)||defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_CXX11 1
#endif
#endif
#ifndef IUTEST_HAS_CXX11
#define IUTEST_HAS_CXX11 0
#endif
#ifndef IUTEST_HAS_CONCEPTS
#if defined(__cpp_concepts)&&__cpp_concepts>=201907
#define IUTEST_HAS_CONCEPTS 1
#endif
#endif
#ifndef IUTEST_HAS_CONCEPTS
#define IUTEST_HAS_CONCEPTS 0
#endif
#ifndef IUTEST_HAS_INLINE_VARIABLE
#if defined(__cpp_inline_variables)&&__cpp_inline_variables>=201606
#define IUTEST_HAS_INLINE_VARIABLE 1
#elif defined(__clang__)
#if IUTEST_HAS_CXX1Z&&(__clang_major__>3 ||(__clang_major__==3 && __clang_minor__>=9))
#define IUTEST_HAS_INLINE_VARIABLE 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_INLINE_VARIABLE
#define IUTEST_HAS_INLINE_VARIABLE 0
#endif
#ifndef IUTEST_HAS_CONSTEXPR_IF
#if defined(__cpp_if_constexpr)&&__cpp_if_constexpr>=201606
#define IUTEST_HAS_CONSTEXPR_IF 1
#endif
#endif
#ifndef IUTEST_HAS_CONSTEXPR_IF
#define IUTEST_HAS_CONSTEXPR_IF 0
#endif
#ifndef IUTEST_HAS_NULLPTR
#ifdef _NATIVE_NULLPTR_SUPPORTED
#define IUTEST_HAS_NULLPTR 1
#elif defined(__clang__)
#if __has_feature(cxx_nullptr)
#define IUTEST_HAS_NULLPTR 1
#endif
#if(__clang_major__<3 ||(__clang_major__==3 && __clang_minor__<=2))
#define IUTEST_NO_NULL_TO_NULLPTR_T 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=6))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_NULLPTR 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_NULLPTR
#define IUTEST_HAS_NULLPTR 0
#endif
#ifndef IUTEST_NULLPTR
#if IUTEST_HAS_NULLPTR
#define IUTEST_NULLPTR nullptr
#else
#define IUTEST_NULLPTR 0
#endif
#endif
#ifndef IUTEST_HAS_AUTO
#ifdef __clang__
#if __has_feature(cxx_auto_type)
#define IUTEST_HAS_AUTO 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=4))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_AUTO 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_AUTO
#define IUTEST_HAS_AUTO 0
#endif
#ifndef IUTEST_HAS_DECLTYPE
#if defined(__cpp_decltype)&&__cpp_decltype>=200707
#define IUTEST_HAS_DECLTYPE 1
#elif defined(__clang__)
#if __has_feature(cxx_decltype)
#define IUTEST_HAS_DECLTYPE 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=3))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_DECLTYPE 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_DECLTYPE
#define IUTEST_HAS_DECLTYPE 0
#endif
#ifndef IUTEST_HAS_STATIC_ASSERT
#if defined(__cpp_static_assert)&&__cpp_static_assert>=200410
#define IUTEST_HAS_STATIC_ASSERT 1
#elif defined(__clang__)
#if __has_feature(cxx_static_assert)
#define IUTEST_HAS_STATIC_ASSERT 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=3))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_STATIC_ASSERT 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_STATIC_ASSERT
#define IUTEST_HAS_STATIC_ASSERT 0
#endif
#ifndef IUTEST_HAS_CONSTEXPR
#if defined(__cpp_constexpr)&&__cpp_constexpr>=200704
#define IUTEST_HAS_CONSTEXPR 1
#elif defined(__clang__)
#if __has_feature(cxx_constexpr)
#define IUTEST_HAS_CONSTEXPR 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=6))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_CONSTEXPR 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_CONSTEXPR
#define IUTEST_HAS_CONSTEXPR 0
#endif
#if IUTEST_HAS_CONSTEXPR
#define II_CXX_CE constexpr
#else
#define II_CXX_CE
#endif
#if IUTEST_HAS_CONSTEXPR&&(defined(__cpp_constexpr)&&__cpp_constexpr>=201304||IUTEST_HAS_CXX14)
#define II_CXX14_CE constexpr
#else
#define II_CXX14_CE
#endif
#if IUTEST_HAS_CONSTEXPR
#define II_CXX_C_O_C constexpr
#else
#define II_CXX_C_O_C const
#endif
#ifndef IUTEST_HAS_RVALUE_REFS
#if defined(__cpp_rvalue_references)&&__cpp_rvalue_references>=200610
#define IUTEST_HAS_RVALUE_REFS 1
#elif defined(__clang__)
#if __has_feature(cxx_rvalue_references)
#define IUTEST_HAS_RVALUE_REFS 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=3))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_RVALUE_REFS 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_RVALUE_REFS
#define IUTEST_HAS_RVALUE_REFS 0
#endif
#ifndef IUTEST_HAS_DELETED_FUNCTIONS
#ifdef __clang__
#if __has_feature(cxx_deleted_functions)
#define IUTEST_HAS_DELETED_FUNCTIONS 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=4))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_DELETED_FUNCTIONS 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_DELETED_FUNCTIONS
#define IUTEST_HAS_DELETED_FUNCTIONS 0
#endif
#if IUTEST_HAS_DELETED_FUNCTIONS
#define II_CXX_DL_F =delete
#else
#define II_CXX_DL_F
#endif
#if !defined(IUTEST_HAS_MOVE_ASSIGNMENT_DEFAULT_FUNCTION)&&!IUTEST_HAS_RVALUE_REFS
#define IUTEST_HAS_MOVE_ASSIGNMENT_DEFAULT_FUNCTION 0
#endif
#ifndef IUTEST_HAS_DEFAULT_FUNCTIONS
#ifdef __clang__
#if __has_feature(cxx_defaulted_functions)
#define IUTEST_HAS_DEFAULT_FUNCTIONS 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__==4))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_DEFAULT_FUNCTIONS 1
#ifndef IUTEST_HAS_MOVE_ASSIGNMENT_DEFAULT_FUNCTION
#define IUTEST_HAS_MOVE_ASSIGNMENT_DEFAULT_FUNCTION 0
#endif
#elif(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=7))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_DEFAULT_FUNCTIONS 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_DEFAULT_FUNCTIONS
#define IUTEST_HAS_DEFAULT_FUNCTIONS 0
#endif
#ifndef IUTEST_HAS_MOVE_ASSIGNMENT_DEFAULT_FUNCTION
#define IUTEST_HAS_MOVE_ASSIGNMENT_DEFAULT_FUNCTION IUTEST_HAS_DEFAULT_FUNCTIONS
#endif
#if IUTEST_HAS_DEFAULT_FUNCTIONS
#define II_CXX_DF_F =default;
#else
#define II_CXX_DF_F {}
#endif
#ifndef IUTEST_HAS_INITIALIZER_LIST
#if defined(__cpp_initializer_lists)&&__cpp_initializer_lists>=200806
#define IUTEST_HAS_INITIALIZER_LIST 1
#elif defined(__clang__)
#if __has_feature(cxx_generalized_initializers)
#define IUTEST_HAS_INITIALIZER_LIST 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=4))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_INITIALIZER_LIST 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_INITIALIZER_LIST
#define IUTEST_HAS_INITIALIZER_LIST 0
#endif
#ifndef IUTEST_HAS_VARIADIC_TEMPLATES
#if defined(__cpp_variadic_templates)&&__cpp_variadic_templates>=200704
#define IUTEST_HAS_VARIADIC_TEMPLATES 1
#elif defined(__clang__)
#if __has_feature(cxx_variadic_templates)
#define IUTEST_HAS_VARIADIC_TEMPLATES 1
#endif
#elif defined(__GNUC__)
#if defined(__VARIADIC_TEMPLATES) ||(((__GNUC__>4)||((__GNUC__==4)&&(__GNUC_MINOR__>=7)))&&defined(__GXX_EXPERIMENTAL_CXX0X__))
#define IUTEST_HAS_VARIADIC_TEMPLATES 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_VARIADIC_TEMPLATES
#define IUTEST_HAS_VARIADIC_TEMPLATES 0
#endif
#ifndef IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES
#ifdef __clang__
#if __has_feature(cxx_variadic_templates)
#define IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES 1
#endif
#elif defined(__GNUC__)
#if defined(__VARIADIC_TEMPLATES)||(((__GNUC__>4) ||((__GNUC__==4)&&(__GNUC_MINOR__>=8)) ||((__GNUC__==4)&&(__GNUC_MINOR__>=7)&&(__GNUC_PATCHLEVEL__>=1))) && defined(__GXX_EXPERIMENTAL_CXX0X__))
#define IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES
#define IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES 0
#endif
#ifndef IUTEST_HAS_CHAR16_T
#if defined(__cpp_unicode_characters)&&__cpp_unicode_characters>=200704&&defined(__cpp_unicode_literals)&&__cpp_unicode_literals>=200710
#define IUTEST_HAS_CHAR16_T 1
#elif defined(__clang__)
#if __has_feature(cxx_unicode_literals)
#define IUTEST_HAS_CHAR16_T 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=4))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_CHAR16_T 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_CHAR16_T
#define IUTEST_HAS_CHAR16_T 0
#endif
#ifndef IUTEST_HAS_CHAR32_T
#if defined(__cpp_unicode_characters)&&__cpp_unicode_characters>=200704&&defined(__cpp_unicode_literals)&&__cpp_unicode_literals>=200710
#define IUTEST_HAS_CHAR32_T 1
#elif defined(__clang__)
#if __has_feature(cxx_unicode_literals)
#define IUTEST_HAS_CHAR32_T 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=4))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_CHAR32_T 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_CHAR32_T
#define IUTEST_HAS_CHAR32_T 0
#endif
#ifndef IUTEST_HAS_LAMBDA
#if defined(__cpp_lambdas)&&__cpp_lambdas>=200907
#define IUTEST_HAS_LAMBDA 1
#elif defined(__clang__)
#if __has_feature(cxx_lambdas)
#define IUTEST_HAS_LAMBDA 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=5))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_LAMBDA 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_LAMBDA
#define IUTEST_HAS_LAMBDA 0
#endif
#if IUTEST_HAS_LAMBDA
#ifdef __GNUC__
#if(__GNUC__<4 ||(__GNUC__==4 && __GNUC_MINOR__<7))
#define IUTEST_NO_LAMBDA_LOCAL_OBJECT_TEMPLATE_PARAMETERS
#endif
#endif
#endif
#ifndef IUTEST_HAS_EXPLICIT_CONVERSION
#ifdef __clang__
#if __has_feature(cxx_explicit_conversions)
#define IUTEST_HAS_EXPLICIT_CONVERSION 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=5))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_EXPLICIT_CONVERSION 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_EXPLICIT_CONVERSION
#define IUTEST_HAS_EXPLICIT_CONVERSION 0
#endif
#ifndef II_CXX_E_C
#if IUTEST_HAS_EXPLICIT_CONVERSION
#define II_CXX_E_C explicit
#else
#define II_CXX_E_C
#endif
#endif
#ifndef IUTEST_HAS_OVERRIDE_AND_FINAL
#ifdef __clang__
#if __has_feature(cxx_override_control)
#define IUTEST_HAS_OVERRIDE_AND_FINAL 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=7))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_OVERRIDE_AND_FINAL 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_OVERRIDE_AND_FINAL
#define IUTEST_HAS_OVERRIDE_AND_FINAL 0
#endif
#ifndef II_CXX_O
#if IUTEST_HAS_OVERRIDE_AND_FINAL
#define II_CXX_O override
#else
#define II_CXX_O
#endif
#endif
#ifndef II_CXX_F
#if IUTEST_HAS_OVERRIDE_AND_FINAL
#define II_CXX_F final
#else
#define II_CXX_F
#endif
#endif
#ifndef IUTEST_HAS_NOEXCEPT
#ifdef __clang__
#if __has_feature(cxx_noexcept)
#define IUTEST_HAS_NOEXCEPT 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=6))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_NOEXCEPT 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_NOEXCEPT
#define IUTEST_HAS_NOEXCEPT 0
#endif
#ifndef IUTEST_HAS_NOEXCEPT_FUNCTION_TYPE
#if defined(__cpp_noexcept_function_type)&&__cpp_noexcept_function_type>=201510L
#define IUTEST_HAS_NOEXCEPT_FUNCTION_TYPE 1
#endif
#endif
#ifndef IUTEST_HAS_NOEXCEPT_FUNCTION_TYPE
#define IUTEST_HAS_NOEXCEPT_FUNCTION_TYPE 0
#endif
#ifndef II_CXX_NEX_S
#if IUTEST_HAS_NOEXCEPT
#define II_CXX_NEX_S noexcept
#else
#define II_CXX_NEX_S
#endif
#endif
#ifndef IUTEST_HAS_EXTERN_TEMPLATE
#if defined(__GNUC__)||defined(__clang__)
#define IUTEST_HAS_EXTERN_TEMPLATE 1
#endif
#endif
#ifndef IUTEST_HAS_EXTERN_TEMPLATE
#define IUTEST_HAS_EXTERN_TEMPLATE 0
#endif
#ifndef IUTEST_HAS_STRONG_ENUMS
#ifdef __clang__
#if __has_feature(cxx_strong_enums)
#define IUTEST_HAS_STRONG_ENUMS 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=6))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_STRONG_ENUMS 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_STRONG_ENUMS
#define IUTEST_HAS_STRONG_ENUMS 0
#endif
#ifndef IUTEST_HAS_EXCEPTIONS
#if defined(__clang__)
#if __EXCEPTIONS&&__has_feature(cxx_exceptions)
#define IUTEST_HAS_EXCEPTIONS 1
#endif
#elif defined(__GNUC__)
#ifdef __EXCEPTIONS
#define IUTEST_HAS_EXCEPTIONS 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_EXCEPTIONS
#define IUTEST_HAS_EXCEPTIONS 0
#endif
#ifndef IUTEST_HAS_RTTI
#ifdef __clang__
#if __has_feature(cxx_rtti)
#define IUTEST_HAS_RTTI 1
#endif
#elif defined(__GNUC__)
#ifdef __RTTI
#define IUTEST_HAS_RTTI 1
#endif
#ifdef __GXX_RTTI
#define IUTEST_HAS_RTTI 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_RTTI
#define IUTEST_HAS_RTTI 0
#endif
#if IUTEST_HAS_RTTI
#include <typeinfo>
#endif
#ifndef IUTEST_WCHAR_UNSIGNED
#if defined(__WCHAR_UNSIGNED__)&&__WCHAR_UNSIGNED__
#define IUTEST_WCHAR_UNSIGNED 1
#endif
#endif
#ifndef IUTEST_WCHAR_UNSIGNED
#define IUTEST_WCHAR_UNSIGNED 0
#endif
#ifndef IUTEST_HAS_INT128
#if defined(__SIZEOF_INT128__)&&__SIZEOF_INT128__==16
#define IUTEST_HAS_INT128 1
#endif
#endif
#ifndef IUTEST_HAS_INT128
#define IUTEST_HAS_INT128 0
#endif
#ifndef IUTEST_HAS_COUNTER_MACRO
#if defined(__clang__)
#define IUTEST_HAS_COUNTER_MACRO 1
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=3))
#define IUTEST_HAS_COUNTER_MACRO 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_COUNTER_MACRO
#define IUTEST_HAS_COUNTER_MACRO 0
#endif
#ifndef IUTEST_HAS_FILENO
#if !defined(__STRICT_ANSI__)
#define IUTEST_HAS_FILENO 1
#endif
#endif
#ifndef IUTEST_HAS_ATTRIBUTE
#if defined(__cpp_attributes)&&__cpp_attributes>=200809
#define IUTEST_HAS_ATTRIBUTE 1
#elif defined(__clang__)
#if __has_feature(cxx_attributes)
#define IUTEST_HAS_ATTRIBUTE 1
#endif
#elif defined(__GNUC__)
#if(__GNUC__>4 ||(__GNUC__==4 && __GNUC_MINOR__>=8))&&defined(__GXX_EXPERIMENTAL_CXX0X__)
#define IUTEST_HAS_ATTRIBUTE 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_ATTRIBUTE
#define IUTEST_HAS_ATTRIBUTE 0
#endif
#ifndef II_ATR_U
#if(defined(__GNUC__))
#define II_ATR_U __attribute__((unused))
#elif defined(__clang__)
#if __has_attribute(unused)
#define II_ATR_U __attribute__((unused))
#endif
#endif
#endif
#ifndef II_ATR_U
#define II_ATR_U
#endif
#ifndef II_ATR_NR
#if IUTEST_HAS_ATTRIBUTE
#define II_ATR_NR [[noreturn]]
#elif defined(__clang__)
#if __has_attribute(noreturn)
#define II_ATR_NR __attribute__((noreturn))
#endif
#elif defined(__GNUC__)
#define II_ATR_NR __attribute__((noreturn))
#endif
#endif
#ifndef II_ATR_NR
#define II_ATR_NR
#endif
#ifndef II_ATR_F
#ifdef __has_attribute
#if __has_attribute(format)
#define II_ATR_F(fmt,fi,vi) __attribute__((__format__(fmt,fi,vi)))
#endif
#elif defined(__GNUC__)
#define II_ATR_F(fmt,fi,vi) __attribute__((__format__(fmt,fi,vi)))
#endif
#endif
#if !defined(II_ATR_F_P)&&defined(II_ATR_F)
#define II_ATR_F_P(fi,vi) II_ATR_F(__printf__,fi,vi)
#endif
#ifndef II_ATR_F
#define II_ATR_F(fmt,fi,vi)
#endif
#ifndef II_ATR_F_P
#define II_ATR_F_P(fi,vi)
#endif
#ifdef __clang__
#define IUTEST_PRAGMA(x) _Pragma(#x)
#elif defined(__GNUC__)
#define IUTEST_PRAGMA(x) _Pragma(#x)
#else
#define IUTEST_PRAGMA(x)
#endif
#define IUTEST_PRAGMA_MESSAGE(m) IUTEST_PRAGMA(message(m))
#ifdef __clang__
#define II_PGM_C_W_PU() IUTEST_PRAGMA(clang diagnostic push)
#define II_PGM_C_W_D(x) IUTEST_PRAGMA(clang diagnostic ignored x)
#define II_PGM_C_W_PP() IUTEST_PRAGMA(clang diagnostic pop)
#define II_PGM_G_W_PU II_PGM_C_W_PU
#define II_PGM_G_W_D II_PGM_C_W_D
#define II_PGM_G_W_PP II_PGM_C_W_PP
#endif
#ifdef __GNUC__
#if((__GNUC__>4)||(__GNUC__==4 && __GNUC_MINOR__>=6))
#define II_PGM_G_W_PU() IUTEST_PRAGMA(GCC diagnostic push)
#define II_PGM_G_W_D(x) IUTEST_PRAGMA(GCC diagnostic ignored x)
#define II_PGM_G_W_PP() IUTEST_PRAGMA(GCC diagnostic pop)
#define II_PGM_C_W_PU II_PGM_G_W_PU
#define II_PGM_C_W_D II_PGM_G_W_D
#define II_PGM_C_W_PP II_PGM_G_W_PP
#endif
#endif
#ifndef II_PGM_C_W_PU
#define II_PGM_C_W_PU()
#endif
#ifndef II_PGM_C_W_D
#define II_PGM_C_W_D(x)
#endif
#ifndef II_PGM_C_W_PP
#define II_PGM_C_W_PP()
#endif
#ifndef II_PGM_G_W_PU
#define II_PGM_G_W_PU()
#endif
#ifndef II_PGM_G_W_D
#define II_PGM_G_W_D(x)
#endif
#ifndef II_PGM_G_W_PP
#define II_PGM_G_W_PP()
#endif
#ifdef __clang__
#define II_PGM_W_PU() II_PGM_C_W_PU()
#define II_PGM_W_PP() II_PGM_C_W_PU()
#define IUTEST_PRAGMA_WARN_DISABLE(x) II_PGM_C_W_D(x)
#elif defined(__GNUC__)
#define II_PGM_W_PU() II_PGM_G_W_PU()
#define II_PGM_W_PP() II_PGM_G_W_PP()
#define IUTEST_PRAGMA_WARN_DISABLE(x) II_PGM_G_W_D(x)
#else
#define II_PGM_W_PU()
#define II_PGM_W_PP()
#define IUTEST_PRAGMA_WARN_DISABLE(x)
#endif
#if defined(__clang__)||defined(__GNUC__)
#endif
#define II_PGM_A_O_CN_G_W_D_B()
#define II_PGM_A_O_CN_G_W_D_E()
#ifndef II_PGM_W_D_S_C
#ifdef __clang__
#define II_PGM_W_D_S_C() II_PGM_C_W_D("-Wsign-compare")
#elif defined(__GNUC__)
#define II_PGM_W_D_S_C() II_PGM_G_W_D("-Wsign-compare")
#else
#define II_PGM_W_D_S_C()
#endif
#endif
#ifndef II_PGM_W_FE
#ifdef __clang__
#define II_PGM_W_FE() II_PGM_C_W_D("-Wfloat-equal")
#elif defined(__GNUC__)
#define II_PGM_W_FE() II_PGM_G_W_D("-Wfloat-equal")
#else
#define II_PGM_W_FE()
#endif
#endif
#ifndef II_PGM_W_CA
#ifdef __clang__
#define II_PGM_W_CA() II_PGM_C_W_D("-Wcast-align")
#elif defined(__GNUC__)
#define II_PGM_W_CA() II_PGM_G_W_D("-Wcast-align")
#else
#define II_PGM_W_CA()
#endif
#endif
#ifndef II_PGM_W_D_D_E
#ifdef __clang__
#if(__clang_major__>3 ||(__clang_major__==3 && __clang_minor__>0))
#define II_PGM_W_D_D_E() II_PGM_C_W_D("-Wdangling-else")
#endif
#elif defined(__GNUC__)
#if(__GNUC__>6)
#define II_PGM_W_D_D_E() II_PGM_G_W_D("-Wdangling-else")
#endif
#endif
#endif
#ifndef II_PGM_W_D_D_E
#define II_PGM_W_D_D_E()
#endif
#ifndef II_PGM_W_D_NE_T
#if defined(__GNUC__)&&(__GNUC__>6)
#define II_PGM_W_D_NE_T() II_PGM_G_W_D("-Wnoexcept-type")
#endif
#endif
#ifndef II_PGM_W_D_NE_T
#define II_PGM_W_D_NE_T()
#endif
#define IP_DIS_C_A_A(TypeName) TypeName(const TypeName&);TypeName& operator=(const TypeName&)
#define IP_DIS_A(TypeName) private: TypeName& operator=(const TypeName&)
#if defined(IUTEST_HAS_RVALUE_REFS)&&IUTEST_HAS_RVALUE_REFS
#define IP_DIS_M_A_C_A_A(TypeName) IP_DIS_C_A_A(TypeName);TypeName(TypeName&& rhs);TypeName& operator=(TypeName&&)
#else
#define IP_DIS_M_A_C_A_A(TypeName) IP_DIS_C_A_A(TypeName)
#endif
#ifndef IUTEST_PP_TOSTRING
#define IUTEST_PP_TOSTRING(z_) IP_TOSTRING_(z_)
#endif
#define IP_TOSTRING_(z_) #z_
#ifndef IP_CAT
#define IP_CAT(a_,b_) IP_CAT_(a_,b_)
#endif
#define IP_CAT_(a_,b_) a_##b_
#define IUTEST_PP_EXPAND(x) x
#define IUTEST_PP_COUNTOF(x) (sizeof(x)/sizeof(x[0]))
#if IUTEST_HAS_COUNTER_MACRO
#define IUTEST_PP_COUNTER __COUNTER__
#else
#define IUTEST_PP_COUNTER __LINE__
#endif
#if IUTEST_HAS_COUNTER_MACRO
#define IUTEST_PP_UNIQUEID IP_CAT(__LINE__,__COUNTER__)
#else
#define IUTEST_PP_UNIQUEID __LINE__
#endif
#define IUTEST_UNUSED_RETURN(x) (void)(x)
#define IP_NS_E_C_R_S(ns,name) case ns::name: return #name
#define IP_DEC(n) IP_D_I(n)
#define IP_D_I(n) IP_D_##n
#define IP_D_0 nil
#define IP_D_1 0
#define IP_D_2 1
#define IP_D_3 2
#define IP_D_4 3
#define IP_D_5 4
#define IP_D_6 5
#define IP_D_7 6
#define IP_D_8 7
#define IP_D_9 8
#define IP_D_10 9
#define IP_D_11 10
#define IP_D_12 11
#define IP_D_13 12
#define IP_D_14 13
#define IP_D_15 14
#define IP_D_16 15
#define IP_D_17 16
#define IP_D_18 17
#define IP_D_19 18
#define IP_D_20 19
#define IP_D_21 20
#define IP_D_22 21
#define IP_D_23 22
#define IP_D_24 23
#define IP_D_25 24
#define IP_D_26 25
#define IP_D_27 26
#define IP_D_28 27
#define IP_D_29 28
#define IP_D_30 29
#define IP_D_31 30
#define IP_D_32 31
#define IP_D_33 32
#define IP_D_34 33
#define IP_D_35 34
#define IP_D_36 35
#define IP_D_37 36
#define IP_D_38 37
#define IP_D_39 38
#define IP_D_40 39
#define IP_D_41 40
#define IP_D_42 41
#define IP_D_43 42
#define IP_D_44 43
#define IP_D_45 44
#define IP_D_46 45
#define IP_D_47 46
#define IP_D_48 47
#define IP_D_49 48
#define IP_D_50 49
#define IP_D_51 50
#define IP_INC(n) IP_I_I(n)
#define IP_I_I(n) IP_I_##n
#define IP_I_0 1
#define IP_I_1 2
#define IP_I_2 3
#define IP_I_3 4
#define IP_I_4 5
#define IP_I_5 6
#define IP_I_6 7
#define IP_I_7 8
#define IP_I_8 9
#define IP_I_9 10
#define IP_I_10 11
#define IP_I_11 12
#define IP_I_12 13
#define IP_I_13 14
#define IP_I_14 15
#define IP_I_15 16
#define IP_I_16 17
#define IP_I_17 18
#define IP_I_18 19
#define IP_I_19 20
#define IP_I_20 21
#define IP_I_21 22
#define IP_I_22 23
#define IP_I_23 24
#define IP_I_24 25
#define IP_I_25 26
#define IP_I_26 27
#define IP_I_27 28
#define IP_I_28 29
#define IP_I_29 30
#define IP_I_30 31
#define IP_I_31 32
#define IP_I_32 33
#define IP_I_33 34
#define IP_I_34 35
#define IP_I_35 36
#define IP_I_36 37
#define IP_I_37 38
#define IP_I_38 39
#define IP_I_39 40
#define IP_I_40 41
#define IP_I_41 42
#define IP_I_42 43
#define IP_I_43 44
#define IP_I_44 45
#define IP_I_45 46
#define IP_I_46 47
#define IP_I_47 48
#define IP_I_48 49
#define IP_I_49 50
#define IP_I_50 51
#define IP_I_100 nil
#define IUTEST_PP_LIMIT_REPEAT 50
#define IP_R_P_M_(i,param) param
#define IP_R_P_M_B_(i,param1,param2) param2(i,param1)
#define IUTEST_PP_REPEAT_PARAMS(n,param) IUTEST_PP_REPEAT(n,IP_R_P_M_,param)
#define IUTEST_PP_REPEAT(n,m,param) IUTEST_PP_REPEAT_BINARY(n,IP_R_P_M_B_,param,m)
#define IP_R_B_P_M_(i,param1,param2) param1 param2
#define IUTEST_PP_REPEAT_BINARY_PARAMS(n,param1,param2) IUTEST_PP_REPEAT_BINARY(n,IP_R_B_P_M_,param1,param2)
#define IUTEST_PP_REPEAT_BINARY(n,m,param1,param2) IP_R_B_P_I(n,m,param1,param2)
#define IP_R_B_P_I(n,m,p1,p2) IP_CAT(IP_R_I_,IP_DEC(n))(0,m,p1,p2)
#define IP_R_I_nil(i,m,p1,p2)
#define IP_R_I_0(i,m,p1,p2) m(i,p1,p2)
#define IP_R_I_1(i,m,p1,p2) m(i,p1,p2) IP_R_I_0(IP_INC(i),m,p1,p2)
#define IP_R_I_2(i,m,p1,p2) m(i,p1,p2) IP_R_I_1(IP_INC(i),m,p1,p2)
#define IP_R_I_3(i,m,p1,p2) m(i,p1,p2) IP_R_I_2(IP_INC(i),m,p1,p2)
#define IP_R_I_4(i,m,p1,p2) m(i,p1,p2) IP_R_I_3(IP_INC(i),m,p1,p2)
#define IP_R_I_5(i,m,p1,p2) m(i,p1,p2) IP_R_I_4(IP_INC(i),m,p1,p2)
#define IP_R_I_6(i,m,p1,p2) m(i,p1,p2) IP_R_I_5(IP_INC(i),m,p1,p2)
#define IP_R_I_7(i,m,p1,p2) m(i,p1,p2) IP_R_I_6(IP_INC(i),m,p1,p2)
#define IP_R_I_8(i,m,p1,p2) m(i,p1,p2) IP_R_I_7(IP_INC(i),m,p1,p2)
#define IP_R_I_9(i,m,p1,p2) m(i,p1,p2) IP_R_I_8(IP_INC(i),m,p1,p2)
#define IP_R_I_10(i,m,p1,p2) m(i,p1,p2) IP_R_I_9(IP_INC(i),m,p1,p2)
#define IP_R_I_11(i,m,p1,p2) m(i,p1,p2) IP_R_I_10(IP_INC(i),m,p1,p2)
#define IP_R_I_12(i,m,p1,p2) m(i,p1,p2) IP_R_I_11(IP_INC(i),m,p1,p2)
#define IP_R_I_13(i,m,p1,p2) m(i,p1,p2) IP_R_I_12(IP_INC(i),m,p1,p2)
#define IP_R_I_14(i,m,p1,p2) m(i,p1,p2) IP_R_I_13(IP_INC(i),m,p1,p2)
#define IP_R_I_15(i,m,p1,p2) m(i,p1,p2) IP_R_I_14(IP_INC(i),m,p1,p2)
#define IP_R_I_16(i,m,p1,p2) m(i,p1,p2) IP_R_I_15(IP_INC(i),m,p1,p2)
#define IP_R_I_17(i,m,p1,p2) m(i,p1,p2) IP_R_I_16(IP_INC(i),m,p1,p2)
#define IP_R_I_18(i,m,p1,p2) m(i,p1,p2) IP_R_I_17(IP_INC(i),m,p1,p2)
#define IP_R_I_19(i,m,p1,p2) m(i,p1,p2) IP_R_I_18(IP_INC(i),m,p1,p2)
#define IP_R_I_20(i,m,p1,p2) m(i,p1,p2) IP_R_I_19(IP_INC(i),m,p1,p2)
#define IP_R_I_21(i,m,p1,p2) m(i,p1,p2) IP_R_I_20(IP_INC(i),m,p1,p2)
#define IP_R_I_22(i,m,p1,p2) m(i,p1,p2) IP_R_I_21(IP_INC(i),m,p1,p2)
#define IP_R_I_23(i,m,p1,p2) m(i,p1,p2) IP_R_I_22(IP_INC(i),m,p1,p2)
#define IP_R_I_24(i,m,p1,p2) m(i,p1,p2) IP_R_I_23(IP_INC(i),m,p1,p2)
#define IP_R_I_25(i,m,p1,p2) m(i,p1,p2) IP_R_I_24(IP_INC(i),m,p1,p2)
#define IP_R_I_26(i,m,p1,p2) m(i,p1,p2) IP_R_I_25(IP_INC(i),m,p1,p2)
#define IP_R_I_27(i,m,p1,p2) m(i,p1,p2) IP_R_I_26(IP_INC(i),m,p1,p2)
#define IP_R_I_28(i,m,p1,p2) m(i,p1,p2) IP_R_I_27(IP_INC(i),m,p1,p2)
#define IP_R_I_29(i,m,p1,p2) m(i,p1,p2) IP_R_I_28(IP_INC(i),m,p1,p2)
#define IP_R_I_30(i,m,p1,p2) m(i,p1,p2) IP_R_I_29(IP_INC(i),m,p1,p2)
#define IP_R_I_31(i,m,p1,p2) m(i,p1,p2) IP_R_I_30(IP_INC(i),m,p1,p2)
#define IP_R_I_32(i,m,p1,p2) m(i,p1,p2) IP_R_I_31(IP_INC(i),m,p1,p2)
#define IP_R_I_33(i,m,p1,p2) m(i,p1,p2) IP_R_I_32(IP_INC(i),m,p1,p2)
#define IP_R_I_34(i,m,p1,p2) m(i,p1,p2) IP_R_I_33(IP_INC(i),m,p1,p2)
#define IP_R_I_35(i,m,p1,p2) m(i,p1,p2) IP_R_I_34(IP_INC(i),m,p1,p2)
#define IP_R_I_36(i,m,p1,p2) m(i,p1,p2) IP_R_I_35(IP_INC(i),m,p1,p2)
#define IP_R_I_37(i,m,p1,p2) m(i,p1,p2) IP_R_I_36(IP_INC(i),m,p1,p2)
#define IP_R_I_38(i,m,p1,p2) m(i,p1,p2) IP_R_I_37(IP_INC(i),m,p1,p2)
#define IP_R_I_39(i,m,p1,p2) m(i,p1,p2) IP_R_I_38(IP_INC(i),m,p1,p2)
#define IP_R_I_40(i,m,p1,p2) m(i,p1,p2) IP_R_I_39(IP_INC(i),m,p1,p2)
#define IP_R_I_41(i,m,p1,p2) m(i,p1,p2) IP_R_I_40(IP_INC(i),m,p1,p2)
#define IP_R_I_42(i,m,p1,p2) m(i,p1,p2) IP_R_I_41(IP_INC(i),m,p1,p2)
#define IP_R_I_43(i,m,p1,p2) m(i,p1,p2) IP_R_I_42(IP_INC(i),m,p1,p2)
#define IP_R_I_44(i,m,p1,p2) m(i,p1,p2) IP_R_I_43(IP_INC(i),m,p1,p2)
#define IP_R_I_45(i,m,p1,p2) m(i,p1,p2) IP_R_I_44(IP_INC(i),m,p1,p2)
#define IP_R_I_46(i,m,p1,p2) m(i,p1,p2) IP_R_I_45(IP_INC(i),m,p1,p2)
#define IP_R_I_47(i,m,p1,p2) m(i,p1,p2) IP_R_I_46(IP_INC(i),m,p1,p2)
#define IP_R_I_48(i,m,p1,p2) m(i,p1,p2) IP_R_I_47(IP_INC(i),m,p1,p2)
#define IP_R_I_49(i,m,p1,p2) m(i,p1,p2) IP_R_I_48(IP_INC(i),m,p1,p2)
#define IP_R_I_50(i,m,p1,p2) m(i,p1,p2) IP_R_I_49(IP_INC(i),m,p1,p2)
#define IUTEST_PP_LIMIT_ENUM 50
#define IP_E_P_M_(i,param) IP_CAT(param,i)
#define IP_E_P_M_B_(i,param1,param2) param2(i,param1)
#define IP_ENM_P(n,param) IP_ENM(n,IP_E_P_M_,param)
#define IP_ENM(n,m,param) IP_ENM_B(n,IP_E_P_M_B_,param,m)
#define IP_ENM_S_P(n,param) IP_ENM_S(n,IP_E_P_M_,param)
#define IP_ENM_S(n,m,param) IP_ENM_S_B(n,IP_E_P_M_B_,param,m)
#define IP_E_B_P_M_(i,param1,param2) IP_CAT(param1,i) IP_CAT(param2,i)
#define IP_ENM_B_P(n,param1,param2) IP_ENM_B(n,IP_E_B_P_M_,param1,param2)
#define IP_ENM_B(n,m,param1,param2) IP_E_B_P_I(0,n,m,param1,param2)
#define IP_ENM_S_B_P(n,param1,param2) IP_ENM_B(n,IP_E_B_P_M_,param1,param2)
#define IP_ENM_S_B(n,m,param1,param2) IP_E_B_P_I(1,n,m,param1,param2)
#define IP_E_B_P_I(begin,n,m,p1,p2) IP_CAT(IP_E_I_,IP_DEC(n))(begin,m,p1,p2)
#define IP_E_I_nil(i,m,p1,p2)
#define IP_E_I_0(i,m,p1,p2) m(i,p1,p2)
#define IP_E_I_1(i,m,p1,p2) m(i,p1,p2),IP_E_I_0(IP_INC(i),m,p1,p2)
#define IP_E_I_2(i,m,p1,p2) m(i,p1,p2),IP_E_I_1(IP_INC(i),m,p1,p2)
#define IP_E_I_3(i,m,p1,p2) m(i,p1,p2),IP_E_I_2(IP_INC(i),m,p1,p2)
#define IP_E_I_4(i,m,p1,p2) m(i,p1,p2),IP_E_I_3(IP_INC(i),m,p1,p2)
#define IP_E_I_5(i,m,p1,p2) m(i,p1,p2),IP_E_I_4(IP_INC(i),m,p1,p2)
#define IP_E_I_6(i,m,p1,p2) m(i,p1,p2),IP_E_I_5(IP_INC(i),m,p1,p2)
#define IP_E_I_7(i,m,p1,p2) m(i,p1,p2),IP_E_I_6(IP_INC(i),m,p1,p2)
#define IP_E_I_8(i,m,p1,p2) m(i,p1,p2),IP_E_I_7(IP_INC(i),m,p1,p2)
#define IP_E_I_9(i,m,p1,p2) m(i,p1,p2),IP_E_I_8(IP_INC(i),m,p1,p2)
#define IP_E_I_10(i,m,p1,p2) m(i,p1,p2),IP_E_I_9(IP_INC(i),m,p1,p2)
#define IP_E_I_11(i,m,p1,p2) m(i,p1,p2),IP_E_I_10(IP_INC(i),m,p1,p2)
#define IP_E_I_12(i,m,p1,p2) m(i,p1,p2),IP_E_I_11(IP_INC(i),m,p1,p2)
#define IP_E_I_13(i,m,p1,p2) m(i,p1,p2),IP_E_I_12(IP_INC(i),m,p1,p2)
#define IP_E_I_14(i,m,p1,p2) m(i,p1,p2),IP_E_I_13(IP_INC(i),m,p1,p2)
#define IP_E_I_15(i,m,p1,p2) m(i,p1,p2),IP_E_I_14(IP_INC(i),m,p1,p2)
#define IP_E_I_16(i,m,p1,p2) m(i,p1,p2),IP_E_I_15(IP_INC(i),m,p1,p2)
#define IP_E_I_17(i,m,p1,p2) m(i,p1,p2),IP_E_I_16(IP_INC(i),m,p1,p2)
#define IP_E_I_18(i,m,p1,p2) m(i,p1,p2),IP_E_I_17(IP_INC(i),m,p1,p2)
#define IP_E_I_19(i,m,p1,p2) m(i,p1,p2),IP_E_I_18(IP_INC(i),m,p1,p2)
#define IP_E_I_20(i,m,p1,p2) m(i,p1,p2),IP_E_I_19(IP_INC(i),m,p1,p2)
#define IP_E_I_21(i,m,p1,p2) m(i,p1,p2),IP_E_I_20(IP_INC(i),m,p1,p2)
#define IP_E_I_22(i,m,p1,p2) m(i,p1,p2),IP_E_I_21(IP_INC(i),m,p1,p2)
#define IP_E_I_23(i,m,p1,p2) m(i,p1,p2),IP_E_I_22(IP_INC(i),m,p1,p2)
#define IP_E_I_24(i,m,p1,p2) m(i,p1,p2),IP_E_I_23(IP_INC(i),m,p1,p2)
#define IP_E_I_25(i,m,p1,p2) m(i,p1,p2),IP_E_I_24(IP_INC(i),m,p1,p2)
#define IP_E_I_26(i,m,p1,p2) m(i,p1,p2),IP_E_I_25(IP_INC(i),m,p1,p2)
#define IP_E_I_27(i,m,p1,p2) m(i,p1,p2),IP_E_I_26(IP_INC(i),m,p1,p2)
#define IP_E_I_28(i,m,p1,p2) m(i,p1,p2),IP_E_I_27(IP_INC(i),m,p1,p2)
#define IP_E_I_29(i,m,p1,p2) m(i,p1,p2),IP_E_I_28(IP_INC(i),m,p1,p2)
#define IP_E_I_30(i,m,p1,p2) m(i,p1,p2),IP_E_I_29(IP_INC(i),m,p1,p2)
#define IP_E_I_31(i,m,p1,p2) m(i,p1,p2),IP_E_I_30(IP_INC(i),m,p1,p2)
#define IP_E_I_32(i,m,p1,p2) m(i,p1,p2),IP_E_I_31(IP_INC(i),m,p1,p2)
#define IP_E_I_33(i,m,p1,p2) m(i,p1,p2),IP_E_I_32(IP_INC(i),m,p1,p2)
#define IP_E_I_34(i,m,p1,p2) m(i,p1,p2),IP_E_I_33(IP_INC(i),m,p1,p2)
#define IP_E_I_35(i,m,p1,p2) m(i,p1,p2),IP_E_I_34(IP_INC(i),m,p1,p2)
#define IP_E_I_36(i,m,p1,p2) m(i,p1,p2),IP_E_I_35(IP_INC(i),m,p1,p2)
#define IP_E_I_37(i,m,p1,p2) m(i,p1,p2),IP_E_I_36(IP_INC(i),m,p1,p2)
#define IP_E_I_38(i,m,p1,p2) m(i,p1,p2),IP_E_I_37(IP_INC(i),m,p1,p2)
#define IP_E_I_39(i,m,p1,p2) m(i,p1,p2),IP_E_I_38(IP_INC(i),m,p1,p2)
#define IP_E_I_40(i,m,p1,p2) m(i,p1,p2),IP_E_I_39(IP_INC(i),m,p1,p2)
#define IP_E_I_41(i,m,p1,p2) m(i,p1,p2),IP_E_I_40(IP_INC(i),m,p1,p2)
#define IP_E_I_42(i,m,p1,p2) m(i,p1,p2),IP_E_I_41(IP_INC(i),m,p1,p2)
#define IP_E_I_43(i,m,p1,p2) m(i,p1,p2),IP_E_I_42(IP_INC(i),m,p1,p2)
#define IP_E_I_44(i,m,p1,p2) m(i,p1,p2),IP_E_I_43(IP_INC(i),m,p1,p2)
#define IP_E_I_45(i,m,p1,p2) m(i,p1,p2),IP_E_I_44(IP_INC(i),m,p1,p2)
#define IP_E_I_46(i,m,p1,p2) m(i,p1,p2),IP_E_I_45(IP_INC(i),m,p1,p2)
#define IP_E_I_47(i,m,p1,p2) m(i,p1,p2),IP_E_I_46(IP_INC(i),m,p1,p2)
#define IP_E_I_48(i,m,p1,p2) m(i,p1,p2),IP_E_I_47(IP_INC(i),m,p1,p2)
#define IP_E_I_49(i,m,p1,p2) m(i,p1,p2),IP_E_I_48(IP_INC(i),m,p1,p2)
#define IP_E_I_50(i,m,p1,p2) m(i,p1,p2),IP_E_I_49(IP_INC(i),m,p1,p2)
#define IUTEST_PP_BOOL(n) IP_B_I(n)
#define IP_B_I(n) IP_B_##n
#define IP_B_0 0
#define IP_B_1 1
#define IP_B_2 1
#define IP_B_3 1
#define IP_B_4 1
#define IP_B_5 1
#define IP_B_6 1
#define IP_B_7 1
#define IP_B_8 1
#define IP_B_9 1
#define IP_B_10 1
#define IP_B_11 1
#define IP_B_12 1
#define IP_B_13 1
#define IP_B_14 1
#define IP_B_15 1
#define IP_B_16 1
#define IP_B_17 1
#define IP_B_18 1
#define IP_B_19 1
#define IP_B_20 1
#define IP_B_21 1
#define IP_B_22 1
#define IP_B_23 1
#define IP_B_24 1
#define IP_B_25 1
#define IP_B_26 1
#define IP_B_27 1
#define IP_B_28 1
#define IP_B_29 1
#define IP_B_30 1
#define IP_B_31 1
#define IP_B_32 1
#define IP_B_33 1
#define IP_B_34 1
#define IP_B_35 1
#define IP_B_36 1
#define IP_B_37 1
#define IP_B_38 1
#define IP_B_39 1
#define IP_B_40 1
#define IP_B_41 1
#define IP_B_42 1
#define IP_B_43 1
#define IP_B_44 1
#define IP_B_45 1
#define IP_B_46 1
#define IP_B_47 1
#define IP_B_48 1
#define IP_B_49 1
#define IP_B_50 1
#define IP_B_51 1
#define IUTEST_PP_IF(cond,t,f) IP_IF_I(IUTEST_PP_BOOL(cond),t,f)
#define IP_IF_I(cond,t,f) IP_CAT(IP_IF_,cond)(t,f)
#define IP_IF_0(t,f) f
#define IP_IF_1(t,f) t
#define IUTEST_PP_IS_EMPTY(x) IP_IS_EMP_I(x IP_EMP_T)
#define IP_IS_EMP_I(x) IP_IS_EMP_I_(IP_CAT(IP_EMP_T_,x)())
#define IP_IS_EMP_I_(x) IP_IS_EMP_II((x))
#define IP_IS_EMP_II(x) IP_IS_EMP_II_ x
#define IP_IS_EMP_II_(a,b) b
#define IP_EMPTY()
#define IP_EMP_T() ,0
#define IP_EMP_T_IP_EMP_T 1,1 IP_EMPTY
#define IUTEST_PP_IDENTITY(x) x IP_EMPTY
#ifndef IUTEST_PP_VA_CAT
#define IUTEST_PP_VA_CAT(a,...) IP_VA_CAT_I(a,__VA_ARGS__)
#define IP_VA_CAT_I(a,...) a ## __VA_ARGS__
#endif
#define IP_SPLIT(i,...) IP_VA_CAT_I(IP_SPLIT_,i)(__VA_ARGS__)
#define IP_IS_BGN_P_C(...) 1
#define IP_SPLIT_0(a,...) a
#define IP_SPLIT_1(a,...) __VA_ARGS__
#define IP_IS_B_PAR(...) IP_SPLIT(0,IUTEST_PP_VA_CAT(IP_IS_BGN_P_R_ ,IP_IS_BGN_P_C __VA_ARGS__))
#define IP_IS_BGN_P_R_1 1,
#define IP_IS_BGN_P_R_IP_IS_BGN_P_C 0,
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#include <stdint.h>
#include <cstdlib>
#include <cstddef>
#include <limits>
#ifdef __has_include
#if __has_include(<version>)
#define IUTEST_HAS_CXX_HDR_VERSION 1
#endif
#endif
#ifndef IUTEST_HAS_CXX_HDR_VERSION
#define IUTEST_HAS_CXX_HDR_VERSION 0
#endif
#if IUTEST_HAS_CXX_HDR_VERSION
#include <version>
#endif
#if defined(__GLIBCPP__)||defined(__GLIBCXX__)
#ifdef __clang__
#if __has_include(<experimental/memory_resource>)
#define II_LSTDCXX_V 60100
#elif __has_include(<experimental/any>)
#define II_LSTDCXX_V 50100
#elif __has_include(<shared_mutex>)
#define II_LSTDCXX_V 40900
#elif __has_include(<ext/cmath>)
#define II_LSTDCXX_V 40800
#elif __has_include(<scoped_allocator>)
#define II_LSTDCXX_V 40700
#elif __has_include(<typeindex>)
#define II_LSTDCXX_V 40600
#elif __has_include(<future>)
#define II_LSTDCXX_V 40500
#elif __has_include(<ratio>)
#define II_LSTDCXX_V 40400
#elif __has_include(<array>)
#define II_LSTDCXX_V 40300
#endif
#elif defined(__GNUC__)
#define II_LSTDCXX_V (__GNUC__*10000+__GNUC_MINOR__*100+__GNUC_PATCHLEVEL__)
#endif
#if IUTEST_HAS_CXX11
#if II_LSTDCXX_V>=60100
#if !defined(IUTEST_HAS_STD_INVOKE)&&IUTEST_HAS_CXX1Z
#define IUTEST_HAS_STD_INVOKE 1
#endif
#endif
#if II_LSTDCXX_V>=50100
#ifndef IUTEST_HAS_CXX_HDR_CODECVT
#define IUTEST_HAS_CXX_HDR_CODECVT 1
#endif
#endif
#if II_LSTDCXX_V>=40900
#ifndef IUTEST_HAS_CXX_HDR_REGEX
#define IUTEST_HAS_CXX_HDR_REGEX 1
#endif
#endif
#if II_LSTDCXX_V>=40700
#ifndef IUTEST_HAS_STD_EMPLACE
#define IUTEST_HAS_STD_EMPLACE 1
#endif
#ifndef IUTEST_HAS_CXX_HDR_CHRONO
#define IUTEST_HAS_CXX_HDR_CHRONO 1
#endif
#endif
#if II_LSTDCXX_V>=40600
#ifndef IUTEST_HAS_STD_BEGIN_END
#define IUTEST_HAS_STD_BEGIN_END 1
#endif
#endif
#if II_LSTDCXX_V>=40500
#ifndef IUTEST_HAS_STD_DECLVAL
#define IUTEST_HAS_STD_DECLVAL 1
#endif
#ifndef IUTEST_HAS_CXX_HDR_RANDOM
#define IUTEST_HAS_CXX_HDR_RANDOM 1
#endif
#ifndef IUTEST_HAS_CXX_HDR_CSTDINT
#define IUTEST_HAS_CXX_HDR_CSTDINT 1
#endif
#endif
#if II_LSTDCXX_V>=40300
#ifndef IUTEST_HAS_CXX_HDR_ARRAY
#define IUTEST_HAS_CXX_HDR_ARRAY 1
#endif
#ifndef IUTEST_HAS_STD_TUPLE
#define IUTEST_HAS_STD_TUPLE 1
#endif
#endif
#if defined(_GLIBCXX_HAVE_QUICK_EXIT)&&defined(_GLIBCXX_HAVE_AT_QUICK_EXIT)
#ifndef IUTEST_HAS_STD_QUICK_EXIT
#define IUTEST_HAS_STD_QUICK_EXIT 1
#endif
#endif
#ifdef __has_include
#if !defined(IUTEST_HAS_CXX_HDR_CUCHAR)&&__has_include(<cuchar>)
#if defined(_GLIBCXX_USE_C11_UCHAR_CXX11)&&_GLIBCXX_USE_C11_UCHAR_CXX11
#define IUTEST_HAS_CXX_HDR_CUCHAR 1
#endif
#endif
#endif
#endif
#ifndef IUTEST_HAS_STD_TUPLE
#if((II_LSTDCXX_V>=40000))
#ifndef IUTEST_HAS_TR1_TUPLE
#define IUTEST_HAS_TR1_TUPLE 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_HDR_CXXABI
#ifdef __has_include
#if __has_include(<cxxabi.h>)
#define IUTEST_HAS_HDR_CXXABI 1
#endif
#else
#define IUTEST_HAS_HDR_CXXABI 1
#endif
#endif
#if defined(__GNUC__)&&!defined(__clang__)
#if(__GNUC__<9)
#define IUTEST_HAS_CXX_HDR_FILESYSTEM 0
#endif
#endif
#elif defined(_LIBCPP_VERSION)
#if IUTEST_HAS_CXX11
#ifndef IUTEST_HAS_STD_BEGIN_END
#define IUTEST_HAS_STD_BEGIN_END 1
#endif
#ifndef IUTEST_HAS_STD_DECLVAL
#define IUTEST_HAS_STD_DECLVAL 1
#endif
#ifndef IUTEST_HAS_STD_EMPLACE
#define IUTEST_HAS_STD_EMPLACE 1
#endif
#ifndef IUTEST_HAS_CXX_HDR_CHRONO
#define IUTEST_HAS_CXX_HDR_CHRONO 1
#endif
#ifndef IUTEST_HAS_CXX_HDR_REGEX
#define IUTEST_HAS_CXX_HDR_REGEX 1
#endif
#ifndef IUTEST_HAS_CXX_HDR_RANDOM
#define IUTEST_HAS_CXX_HDR_RANDOM 1
#endif
#ifndef IUTEST_HAS_CXX_HDR_CODECVT
#define IUTEST_HAS_CXX_HDR_CODECVT 1
#endif
#ifndef IUTEST_HAS_CXX_HDR_CSTDINT
#define IUTEST_HAS_CXX_HDR_CSTDINT 1
#endif
#ifndef IUTEST_HAS_CXX_HDR_ARRAY
#define IUTEST_HAS_CXX_HDR_ARRAY 1
#endif
#if !defined(IUTEST_HAS_STD_QUICK_EXIT)&&defined(_LIBCPP_HAS_QUICK_EXIT)
#define IUTEST_HAS_STD_QUICK_EXIT 1
#endif
#ifdef __has_include
#if !defined(IUTEST_HAS_CXX_HDR_CUCHAR)&&__has_include(<cuchar>)
#define IUTEST_HAS_CXX_HDR_CUCHAR 1
#endif
#if !defined(IUTEST_HAS_STD_TUPLE)&&__has_include(<tuple>)
#define IUTEST_HAS_STD_TUPLE 1
#endif
#endif
#endif
#if _LIBCPP_VERSION<9000
#define IUTEST_HAS_CXX_HDR_FILESYSTEM 0
#endif
#if _LIBCPP_VERSION>=3700
#if !defined(IUTEST_HAS_STD_INVOKE)&&IUTEST_HAS_CXX1Z
#define IUTEST_HAS_STD_INVOKE 1
#endif
#endif
#if _LIBCPP_VERSION>=1001
#ifndef IUTEST_HAS_STD_BEGIN_END
#define IUTEST_HAS_STD_BEGIN_END 1
#endif
#endif
#ifdef __has_include
#if !defined(IUTEST_HAS_STD_TUPLE)&&!defined(IUTEST_HAS_TR1_TUPLE)&&__has_include(<tr1/tuple>)
#define IUTEST_HAS_TR1_TUPLE 1
#endif
#if !defined(IUTEST_HAS_HDR_CXXABI)&&__has_include(<cxxabi.h>)
#define IUTEST_HAS_HDR_CXXABI 1
#endif
#endif
#endif
#if IUTEST_HAS_CXX1Z
#ifdef __has_include
#ifndef IUTEST_HAS_CXX_HDR_ANY
#if __has_include(<any>)
#define IUTEST_HAS_CXX_HDR_ANY 1
#endif
#endif
#ifndef IUTEST_HAS_CXX_HDR_FILESYSTEM
#if __has_include(<filesystem>)
#define IUTEST_HAS_CXX_HDR_FILESYSTEM 1
#endif
#endif
#ifndef IUTEST_HAS_CXX_HDR_OPTIONAL
#if __has_include(<optional>)
#define IUTEST_HAS_CXX_HDR_OPTIONAL 1
#endif
#endif
#ifndef IUTEST_HAS_CXX_HDR_STRING_VIEW
#if __has_include(<string_view>)
#define IUTEST_HAS_CXX_HDR_STRING_VIEW 1
#endif
#endif
#endif
#endif
#if IUTEST_HAS_CXX17
#ifndef IUTEST_HAS_CXX_HDR_VARIANT
#if IUTEST_HAS_VARIADIC_TEMPLATES&&defined(__has_include)
#if defined(__clang__)&&(__clang_major__<3 ||(__clang_major__==3 && __clang_minor__<6))
#define IUTEST_HAS_CXX_HDR_VARIANT 0
#elif __has_include(<variant>)
#define IUTEST_HAS_CXX_HDR_VARIANT 1
#endif
#endif
#endif
#endif
#ifdef __has_include
#if defined(IUTEST_HAS_CXX_HDR_CODECVT)&&IUTEST_HAS_CXX_HDR_CODECVT
#if !__has_include(<codecvt>)
#undef IUTEST_HAS_CXX_HDR_CODECVT
#endif
#endif
#endif
#ifndef IUTEST_HAS_CXX_HDR_ANY
#define IUTEST_HAS_CXX_HDR_ANY 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_ARRAY
#define IUTEST_HAS_CXX_HDR_ARRAY 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_CHRONO
#define IUTEST_HAS_CXX_HDR_CHRONO 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_CODECVT
#define IUTEST_HAS_CXX_HDR_CODECVT 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_CSTDINT
#define IUTEST_HAS_CXX_HDR_CSTDINT 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_CUCHAR
#define IUTEST_HAS_CXX_HDR_CUCHAR 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_FILESYSTEM
#define IUTEST_HAS_CXX_HDR_FILESYSTEM 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_OPTIONAL
#define IUTEST_HAS_CXX_HDR_OPTIONAL 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_RANDOM
#define IUTEST_HAS_CXX_HDR_RANDOM 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_REGEX
#define IUTEST_HAS_CXX_HDR_REGEX 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_STRING_VIEW
#define IUTEST_HAS_CXX_HDR_STRING_VIEW 0
#endif
#ifndef IUTEST_HAS_CXX_HDR_VARIANT
#define IUTEST_HAS_CXX_HDR_VARIANT 0
#endif
#ifndef IUTEST_HAS_HDR_CXXABI
#define IUTEST_HAS_HDR_CXXABI 0
#endif
#include <iterator>
#if IUTEST_HAS_CXX_HDR_ANY
#include <any>
#endif
#if IUTEST_HAS_CXX_HDR_CSTDINT
#include <cstdint>
#endif
#if IUTEST_HAS_CXX_HDR_FILESYSTEM
#include <filesystem>
#endif
#if IUTEST_HAS_CXX_HDR_OPTIONAL
#include <optional>
#endif
#if IUTEST_HAS_CXX_HDR_VARIANT
#include <variant>
#endif
#ifndef IUTEST_HAS_STD_FILESYSTEM
#if IUTEST_HAS_CXX_HDR_FILESYSTEM&&defined(__cpp_lib_filesystem)&&__cpp_lib_filesystem>=201703
#ifndef __cpp_lib_experimental_filesystem
#define IUTEST_HAS_STD_FILESYSTEM 1
#endif
#endif
#endif
#ifndef IUTEST_HAS_STD_TO_CHARS
#if defined(__cpp_lib_to_chars)&&__cpp_lib_to_chars>=201611
#define IUTEST_HAS_STD_TO_CHARS 1
#endif
#endif
#ifndef IUTEST_HAS_STD_BEGIN_END
#define IUTEST_HAS_STD_BEGIN_END 0
#endif
#ifndef IUTEST_HAS_STD_DECLVAL
#define IUTEST_HAS_STD_DECLVAL 0
#endif
#ifndef IUTEST_HAS_STD_EMPLACE
#define IUTEST_HAS_STD_EMPLACE 0
#endif
#ifndef IUTEST_HAS_STD_FILESYSTEM
#define IUTEST_HAS_STD_FILESYSTEM 0
#endif
#ifndef IUTEST_HAS_STD_INVOKE
#define IUTEST_HAS_STD_INVOKE 0
#endif
#ifndef IUTEST_HAS_STD_QUICK_EXIT
#define IUTEST_HAS_STD_QUICK_EXIT 0
#endif
#ifndef IUTEST_HAS_STD_TO_CHARS
#define IUTEST_HAS_STD_TO_CHARS 0
#endif
#ifndef IUTEST_HAS_STD_TUPLE
#define IUTEST_HAS_STD_TUPLE 0
#endif
#ifndef IUTEST_HAS_TR1_TUPLE
#define IUTEST_HAS_TR1_TUPLE 0
#endif
#if IUTEST_HAS_STD_TUPLE||IUTEST_HAS_TR1_TUPLE||IUTEST_USE_EXTERNAL_TR1_TUPLE||IUTEST_USE_EXTERNAL_STD_TUPLE
#ifndef IUTEST_HAS_TUPLE
#define IUTEST_HAS_TUPLE 1
#endif
#else
#ifdef IUTEST_HAS_TUPLE
#undef IUTEST_HAS_TUPLE
#endif
#define IUTEST_HAS_TUPLE 0
#endif
#if !defined(IUTEST_HAS_VARIADIC_TUPLES)&&IUTEST_HAS_VARIADIC_TEMPLATES&&IUTEST_HAS_TUPLE&&IUTEST_HAS_STD_TUPLE
#ifdef __clang__
#if(__clang_major__>3 ||(__clang_major__==3 && __clang_minor__>7))
#define IUTEST_HAS_VARIADIC_TUPLES 1
#endif
#else
#define IUTEST_HAS_VARIADIC_TUPLES 1
#endif
#endif
#ifndef IUTEST_HAS_VARIADIC_TUPLES
#define IUTEST_HAS_VARIADIC_TUPLES 0
#endif
#ifndef IUTEST_HAS_STD_STR_TO_VALUE
#if IUTEST_HAS_CXX11
#define IUTEST_HAS_STD_STR_TO_VALUE 1
#endif
#endif
#ifndef IUTEST_HAS_STD_STR_TO_VALUE
#define IUTEST_HAS_STD_STR_TO_VALUE 0
#endif
#ifndef IUTEST_USING_BEGIN_END
#if IUTEST_HAS_STD_BEGIN_END
#define IUTEST_USING_BEGIN_END() using ::std::begin;using ::std::end
#else
#define IUTEST_USING_BEGIN_END() using ::iutest::detail::cxx::begin;using ::iutest::detail::cxx::end
#endif
#endif
namespace iutest{namespace detail{namespace cxx{
#if IUTEST_HAS_STD_BEGIN_END
using ::std::begin;using ::std::end;
#else
template<typename T> typename T::iterator begin(T& x){return x.begin();}template<typename T> typename T::iterator end(T& x){return x.end();}template<typename T> typename T::const_iterator begin(const T& x){return x.begin();}template<typename T> typename T::const_iterator end(const T& x){return x.end();}template<typename T,size_t SIZE> T* begin(T(&x)[SIZE]){return &x[0];}template<typename T,size_t SIZE> T* end(T(&x)[SIZE]){return begin(x)+SIZE;}template<typename T,size_t SIZE> const T* begin(const T(&x)[SIZE]){return &x[0];}template<typename T,size_t SIZE> const T* end(const T(&x)[SIZE]){return begin(x)+SIZE;}
#endif
}}}
#if IUTEST_HAS_TUPLE
#if IUTEST_HAS_STD_TUPLE
#include <tuple>
#elif IUTEST_HAS_TR1_TUPLE
#if(defined(__GNUC__)&&(__GNUC__>=4))
#include <tr1/tuple>
#endif
#endif
namespace iutest{namespace tuples{
#if IUTEST_HAS_STD_TUPLE
namespace alias=::std;
#elif IUTEST_HAS_TR1_TUPLE
namespace alias=::std::tr1;
#endif
using alias::tuple;using alias::tuple_element;using alias::make_tuple;using alias::get;template<typename T>struct tuple_size:public alias::tuple_size<T>{};template<typename T>struct tuple_size<const T>:public alias::tuple_size<T>{};template<typename T>struct tuple_size<volatile T>:public alias::tuple_size<T>{};template<typename T>struct tuple_size<const volatile T>:public alias::tuple_size<T>{};namespace detail{template<typename T,typename F,int Begin>struct tuple_foreach_impl{template<int N,int I>struct impl{static void do_something(T& t,F fn){fn(I,get<I>(t));impl<N,I+1>::do_something(t,fn);}};template<int N>struct impl<N,N>{static void do_something(T&,F){}};static void do_something(T& t,F fn){impl<tuple_size<T>::value,Begin>::do_something(t,fn);}};template<typename T,typename U>struct tuple_cast_copy_impl{template<int N,int I>struct impl{static void copy(T& dst,const U& src){get<I>(dst)=static_cast<typename tuple_element<I,T>::type>(get<I>(src));impl<N,I+1>::copy(dst,src);}};template<int N>struct impl<N,N>{static void copy(T&,const U&){}};static void copy(T& dst,const U& src){impl<tuple_size<T>::value,0>::copy(dst,src);}};}template<int I,typename tuple_t,typename F>void tuple_foreach(tuple_t& t,F& fn){detail::tuple_foreach_impl<tuple_t,F&,I>::do_something(t,fn);}template<typename tuple_t,typename F>void tuple_foreach(tuple_t& t,F& fn){tuple_foreach<0>(t,fn);}template<int I,typename tuple_t,typename F>void tuple_foreach(tuple_t& t,const F& fn){detail::tuple_foreach_impl<tuple_t,const F&,I>::do_something(t,fn);}template<typename tuple_t,typename F>void tuple_foreach(tuple_t& t,const F& fn){tuple_foreach<0>(t,fn);}template<typename T,typename U>void tuple_cast_copy(T& dst,const U& src){detail::tuple_cast_copy_impl<T,U>::copy(dst,src);}}using tuples::tuple;using tuples::tuple_size;using tuples::tuple_element;using tuples::tuple_foreach;using tuples::make_tuple;using tuples::get;}
#endif
#ifndef IUPRzu
#define IUPRzu "zu"
#endif
#ifndef iu_va_copy
#ifdef va_copy
#define iu_va_copy va_copy
#elif defined(__GNUC__)||defined(__clang__)
#define iu_va_copy(dest,src) __builtin_va_copy(dest,src)
#else
#define iu_va_copy(dest,src) (dest=src)
#endif
#endif
namespace iutest{namespace detail{template<int SIZE>struct type_least_t{};template<>struct type_least_t<1>{
#ifdef INT_LEAST8_MIN
typedef int_least8_t Int;typedef uint_least8_t UInt;
#else
typedef char Int;typedef unsigned char UInt;
#endif
};template<>struct type_least_t<2>{
#ifdef INT_LEAST16_MIN
typedef int_least16_t Int;typedef uint_least16_t UInt;
#else
typedef short Int;typedef unsigned short UInt;
#endif
};template<>struct type_least_t<4>{
#ifdef INT_LEAST32_MIN
typedef int_least32_t Int;typedef uint_least32_t UInt;
#else
typedef int Int;typedef unsigned int UInt;
#endif
};template<>struct type_least_t<8>{
#ifdef INT_LEAST64_MIN
typedef int_least64_t Int;typedef uint_least64_t UInt;
#else
typedef long long Int;typedef unsigned long long UInt;
#endif
};template<size_t SIZE>struct type_fit_t{};template<>struct type_fit_t<1>{
#ifdef INT8_MIN
typedef int8_t Int;typedef uint8_t UInt;
#else
typedef char Int;typedef unsigned char UInt;
#endif
};template<>struct type_fit_t<2>{
#ifdef INT16_MIN
typedef int16_t Int;typedef uint16_t UInt;
#else
typedef short Int;typedef unsigned short UInt;
#endif
};template<>struct type_fit_t<4>{
#ifdef INT32_MIN
typedef int32_t Int;typedef uint32_t UInt;
#else
private: template<typename T,typename F,bool b>struct impl{typedef T type;};template<typename T,typename F>struct impl<T,F,false>{typedef F type;};public: typedef impl<long,int,sizeof(int)!=4&&sizeof(long)==4>::type Int;typedef impl<unsigned long,unsigned int,sizeof(int)!=4&&sizeof(long)==4>::type UInt;
#endif
};template<>struct type_fit_t<8>{
#ifdef INT64_MIN
typedef int64_t Int;typedef uint64_t UInt;
#else
typedef long long Int;typedef unsigned long long UInt;
#endif
};template<>struct type_fit_t<16>{
#if IUTEST_HAS_INT128
typedef __int128_t Int;typedef __uint128_t UInt;
#endif
};inline int iu_mbtowc(wchar_t* dst,const char* src,size_t size){return mbtowc(dst,src,size);}}}
#define IUTEST_HAS_LIB 0
#define IUTEST_HAS_PARAM_TEST 1
#define IUTEST_HAS_TYPED_TEST 1
#define IUTEST_HAS_TYPED_TEST_P 1
#define IUTEST_TYPED_TEST_P_STRICT 1
#define IUTEST_HAS_MATCHERS 1
#define IUTEST_HAS_VALUESGEN 1
#define IUTEST_HAS_RANDOMVALUES 1
#define IUTEST_HAS_CONCAT 1
#define IUTEST_HAS_CSVPARAMS 1
#define IUTEST_HAS_TESTNAME_ALIAS_JP 0
#define IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE 1
#define IUTEST_HAS_AUTOFIXTURE_PARAM_TEST 1
#define IUTEST_HAS_ANY_PARAM_TEST 1
#define IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR 1
#define IUTEST_HAS_IF_EXISTS 0
#define IUTEST_HAS_ANALYSIS_ASSUME 0
#define IUTEST_HAS_IGNORE_TEST 0
#define IUTEST_HAS_MINIDUMP 0
#define IUTEST_HAS_STRSTREAM 0
#define IUTEST_HAS_STRINGSTREAM 1
#define IUTEST_HAS_IOMANIP 1
#define IUTEST_HAS_CTIME 1
#define IUTEST_HAS_GETTIMEOFDAY 1
#define IUTEST_HAS_HDR_SYSTIME 1
#define IUTEST_HAS_FOPEN 1
#define IUTEST_HAS_FILE_STAT 1
#define IUTEST_HAS_CLASS_MEMBER_TEMPLATE_SPECIALIZATION 0
#define IUTEST_HAS_GENERIC 0
#define IUTEST_HAS_MEMORY_SANITIZER 0
#define IUTEST_HAS_ADDRESS_SANITIZER 0
#define IUTEST_HAS_THREAD_SANITIZER 0
#define IUTEST_HAS_SEH 0
#define IUTEST_USE_OWN_LIST 0
#define IUTEST_HAS_MATCHER_FLOATINGPOINT_NEAR 1
#define IUTEST_HAS_MATCHER_EACH 1
#define IUTEST_HAS_MATCHER_POINTWISE 1
#define IUTEST_HAS_GENRAND 1
#define IUTEST_HAS_PACKAGE 1
#define IUTEST_HAS_PEEP 1
#define IUTEST_HAS_SOCKET 1
#define IUTEST_HAS_PRINT_TO 1
#define IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE 1
#define IUTEST_HAS_STATIC_ASSERT_TYPEEQ 1
#define IUTEST_HAS_ASSERTION_RETURN 1
#define IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT 1
#define IUTEST_HAS_TESTNAME_ALIAS 1
#define IUTEST_HAS_REPORT_SKIPPED 1
#define IUTEST_HAS_STREAM_BUFFER 1
#define IUTEST_HAS_BIGGESTINT_OSTREAM 1
#define IUTEST_CHECK_STRICT 1
#define IUTEST_HAS_COLORCONSOLE 0
#ifndef IUTEST_VPRINTF
#define IUTEST_VPRINTF(f,a) vprintf(f,a)
#endif
#ifndef IUTEST_HAS_PARAM_METHOD_TEST
#define IUTEST_HAS_PARAM_METHOD_TEST 1
#endif
#ifndef IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE
#if IUTEST_HAS_DECLTYPE
#define IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE 1
#else
#define IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE 0
#endif
#endif
#ifndef IUTEST_HAS_COMBINE
#if IUTEST_HAS_PARAM_TEST&&IUTEST_HAS_TUPLE
#define IUTEST_HAS_COMBINE 1
#endif
#else
#if IUTEST_HAS_COMBINE&&!IUTEST_HAS_TUPLE
#undef IUTEST_HAS_COMBINE
#endif
#endif
#ifndef IUTEST_HAS_COMBINE
#define IUTEST_HAS_COMBINE 0
#endif
#ifndef IUTEST_HAS_PAIRWISE
#if IUTEST_HAS_PARAM_TEST&&IUTEST_HAS_TUPLE
#define IUTEST_HAS_PAIRWISE 1
#endif
#else
#if IUTEST_HAS_PAIRWISE&&!IUTEST_HAS_TUPLE
#undef IUTEST_HAS_PAIRWISE
#endif
#endif
#ifndef IUTEST_HAS_PAIRWISE
#define IUTEST_HAS_PAIRWISE 0
#endif
#ifndef IUTEST_HAS_VARIADIC_VALUES
#if IUTEST_HAS_PARAM_TEST&&IUTEST_HAS_VARIADIC_TEMPLATES&&IUTEST_HAS_VARIADIC_TUPLES
#define IUTEST_HAS_VARIADIC_VALUES 1
#else
#define IUTEST_HAS_VARIADIC_VALUES 0
#endif
#endif
#ifndef IUTEST_HAS_VARIADIC_COMBINE
#if IUTEST_HAS_COMBINE&&IUTEST_HAS_VARIADIC_TEMPLATES&&IUTEST_HAS_VARIADIC_TUPLES
#define IUTEST_HAS_VARIADIC_COMBINE 1
#else
#define IUTEST_HAS_VARIADIC_COMBINE 0
#endif
#endif
#ifndef IUTEST_HAS_VARIADIC_PAIRWISE
#if IUTEST_HAS_PAIRWISE&&IUTEST_HAS_VARIADIC_TEMPLATES&&IUTEST_HAS_VARIADIC_TUPLES
#define IUTEST_HAS_VARIADIC_PAIRWISE 1
#else
#define IUTEST_HAS_VARIADIC_PAIRWISE 0
#endif
#endif
#ifndef IUTEST_HAS_MATCHER_ELEMENTSARE
#if IUTEST_HAS_TUPLE
#define IUTEST_HAS_MATCHER_ELEMENTSARE IUTEST_HAS_MATCHERS
#else
#define IUTEST_HAS_MATCHER_ELEMENTSARE 0
#endif
#endif
#ifndef IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD
#if IUTEST_HAS_TUPLE
#define IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD IUTEST_HAS_MATCHERS
#else
#define IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD 0
#endif
#endif
#ifndef IUTEST_HAS_REGEX
#if IUTEST_HAS_CXX_HDR_REGEX
#define IUTEST_HAS_REGEX 1
#else
#define IUTEST_HAS_REGEX 0
#endif
#endif
#ifndef IUTEST_HAS_MATCHER_VARIADIC
#define IUTEST_HAS_MATCHER_VARIADIC IUTEST_HAS_VARIADIC_TEMPLATES
#endif
#ifndef IUTEST_HAS_MATCHER_REGEX
#if IUTEST_HAS_CXX_HDR_REGEX&&IUTEST_HAS_REGEX
#define IUTEST_HAS_MATCHER_REGEX IUTEST_HAS_MATCHERS
#else
#define IUTEST_HAS_MATCHER_REGEX 0
#endif
#endif
#ifndef IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF
#if IUTEST_HAS_TUPLE
#define IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF IUTEST_HAS_MATCHERS
#else
#define IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF 0
#endif
#endif
#ifndef IUTEST_USE_THROW_ON_ASSERTION_FAILURE
#ifdef IUTEST_USE_THROW_ON_ASSERT_FAILURE
#define IUTEST_USE_THROW_ON_ASSERTION_FAILURE IUTEST_USE_THROW_ON_ASSERT_FAILURE
#else
#define IUTEST_USE_THROW_ON_ASSERTION_FAILURE 0
#endif
#endif
#if !IUTEST_HAS_EXCEPTIONS&&IUTEST_USE_THROW_ON_ASSERTION_FAILURE
#undef IUTEST_USE_THROW_ON_ASSERTION_FAILURE
#define IUTEST_USE_THROW_ON_ASSERTION_FAILURE 0
#endif
#ifndef IUTEST_HAS_LAMBDA_STATEMENTS
#if IUTEST_HAS_LAMBDA
#define IUTEST_HAS_LAMBDA_STATEMENTS 1
#else
#define IUTEST_HAS_LAMBDA_STATEMENTS 0
#endif
#endif
#ifndef IUTEST_HAS_SPI_LAMBDA_SUPPORT
#define IUTEST_HAS_SPI_LAMBDA_SUPPORT IUTEST_HAS_LAMBDA_STATEMENTS
#endif
#ifndef IUTEST_HAS_PEEP_FUNC
#define IUTEST_HAS_PEEP_FUNC IUTEST_HAS_PEEP
#endif
#ifndef IUTEST_HAS_PEEP_STATIC_FUNC
#define IUTEST_HAS_PEEP_STATIC_FUNC IUTEST_HAS_PEEP
#endif
#ifndef IUTEST_HAS_PEEP_CLASS
#define IUTEST_HAS_PEEP_CLASS IUTEST_HAS_PEEP
#endif
#ifndef IUTEST_HAS_VARIADIC_PRED
#if IUTEST_HAS_VARIADIC_TEMPLATES
#define IUTEST_HAS_VARIADIC_PRED 1
#else
#define IUTEST_HAS_VARIADIC_PRED 0
#endif
#endif
#ifndef IUTEST_TYPED_TEST_APPEND_TYPENAME
#define IUTEST_TYPED_TEST_APPEND_TYPENAME 0
#endif
#ifndef IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME
#define IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME IUTEST_TYPED_TEST_APPEND_TYPENAME
#endif
#ifndef IUTEST_HAS_LONG_DOUBLE
#if IUTEST_HAS_INT128
#define IUTEST_HAS_LONG_DOUBLE 1
#elif defined(__SIZEOF_FLOAT128__)&&(__SIZEOF_FLOAT128__<=8)
#define IUTEST_HAS_LONG_DOUBLE 1
#endif
#endif
#ifndef IUTEST_HAS_LONG_DOUBLE
#define IUTEST_HAS_LONG_DOUBLE 0
#endif
#ifndef IUTEST_HAS_FILENO
#define IUTEST_HAS_FILENO 0
#endif
#ifndef IUTEST_HAS_CLOCK
#ifdef CLOCKS_PER_SEC
#define IUTEST_HAS_CLOCK 1
#endif
#endif
#ifndef IUTEST_HAS_CLOCK
#define IUTEST_HAS_CLOCK 0
#endif
#ifndef IUTEST_HAS_CHAR16_T_PRINTABLE
#if IUTEST_HAS_CXX_HDR_CODECVT||IUTEST_HAS_CXX_HDR_CUCHAR
#define IUTEST_HAS_CHAR16_T_PRINTABLE IUTEST_HAS_CHAR16_T
#endif
#endif
#ifndef IUTEST_HAS_CHAR16_T_PRINTABLE
#define IUTEST_HAS_CHAR16_T_PRINTABLE 0
#endif
#ifndef IUTEST_HAS_CHAR32_T_PRINTABLE
#if IUTEST_HAS_CXX_HDR_CODECVT||IUTEST_HAS_CXX_HDR_CUCHAR
#define IUTEST_HAS_CHAR32_T_PRINTABLE IUTEST_HAS_CHAR32_T
#endif
#endif
#ifndef IUTEST_HAS_CHAR32_T_PRINTABLE
#define IUTEST_HAS_CHAR32_T_PRINTABLE 0
#endif
#ifndef IUTEST_USE_OWN_STRING_VIEW
#if !IUTEST_HAS_CXX_HDR_STRING_VIEW
#define IUTEST_USE_OWN_STRING_VIEW 1
#endif
#endif
#ifndef IUTEST_USE_OWN_STRING_VIEW
#define IUTEST_USE_OWN_STRING_VIEW 0
#endif
#ifndef IUTEST_HAS_STREAM_RESULT
#define IUTEST_HAS_STREAM_RESULT 1
#endif
#include <stdio.h>
#include <vector>
#include <algorithm>
namespace iutest{namespace detail{static void II_ATR_U iuDebugInitialize(){}static void II_ATR_U iuDebugBreakAlloc(long n){(void)n;}}}namespace iutest{namespace detail{}}
#include <set>
namespace iutest{namespace internal{typedef void* TypeId;namespace helper{template<typename T>struct TestTypeIdHelper{public: static bool _dmy;};template<typename T>bool TestTypeIdHelper<T>::_dmy=false;}template<typename T>inline TypeId GetTypeId(){return &(helper::TestTypeIdHelper<T>::_dmy);}inline II_CXX_CE TypeId GetTestTypeId(){return 0;}template<size_t SIZE>struct TypeWithSize:public detail::type_fit_t<SIZE>{};}namespace detail{template<typename T>struct ieee754_bits{};template<>struct ieee754_bits<float>{enum{EXP=8,FRAC=23};};template<>struct ieee754_bits<double>{enum{EXP=11,FRAC=52};};
#if IUTEST_HAS_LONG_DOUBLE
template<size_t N>struct ieee754_bits_longdouble{};template<>struct ieee754_bits_longdouble<8u>{enum{EXP=11,FRAC=52};};template<>struct ieee754_bits_longdouble<16u>{enum{EXP=15,FRAC=64};};template<>struct ieee754_bits<long double>:ieee754_bits_longdouble<sizeof(long double)>{};
#endif
}template<typename RawType>class floating_point{private: typedef floating_point<RawType> _Myt;private: typedef typename detail::type_fit_t<sizeof(RawType)> type;typedef typename type::Int Int;typedef typename type::UInt UInt;union FInt{Int iv;UInt uv;RawType fv;};public: floating_point(){m_v.uv=0;}floating_point(RawType f){m_v.uv=0;m_v.fv=f;}floating_point(const floating_point& rhs):m_v(rhs.m_v){}public: bool AlmostEquals(const _Myt& rhs)const{if(is_nan()||rhs.is_nan()){return false;}return NanSensitiveAlmostEquals(rhs);}bool NanSensitiveAlmostEquals(const _Myt& rhs)const{const UInt v1=norm(bits());const UInt v2=norm(rhs.bits());const UInt diff=(v1>v2)?v1-v2:v2-v1;if(diff<=kMaxUlps){return true;}return false;}public: bool AlmostNear(const _Myt& rhs,RawType max_abs_error)const{if(is_nan()||rhs.is_nan()){return false;}II_PGM_W_PU()II_PGM_W_FE()if(m_v.fv==rhs.m_v.fv){return true;}II_PGM_W_PP()_Myt abs=Abs(rhs);if(abs.m_v.fv<=max_abs_error){return true;}_Myt abs_error=_Myt(max_abs_error);if(abs.AlmostEquals(abs_error)){return true;}return false;}bool NanSensitiveAlmostNear(const _Myt& rhs,RawType max_abs_error)const{if(is_nan()&&rhs.is_nan()){return true;}return AlmostNear(rhs,max_abs_error);}public: _Myt Abs(const _Myt& rhs)const{if(m_v.fv>rhs.m_v.fv){return _Myt(m_v.fv-rhs.m_v.fv);}else{return _Myt(rhs.m_v.fv-m_v.fv);}}public: UInt bits()const{return m_v.uv&kEnableBitMask;}RawType raw()const{return m_v.fv;}UInt exponent_bits()const{return m_v.uv&kExpMask;}UInt fraction_bits()const{return m_v.uv&kFracMask;}UInt sign_bit()const{return m_v.uv&kSignMask;}bool is_nan()const{return exponent_bits()==kExpMask&&fraction_bits()!=0;}bool is_inf()const{return exponent_bits()==kExpMask&&fraction_bits()==0;}public: static _Myt PINF(){_Myt f;f.m_v.uv=kExpMask;return f;}static _Myt NINF(){_Myt f=PINF();f.m_v.uv|=kSignMask;return f;}static _Myt PNAN(){_Myt f;f.m_v.uv=kExpMask|1;return f;}static _Myt NNAN(){_Myt f=PNAN();f.m_v.uv|=kSignMask;return f;}static _Myt PQNAN(){_Myt f;f.m_v.uv=((1<<(kEXP+1))-1);f.m_v.uv<<=kFRAC-1;return f;}static _Myt NQNAN(){_Myt f=PQNAN();f.m_v.uv|=kSignMask;return f;}public:operator RawType()const{return m_v.fv;}_Myt& operator=(RawType f){m_v.fv=f;return *this;}_Myt& operator=(const _Myt& rhs){m_v.fv=rhs.m_v;return *this;}bool operator==(const _Myt& rhs)const{return m_v.uv==rhs.m_v.uv;}private: enum{kEXP=detail::ieee754_bits<RawType>::EXP,kFRAC=detail::ieee754_bits<RawType>::FRAC,kMaxUlps=4};private: static UInt norm(UInt v){return(v&kSignMask)?(~v+1) :(v|kSignMask);}static const UInt kSignMask=static_cast<UInt>(1u)<<(kEXP+kFRAC);static const UInt kExpMask=((static_cast<UInt>(1u)<<kEXP)-1)<<kFRAC;static const UInt kFracMask=(static_cast<UInt>(1u)<<kFRAC)-1;static const UInt kEnableBitMask=kSignMask|kExpMask|kFracMask;private: FInt m_v;};typedef detail::type_fit_t<1>::Int Int8;typedef detail::type_fit_t<1>::UInt UInt8;typedef detail::type_fit_t<2>::Int Int16;typedef detail::type_fit_t<2>::UInt UInt16;typedef detail::type_fit_t<4>::Int Int32;typedef detail::type_fit_t<4>::UInt UInt32;typedef detail::type_fit_t<8>::Int Int64;typedef detail::type_fit_t<8>::UInt UInt64;
#if IUTEST_HAS_CXX11&&IUTEST_HAS_CXX_HDR_CSTDINT
typedef ::std::uintmax_t iu_off_t;
#else
typedef UInt64 iu_off_t;
#endif
#if IUTEST_HAS_CXX11&&IUTEST_HAS_CXX_HDR_CSTDINT
typedef ::std::uintptr_t iu_uintptr_t;
#else
typedef detail::type_fit_t<sizeof(ptrdiff_t)>::UInt iu_uintptr_t;
#endif
typedef internal::TypeId TestTypeId;typedef void(*SetUpMethod)();typedef void(*TearDownMethod)();typedef detail::type_least_t<8>::UInt TimeInMillisec;typedef detail::type_least_t<8>::Int BiggestInt;}
#include <wchar.h>
#include <wctype.h>
#include <stdarg.h>
#include <errno.h>
#include <string>
#include <cstring>
#include <cmath>
namespace iutest{namespace detail{::std::string StringFormat(const char* format,...) II_ATR_F_P(1,2);::std::string StringFormat(const char* format,va_list va) II_ATR_F_P(1,0);namespace wrapper{inline int iu_mbicmp(char l,char r){const int ul=static_cast<int>(static_cast<unsigned char>(toupper(l)));const int ur=static_cast<int>(static_cast<unsigned char>(toupper(r)));return ul-ur;}inline int iu_stricmp(const char* str1,const char* str2){const char* l=str1;const char* r=str2;while(*l){const int ret=iu_mbicmp(*l,*r);if(ret!=0){return ret;}++l;++r;}return iu_mbicmp(*l,*r);}inline int iu_wcicmp(wchar_t l,wchar_t r){const ::std::wint_t ul=towupper(l);const ::std::wint_t ur=towupper(r);return ul-ur;}inline int iu_wcsicmp(const wchar_t * str1,const wchar_t * str2){const wchar_t* l=str1;const wchar_t* r=str2;while(*l){const int ret=iu_wcicmp(*l,*r);if(ret!=0){return ret;}++l;++r;}return iu_wcicmp(*l,*r);}}inline int iu_stricmp(const char* str1,const char* str2){return strcasecmp(str1,str2);}inline int iu_wcsicmp(const wchar_t * str1,const wchar_t * str2){return wcscasecmp(str1,str2);}namespace wrapper{int iu_vsnprintf(char* dst,size_t size,const char* format,va_list va) II_ATR_F_P(3,0);inline int iu_vsnprintf(char* dst,size_t size,const char* format,va_list va){char buffer[4096]={0};char* write_buffer=dst!=0&&size>=4096?dst:buffer;const int ret=vsprintf(write_buffer,format,va);if(dst!=0){const size_t length=static_cast<size_t>(ret);const size_t write=(size<=length)?size-1:length;if(write_buffer==buffer){strncpy(dst,buffer,write);}dst[write]='\0';}return ret;}}int iu_vsnprintf(char* dst,size_t size,const char* format,va_list va) II_ATR_F_P(3,0);int iu_snprintf(char* dst,size_t size,const char* format,...) II_ATR_F_P(3,4);inline int iu_vsnprintf(char* dst,size_t size,const char* format,va_list va){if(dst==0&&size>0){return -1;}return vsnprintf(dst,size,format,va);}inline int iu_snprintf(char* dst,size_t size,const char* format,...){va_list va;va_start(va,format);const int ret=iu_vsnprintf(dst,size,format,va);va_end(va);return ret;}inline bool IsEmpty(const char* p){return p==0||*p=='\0';}inline II_CXX_CE bool IsSpace(char ch){return ch==' ' || ch=='\t';}inline const char* NullableString(const char* str){return str==0?"":str;}inline II_CXX_CE const char* SkipSpace(const char* p){return p==0?0 :(IsSpace(*p)?SkipSpace(++p):p);}inline II_CXX_CE const char* FindComma(const char* p){return(p==0||*p=='\0')?0 :((*p==',')?p:FindComma(++p));}inline bool IsStringEqual(const char* str1,const char* str2){return strcmp(str1,str2)==0;}inline bool IsStringEqual(const ::std::string& str1,const char* str2){return str1.compare(str2)==0;}inline bool IsStringEqual(const ::std::string& str1,const ::std::string& str2){return str1.compare(str2)==0;}inline bool IsStringCaseEqual(const char* str1,const char* str2){return iu_stricmp(str1,str2)==0;}inline bool IsStringCaseEqual(const ::std::string& str1,const char* str2){return iu_stricmp(str1.c_str(),str2)==0;}inline bool IsStringCaseEqual(const ::std::string& str1,const ::std::string& str2){return iu_stricmp(str1.c_str(),str2.c_str())==0;}inline bool IsStringForwardMatching(const char* str1,const char* str2){return strstr(str1,str2)==str1;}inline bool IsStringForwardMatching(const ::std::string& str1,const char* str2){return str1.find(str2)==0;}inline bool IsStringForwardMatching(const ::std::string& str1,const std::string& str2){return str1.find(str2)==0;}inline bool IsStringContains(const char* str1,const char* str2){return strstr(str1,str2)!=0;}inline bool IsStringContains(const ::std::string& str1,const char* str2){return str1.find(str2)!=::std::string::npos;}inline bool IsStringContains(const ::std::string& str1,const ::std::string& str2){return str1.find(str2)!=::std::string::npos;}inline void StringReplace(::std::string& str,const char* from,size_t n,const char* to){::std::string::size_type pos=0;while(static_cast<void>(pos=str.find(from,pos)),pos!=::std::string::npos){str.replace(pos,n,to);++pos;}}inline void StringReplace(::std::string& str,char a,const char* to){char s[]={a,0};return StringReplace(str,s,1,to);}inline ::std::string StripLeadingSpace(const ::std::string& str){::std::string::const_iterator it=str.begin();while(it!=str.end()&&IsSpace(*it)){++it;}return ::std::string(it,str.end());}inline ::std::string StripTrailingSpace(const ::std::string& str){::std::string::const_iterator it=str.end()-1;while(it!=str.begin()&&IsSpace(*it)){--it;}return ::std::string(str.begin(),it+1);}inline ::std::string StripSpace(const ::std::string& str){::std::string::const_iterator start=str.begin();while(start!=str.end()&&IsSpace(*start)){++start;}::std::string::const_iterator end=str.end()-1;while(end!=str.begin()&&IsSpace(*end)){--end;}return ::std::string(start,end+1);}inline bool StringIsBlank(const ::std::string& str){::std::string::const_iterator it=str.begin();while(it!=str.end()){const char ch=*it;if(!IsSpace(ch)&&ch!='\r' && ch!='\n'){return false;}++it;}return true;}inline void StringReplaceToLF(::std::string& str){StringReplace(str,"\r\n",2,"\n");StringReplace(str,"\r",1,"\n");}inline ::std::string StringRemoveComment(const ::std::string& str){::std::string r;::std::string::size_type prev=0;::std::string::size_type pos=str.find('\n',0);while(pos!=::std::string::npos){++pos;if(str[prev]!='#'){r+=str.substr(prev,pos-prev);}prev=pos;pos=str.find('\n',pos);}if(str[prev]!='#'){r+=str.substr(prev);}return r;}inline void StringSplit(const ::std::string& str,char delimiter,::std::vector< ::std::string>&dst){::std::string::size_type prev=0;::std::string::size_type pos=0;::std::vector< ::std::string>parsed;while(static_cast<void>(pos=str.find(delimiter,prev)),pos!=::std::string::npos){parsed.push_back(str.substr(prev,pos-prev));++pos;prev=pos;}parsed.push_back(str.substr(prev));dst.swap(parsed);}template<typename T>inline ::std::string ToOctString(T value){const size_t kB=sizeof(T) * 8;const size_t kN=(kB+2) / 3;const size_t kD=kB-(kN-1) * 3;const size_t kMask=(1u<<kD)-1u;const T head=(value>>((kN-1) * 3))&kMask;char buf[kN+1]={static_cast<char>('0' +(head&7)),0};for(size_t i=1;i<kN;++i){const T n=(value>>((kN-i - 1) * 3));buf[i]=static_cast<char>('0' +(n&7));}buf[kN]='\0';return buf;}inline II_CXX_CE char ToHex(unsigned int n){return static_cast<char>((n&0xF)>=0xA?'A'+((n&0xF)-0xA) : '0'+(n&0xF));}template<typename T>inline ::std::string ToHexString(T value){const size_t kN=sizeof(T)*2;char buf[kN+1]={0};for(size_t i=0;i<kN;++i){buf[i]=ToHex(static_cast<unsigned int>((value>>((kN-i-1)*4))));}buf[kN]='\0';return buf;}template<typename T>inline ::std::string ToHexString(const T* str,int length){::std::string r;for(int i=0;(length<0 || i<length)&&*str!=0;++str,++i){r+=ToHexString(*str);}return r;}inline ::std::string FormatIntWidth2(int value){char buf[3]="00";buf[0]=static_cast<char>((value/10)%10+'0');buf[1]=static_cast<char>((value)%10+'0');return buf;}
#if IUTEST_HAS_STD_TO_CHARS
template<typename T>::std::string iu_to_string(const T& value){const size_t kN=128;char buf[kN]={0};const ::std::to_chars_result r=::std::to_chars(buf,buf+kN,value);*r.ptr='\0';return buf;}
#else
#define II_DECL_TOSTRING(fmt_,type_) inline ::std::string iu_to_string(type_ value){char buf[128]={0};iu_snprintf(buf,sizeof(buf),fmt_,value);return buf;}
II_DECL_TOSTRING("%d",int)II_DECL_TOSTRING("%u",unsigned int)II_DECL_TOSTRING("%ld",long)II_DECL_TOSTRING("%lu",unsigned long)II_DECL_TOSTRING("%lld",long long)II_DECL_TOSTRING("%llu",unsigned long long)
#undef II_DECL_TOSTRING
#endif
inline ::std::string FormatSizeByte(UInt64 value){const char* suffixes[]={"B","KB","MB","GB","TB",};const size_t suffixes_length=IUTEST_PP_COUNTOF(suffixes);size_t index=0;double view_value=static_cast<double>(value);while(view_value>=1024&&index+1 <suffixes_length){++index;view_value/=1024;}const UInt32 n=static_cast<UInt32>(::std::floor(view_value));const UInt32 f=static_cast<UInt32>(view_value * 10.0-n * 10.0);const char* suffix=suffixes[index];if(view_value-n<=0.0){return iu_to_string(n)+suffix;}else{return iu_to_string(n)+"." + iu_to_string(f)+suffix;}}inline ::std::string ShowStringQuoted(const char* str){::std::string s="\"";s+=str;s+="\"";return s;}inline ::std::string ShowStringQuoted(const ::std::string& str){::std::string s="\"";s+=str;s+="\"";return s;}inline ::std::string StringFormat(const char* format,...){va_list va;va_start(va,format);::std::string str=StringFormat(format,va);va_end(va);return str;}inline ::std::string StringFormat(const char* format,va_list va){size_t n=strlen(format) * 2+1;{va_list va2;iu_va_copy(va2,va);const size_t ret=iu_vsnprintf(0,0,format,va2);va_end(va2);if(ret>0){n=ret+1;}}for(;;){char* dst=new char[n];va_list va2;iu_va_copy(va2,va);const int written=iu_vsnprintf(dst,n,format,va2);va_end(va2);if(written<0){
#ifdef EOVERFLOW
if(errno==EOVERFLOW){break;}
#endif
#ifdef E2BIG
if(errno==E2BIG){break;}
#endif
}else if(static_cast<size_t>(written)<n){::std::string s=::std::string(dst,static_cast<size_t>(written));delete[] dst;return s;}delete[] dst;n*=2;}return "";}}}
#include <sstream>
#include <iomanip>
#if IUTEST_HAS_EXCEPTIONS
#include <stdexcept>
#endif
namespace iutest{namespace detail{template<typename T>bool StringToValue(const ::std::string& s,T& out){::std::istringstream strm(s);if(strm>>out){return true;}return false;}inline bool StringToValue(const ::std::string& s,float& out){
#if IUTEST_HAS_STD_STR_TO_VALUE
out=::std::stof(s);
#else
char* endptr=0;const char* p=s.c_str();errno=0;const floating_point<float> v=strtof(p,&endptr);
#if IUTEST_HAS_EXCEPTIONS
if(p==endptr){throw ::std::invalid_argument(p);}if((errno==ERANGE)||v.is_inf()){throw ::std::out_of_range(p);}
#endif
out=v;
#endif
return true;}inline bool StringToValue(const ::std::string& s,double& out){
#if IUTEST_HAS_STD_STR_TO_VALUE
out=::std::stod(s);
#else
char* endptr=0;const char* p=s.c_str();errno=0;const floating_point<double> v=strtod(s.c_str(),&endptr);
#if IUTEST_HAS_EXCEPTIONS
if(p==endptr){throw ::std::invalid_argument(p);}if((errno==ERANGE)||v.is_inf()){throw ::std::out_of_range(p);}
#endif
out=v;
#endif
return true;}
#if IUTEST_HAS_LONG_DOUBLE
inline bool StringToValue(const ::std::string& s,long double& out){
#if IUTEST_HAS_STD_STR_TO_VALUE
out=::std::stold(s);
#else
char* endptr=0;const char* p=s.c_str();errno=0;const floating_point<long double> v=strtold(s.c_str(),&endptr);
#if IUTEST_HAS_EXCEPTIONS
if(p==endptr){throw ::std::invalid_argument(p);}if((errno==ERANGE)||v.is_inf()){throw ::std::out_of_range(p);}
#endif
out=v;
#endif
return true;}
#endif
typedef ::std::stringstream stlstream;}typedef ::std::ostream iu_ostream;typedef detail::stlstream iu_stringstream;typedef iu_ostream&(*iu_basic_iomanip)(iu_ostream&);}
#if IUTEST_HAS_CXX_HDR_STRING_VIEW
#include <string_view>
#endif
#if IUTEST_HAS_EXCEPTIONS
#include <stdexcept>
#endif
#include <climits>
namespace iutest{namespace detail{
#if !IUTEST_USE_OWN_STRING_VIEW
template<typename CharT,typename Traits=::std::char_traits<CharT> >using iu_basic_string_view=::std::basic_string_view<CharT,Traits>;
#else
template <class CharT,class Traits=::std::char_traits<CharT> >class iu_basic_string_view;template<typename CharT,typename Traits>class iu_basic_string_view{public: typedef Traits traits_type;typedef CharT value_type;typedef value_type* pointer;typedef const value_type* const_pointer;typedef value_type& reference;typedef const value_type& const_reference;typedef size_t size_type;typedef ::std::ptrdiff_t difference_type;public: static const size_type npos=static_cast<size_type >(-1);private: static const size_type size_type_max=static_cast<size_type>(
#ifdef PTRDIFF_MAX
PTRDIFF_MAX
#else
INT_MAX
#endif
);public: II_CXX_CE iu_basic_string_view() II_CXX_NEX_S: m_data(IUTEST_NULLPTR),m_size(0){}II_CXX_CE iu_basic_string_view(const_pointer str):m_data(str),m_size(traits_type::length(str)){}II_CXX_CE iu_basic_string_view(const_pointer str,size_type len):m_data(str),m_size(len){}
#if IUTEST_HAS_DEFAULT_FUNCTIONS
II_CXX_CE iu_basic_string_view(const iu_basic_string_view&) II_CXX_NEX_S=default;
#else
II_CXX_CE iu_basic_string_view(const iu_basic_string_view& rhs) II_CXX_NEX_S: m_data(rhs.m_data),m_size(rhs.m_size){}
#endif
template<size_t N>iu_basic_string_view(value_type(&str)[N]):m_data(str),m_size(N){}template<typename Allocator>iu_basic_string_view(const ::std::basic_string<value_type,traits_type,Allocator>& str):m_data(str.data()),m_size(str.length()){}~iu_basic_string_view() II_CXX_DF_F public:
#if IUTEST_HAS_DEFAULT_FUNCTIONS
iu_basic_string_view& operator=(const iu_basic_string_view&)=default;
#if IUTEST_HAS_MOVE_ASSIGNMENT_DEFAULT_FUNCTION
iu_basic_string_view& operator=(iu_basic_string_view&&)=default;
#endif
#else
iu_basic_string_view& operator=(const iu_basic_string_view& rhs){m_data=rhs.m_data;m_size=rhs.m_size;return *this;}
#endif
public: II_CXX_CE size_type size()const II_CXX_NEX_S{return m_size;}II_CXX_CE size_type length()const II_CXX_NEX_S{return m_size;}II_CXX_CE size_type max_size()const II_CXX_NEX_S{return(::std::min)(size_type_max,static_cast<size_type>(-1) / sizeof(value_type));}II_CXX_CE bool empty()const II_CXX_NEX_S{return m_size==0;}public: II_CXX_CE const_reference operator[](size_type pos)const II_CXX_NEX_S{return m_data[pos];}II_CXX14_CE const_reference at(size_type pos)const{offset_exclusive(pos);return m_data[pos];}II_CXX_CE const_reference front()const II_CXX_NEX_S{return m_data[0];}II_CXX_CE const_reference back()const II_CXX_NEX_S{return m_data[0];}II_CXX_CE const_pointer data()const II_CXX_NEX_S{return m_data;}public: II_PGM_W_PU()IUTEST_PRAGMA_WARN_CXX14_CONSTEXPR_NOT_IMPLY_CONST()II_CXX14_CE void remove_prefix(size_type n) II_CXX_NEX_S{m_data+=n;m_size-=n;}II_CXX14_CE void remove_suffix(size_type n) II_CXX_NEX_S{m_size-=n;}II_CXX14_CE void swap(iu_basic_string_view&other) II_CXX_NEX_S{const iu_basic_string_view tmp={other};other=*this;*this=other;}II_PGM_W_PP()public: size_type copy(pointer s,size_type n,size_type pos=0)const{offset_exclusive(pos);const size_type count=clamp_suffix_size(pos,n);traits_type::copy(s,m_data+pos,count);return count;}II_CXX14_CE iu_basic_string_view substr(size_type pos=0,size_type n=npos)const{offset_exclusive(pos);const size_type count=clamp_suffix_size(pos,n);return iu_basic_string_view(m_data+pos,count);}public: II_CXX_CE bool equal(iu_basic_string_view sv)const II_CXX_NEX_S{return m_size==sv.m_size&&(traits_type::compare(m_data,sv.m_data,m_size)==0);}public: II_CXX14_CE int compare(iu_basic_string_view sv)const II_CXX_NEX_S{{const size_type count=(::std::min)(m_size,sv.m_size);const int result=traits_type::compare(m_data,sv.m_data,count);if(result!=0){return result;}}if(m_size<sv.m_size){return -1;}if(m_size>sv.m_size){return 1;}return 0;}II_CXX_CE int compare(size_type pos1,size_type n1,iu_basic_string_view sv)const{return substr(pos1,n1).compare(sv);}II_CXX_CE int compare(size_type pos1,size_type n1,iu_basic_string_view sv,size_type pos2,size_type n2)const{return substr(pos1,n1).compare(sv.substr(pos2,n2));}II_CXX_CE int compare(const_pointer s)const{return compare(basic_string_view(s));}II_CXX_CE int compare(size_type pos1,size_type n1,const_pointer s)const{return substr(pos1,n1).compare(basic_string_view(s));}II_CXX_CE int compare(size_type pos1,size_type n1,const_pointer s,size_type n2)const{return substr(pos1,n1).compare(basic_string_view(s,n2));}public: II_CXX_CE bool starts_with(iu_basic_string_view x)const II_CXX_NEX_S{return compare(0,npos,x)==0;}II_CXX_CE bool starts_with(value_type x)const II_CXX_NEX_S{return starts_with(iu_basic_string_view(&x,1));}II_CXX_CE bool starts_with(const_pointer x)const{return starts_with(iu_basic_string_view(x));}II_CXX_CE bool ends_with(iu_basic_string_view x)const II_CXX_NEX_S{return m_size>=x.m_size&&compare(m_size-x.m_size,npos,x)==0;}II_CXX_CE bool ends_with(value_type x)const II_CXX_NEX_S{return ends_with(iu_basic_string_view(&x,1));}II_CXX_CE bool ends_with(const_pointer x)const{return ends_with(iu_basic_string_view(x));}public: II_CXX14_CE size_type find(iu_basic_string_view sv,size_type pos=0)const II_CXX_NEX_S{if((sv.m_size>m_size)||(pos>m_size-sv.m_size)){return npos;}if(sv.m_size==0){return pos;}const_pointer end=m_data+(m_size-sv.m_size)+1;for(const_pointer top=m_data+pos;;++top){top=traits_type::find(top,static_cast<size_type>(end-top),sv[0]);if(!top){return npos;}if(traits_type::compare(top,sv.m_data,sv.m_size)==0){return static_cast<size_type>(top-m_data);}}}II_CXX14_CE size_type find(value_type c,size_type pos=0)const II_CXX_NEX_S{if(pos<m_size){const_pointer find=traits_type::find(m_data+pos,m_size,c);if(find!=IUTEST_NULLPTR){return static_cast<size_type>(find-m_data);}}return npos;}II_CXX_CE size_type find(const_pointer s,size_type pos,size_type n)const{return find(iu_basic_string_view(s,n),pos);}II_CXX_CE size_type find(const_pointer s,size_type pos=0)const{return find(iu_basic_string_view(s),pos);}public: private: size_type clamp_suffix_size(size_type pos,size_type n)const{return(::std::min)(n,m_size-pos);}void offset_exclusive(size_type pos)const{if(pos>=m_size){out_of_range();}}void out_of_range()const{
#if IUTEST_HAS_EXCEPTIONS
throw new ::std::out_of_range("invalid string_view position");
#endif
}public: friend bool operator==(const iu_basic_string_view lhs,const iu_basic_string_view& rhs){return lhs.equal(rhs);}friend bool operator!=(const iu_basic_string_view lhs,const iu_basic_string_view& rhs){return !lhs.equal(rhs);}private: const_pointer m_data;size_type m_size;};
#endif
template<typename CharT,typename Traits=::std::char_traits<CharT> >class iu_nullable_basic_string_view:public iu_basic_string_view<CharT,Traits>{public: typedef iu_basic_string_view<CharT,Traits> _Mybase;typedef Traits traits_type;typedef CharT value_type;typedef value_type* pointer;typedef const value_type* const_pointer;typedef size_t size_type;public: II_CXX_CE iu_nullable_basic_string_view() II_CXX_NEX_S II_CXX_DF_F
#if IUTEST_HAS_NULLPTR
II_CXX_CE iu_nullable_basic_string_view(::std::nullptr_t):_Mybase(IUTEST_NULLPTR,0){}
#endif
II_CXX_CE iu_nullable_basic_string_view(const_pointer str):_Mybase(str,str?traits_type::length(str):0){}II_CXX_CE iu_nullable_basic_string_view(const_pointer str,size_type len):_Mybase(str,len){}
#if IUTEST_HAS_DEFAULT_FUNCTIONS
II_CXX_CE iu_nullable_basic_string_view(const iu_nullable_basic_string_view&) II_CXX_NEX_S=default;
#else
II_CXX_CE iu_nullable_basic_string_view(const iu_nullable_basic_string_view& rhs) II_CXX_NEX_S: _Mybase(rhs){}
#endif
template<size_t N>iu_nullable_basic_string_view(value_type(&str)[N]):_Mybase(str,N){}iu_nullable_basic_string_view(const _Mybase& str_view):_Mybase(str_view){}template<typename Allocator>iu_nullable_basic_string_view(const ::std::basic_string<value_type,traits_type,Allocator>& str):_Mybase(str.data(),str.length()){}};typedef iu_basic_string_view<char> iu_string_view;typedef iu_basic_string_view<wchar_t> iu_wstring_view;}}
#ifndef IUTEST_HAS_CXX_HDR_TYPE_TARITS
#ifdef __has_include
#if __has_include(<type_traits>)&&IUTEST_HAS_CXX11
#define IUTEST_HAS_CXX_HDR_TYPE_TARITS 1
#endif
#elif(defined(__GLIBCXX__)||defined(_LIBCPP_VERSION))&&IUTEST_HAS_CXX11
#define IUTEST_HAS_CXX_HDR_TYPE_TARITS 1
#endif
#endif
#ifndef IUTEST_HAS_CXX_HDR_TYPE_TARITS
#define IUTEST_HAS_CXX_HDR_TYPE_TARITS 0
#endif
#if IUTEST_HAS_CXX_HDR_TYPE_TARITS
#include <type_traits>
#else
#ifndef IUTEST_USE_OWN_IS_MEMBER_FUNCTION_POINTER
#define IUTEST_USE_OWN_IS_MEMBER_FUNCTION_POINTER 1
#endif
#endif
namespace iutest_type_traits{typedef void type_defined_void;template<typename T>struct identity{typedef T type;};template<bool b,typename T=type_defined_void>struct enable_if;template<bool B,typename T>struct enable_if{typedef T type;};template<typename T>struct enable_if<false,T>{};template<class COND,typename T=type_defined_void>struct enable_if_t:public enable_if<COND::value,T>{};template<bool B,typename T=type_defined_void>struct disable_if:public enable_if<!B,T>{};template<class COND,typename T=type_defined_void>struct disable_if_t:public disable_if<COND::value,T>{};template<typename T>struct enabler_t{static void* value;};template<typename T>void* enabler_t<T>::value=0;typedef enabler_t<void> enabler;template<typename T>class add_const_to_pointer{template<typename U,typename DMY>struct impl{typedef const U type;};template<typename U,typename DMY>struct impl<U*,DMY>{typedef const U* type;};public: typedef typename impl<T,void>::type type;};
#if defined(IUTEST_USE_OWN_IS_MEMBER_FUNCTION_POINTER)&&IUTEST_USE_OWN_IS_MEMBER_FUNCTION_POINTER
template<typename T>struct is_member_function_pointer;
#endif
#if IUTEST_HAS_CXX_HDR_TYPE_TARITS
using ::std::true_type;using ::std::false_type;using ::std::remove_const;using ::std::remove_volatile;using ::std::remove_reference;using ::std::remove_cv;using ::std::remove_pointer;using ::std::is_integral;using ::std::is_pointer;using ::std::is_reference;using ::std::is_void;using ::std::is_const;using ::std::is_same;using ::std::is_class;using ::std::is_convertible;using ::std::is_base_of;using ::std::is_signed;using ::std::add_lvalue_reference;
#if IUTEST_HAS_RVALUE_REFS
using ::std::add_rvalue_reference;
#else
template<typename T>struct add_rvalue_reference{typedef T type;};
#endif
using ::std::is_function;
#if !defined(IUTEST_USE_OWN_IS_MEMBER_FUNCTION_POINTER)||!IUTEST_USE_OWN_IS_MEMBER_FUNCTION_POINTER
using ::std::is_member_function_pointer;
#endif
using ::std::is_member_pointer;template<typename F>struct is_function_pointer:public ::std::integral_constant<bool,::std::is_pointer<F>::value&&::std::is_function<typename ::std::remove_pointer<F>::type >::value>{};
#if defined(__cpp_lib_bool_constant)&&__cpp_lib_bool_constant>=201505
using ::std::bool_constant;
#else
template<bool B>struct bool_constant : ::std::integral_constant<bool,B>{};
#endif
#else
template<bool B>struct bool_constant{static const bool value=B;};template<bool B>const bool bool_constant<B>::value;typedef bool_constant<true> true_type;typedef bool_constant<false> false_type;template<typename T>class remove_const{template<typename U>struct impl{typedef U type;};template<typename U>struct impl<const U>{typedef U type;};public: typedef typename impl<T>::type type;};template<typename T>class remove_volatile{template<typename U>struct impl{typedef U type;};template<typename U>struct impl<volatile U>{typedef U type;};public: typedef typename impl<T>::type type;};template<typename T>class remove_reference{template<typename U>struct impl{typedef U type;};template<typename U>struct impl<U&>{typedef U type;};
#if IUTEST_HAS_RVALUE_REFS
template<typename U>struct impl<U&&>{typedef U type;};
#endif
public: typedef typename impl<T>::type type;};template<typename T>struct remove_cv{typedef typename remove_const<typename remove_volatile<T>::type >::type type;};template<typename T>class remove_pointer{template<typename U>struct impl{typedef U type;};template<typename U>struct impl<U*>{typedef U type;};public: typedef typename impl<T>::type type;};namespace is_integral_helper{template<typename T>class is_integral:public false_type{};template<typename T>class is_integral<const T>:public is_integral<T>{};template<typename T>class is_integral<volatile T>:public is_integral<T>{};template<typename T>class is_integral<const volatile T>:public is_integral<T>{};template<>class is_integral<unsigned char>:public true_type{};template<>class is_integral<unsigned short>:public true_type{};template<>class is_integral<unsigned int>:public true_type{};template<>class is_integral<unsigned long>:public true_type{};template<>class is_integral<signed char>:public true_type{};template<>class is_integral<signed short>:public true_type{};template<>class is_integral<signed int>:public true_type{};template<>class is_integral<signed long>:public true_type{};template<>class is_integral<unsigned long long>:public true_type{};template<>class is_integral<signed long long>:public true_type{};template<>class is_integral<wchar_t>:public true_type{};
#if IUTEST_HAS_CHAR16_T
template<>class is_integral<char16_t>:public true_type{};
#endif
#if IUTEST_HAS_CHAR32_T
template<>class is_integral<char32_t>:public true_type{};
#endif
template<>class is_integral<char>:public true_type{};template<>class is_integral<bool>:public true_type{};
#if IUTEST_HAS_INT128
template<>class is_integral<__uint128_t>:public true_type{};template<>class is_integral<__int128>:public true_type{};
#endif
}template<typename T>struct is_integral:public is_integral_helper::is_integral<T>{};namespace is_pointer_helper{template<typename T>class is_pointer{template<typename U,typename TMP> struct impl{typedef false_type type;};template<typename U,typename TMP> struct impl<U*,TMP>{typedef true_type type;};typedef typename remove_cv<T>::type rmcv_type;public: typedef typename impl<rmcv_type,void>::type type;};}template<typename T>struct is_pointer:public is_pointer_helper::is_pointer<T>::type{};namespace is_reference_helper{template<typename T>class is_reference{template<typename U,typename TMP> struct impl{typedef false_type type;};template<typename U,typename TMP> struct impl<U&,TMP>{typedef true_type type;};typedef typename remove_cv<T>::type rmcv_type;public: typedef typename impl<rmcv_type,void>::type type;};}template<typename T>struct is_reference: public is_reference_helper::is_reference<T>::type{};namespace is_void_helper{template<typename T>class is_void{template<typename U,typename TMP> struct impl{typedef false_type type;};template<typename TMP> struct impl<void,TMP>{typedef true_type type;};typedef typename remove_cv<T>::type rmcv_type;public: typedef typename impl<rmcv_type,void>::type type;};}template<typename T>struct is_void: public is_void_helper::is_void<T>::type{};namespace is_const_helper{template<typename T>class is_const{template<typename U> struct impl{typedef false_type type;};template<typename U> struct impl<U const>{typedef true_type type;};public: typedef typename impl<T>::type type;};}template<typename T>struct is_const: public is_const_helper::is_const<T>::type{};namespace is_same_helper{template<typename T1,typename T2>struct is_same{typedef false_type type;};template<typename T>struct is_same<T,T>{typedef true_type type;};}template<typename T1,typename T2>struct is_same: public is_same_helper::is_same<T1,T2>::type{};namespace is_class_helper{template<typename T>class is_class{template<typename U>static char IsClassHelper(int U::*);template<typename U>static char(&IsClassHelper(...))[2];enum{IsClass=sizeof(IsClassHelper<T>(0))==1 ? true:false};public: typedef bool_constant<IsClass> type;};}template<typename T>struct is_class: public is_class_helper::is_class<T>::type{};namespace is_convertible_helper{template<typename From,typename To>class is_convertible_type{static From MakeFrom();static char IsConvertibleHelper(To);static char(&IsConvertibleHelper(...))[2];enum{IsConvertible=sizeof(IsConvertibleHelper(is_convertible_type::MakeFrom()))==1 ? true:false};public: typedef bool_constant<IsConvertible> type;};}template<typename From,typename To>struct is_convertible: public is_convertible_helper::is_convertible_type<From,To>::type{};namespace is_base_of_helper{template<typename Base,typename Derived>class is_base_of_check{struct no_t{char a[2];};template<typename T>static char CheckSig(Derived const volatile *,T);static no_t CheckSig(Base const volatile *,int);struct host{operator Base const volatile *()const;operator Derived const volatile *();};enum{IsBaseAndDerived=sizeof(CheckSig(host(),0))==1 ? true:false};public: typedef bool_constant<IsBaseAndDerived> type;};template<bool is_class_b,bool is_class_d,bool is_same>struct is_base_of_select{template<typename T,typename U>struct rebind{typedef false_type type;};};template<>struct is_base_of_select<true,true,true>{template<typename T,typename U>struct rebind{typedef true_type type;};};template<>struct is_base_of_select<true,true,false>{template<typename T,typename U>struct rebind{typedef typename is_base_of_check<T,U>::type type;};};template<typename Base,typename Derived>class is_base_of{typedef typename remove_cv<Base>::type B;typedef typename remove_cv<Derived>::type D;typedef is_base_of_select<is_class<Base>::value,is_class<Derived>::value,is_same<Base,Derived>::value> selector;typedef typename selector::template rebind<B,D> binder;public: typedef typename binder::type type;};}template<typename Base,typename Derived>struct is_base_of: public is_base_of_helper::is_base_of<Base,Derived>::type{};namespace is_signed_helper{template<typename T,bool Arithmetic>struct is_signed:public bool_constant< !(T(-1)> T(0))>{};template<typename T>struct is_signed<T,false>:public false_type{};}template<typename T>struct is_signed: public is_signed_helper::is_signed<T,true>{};template<typename T>class add_lvalue_reference{template<typename U,bool b>struct impl{typedef U type;};template<typename U>struct impl<U,true>{typedef U& type;};public: typedef typename impl<T,!is_void<T>::value&&!is_reference<T>::value >::type type;};template<typename T>class add_rvalue_reference{template<typename U,bool b>struct impl{typedef U type;};
#if IUTEST_HAS_RVALUE_REFS
template<typename U>struct impl<U,true>{typedef U&& type;};
#endif
public: typedef typename impl<T,!is_void<T>::value&&!is_reference<T>::value >::type type;};namespace is_function_pointer_helper{template<typename T>class is_function_pointer{template<typename U>struct impl:public false_type{};
#if IUTEST_HAS_VARIADIC_TEMPLATES
template<typename R,typename ...Args>struct impl<R(*)(Args...)>:public true_type{};template<typename R,typename ...Args>struct impl<R(*)(Args...,...)>:public true_type{};
#else
template<typename R>struct impl<R(*)()>:public true_type{};template<typename R>struct impl<R(*)(...)>:public true_type{};
#define II_D_IS_FP_(n) template<typename R,IP_ENM_P(n,typename T)> struct impl<R(*)(IP_ENM_P(n,T))>:public true_type{};template<typename R,IP_ENM_P(n,typename T)> struct impl<R(*)(IP_ENM_P(n,T),...)>:public true_type{}
II_D_IS_FP_(1);II_D_IS_FP_(2);II_D_IS_FP_(3);II_D_IS_FP_(4);II_D_IS_FP_(5);II_D_IS_FP_(6);II_D_IS_FP_(7);II_D_IS_FP_(8);II_D_IS_FP_(9);II_D_IS_FP_(10);II_D_IS_FP_(11);II_D_IS_FP_(12);II_D_IS_FP_(13);II_D_IS_FP_(14);II_D_IS_FP_(15);II_D_IS_FP_(16);II_D_IS_FP_(17);II_D_IS_FP_(18);II_D_IS_FP_(19);II_D_IS_FP_(20);
#undef II_D_IS_FP_
#endif
enum{value=impl<typename remove_cv<T>::type >::value};public: typedef bool_constant<value> type;};}template<typename T>struct is_function_pointer: public is_function_pointer_helper::is_function_pointer<T>::type{};namespace is_member_pointer_helper{template<typename T>class is_member_pointer{template<typename U>struct impl:public false_type{};template<typename U,typename C>struct impl<U C::*>:public true_type{};public: typedef bool_constant<impl<typename remove_cv<T>::type >::value|| is_member_function_pointer<T>::value>type;};}template<typename T>struct is_member_pointer: public is_member_pointer_helper::is_member_pointer<T>::type{};
#endif
#if defined(IUTEST_USE_OWN_IS_MEMBER_FUNCTION_POINTER)&&IUTEST_USE_OWN_IS_MEMBER_FUNCTION_POINTER
namespace is_member_function_pointer_helper{template<typename T>class is_member_function_pointer{template<typename U>struct impl:public false_type{};
#if IUTEST_HAS_VARIADIC_TEMPLATES
#define II_D_IS_M_FP_CV_(CV) template<typename R,typename U,typename ...Args> struct impl<R(U::*)(Args...) CV>:public true_type{};template<typename R,typename U,typename ...Args> struct impl<R(U::*)(Args...,...) CV>:public true_type{}
II_D_IS_M_FP_CV_(IP_EMPTY());II_D_IS_M_FP_CV_(const);II_D_IS_M_FP_CV_(volatile);II_D_IS_M_FP_CV_(const volatile);
#undef II_D_IS_M_FP_CV_
#else
#define II_D_IS_M_FP_VOID_CV_(CV) template<typename R,typename U>struct impl<R(U::*)() CV>:public true_type{};template<typename R,typename U>struct impl<R(U::*)(...) CV>:public true_type{}
template<typename R,typename U>struct impl<R(U::*)()>:public true_type{};template<typename R,typename U>struct impl<R(U::*)(...)>:public true_type{};II_D_IS_M_FP_VOID_CV_(const);II_D_IS_M_FP_VOID_CV_(volatile);II_D_IS_M_FP_VOID_CV_(const volatile);
#undef II_D_IS_M_FP_VOID_CV_
#define II_D_IS_M_FP_(n) II_D_IS_M_FP_I(n,IP_EMPTY());II_D_IS_M_FP_I(n,const);II_D_IS_M_FP_I(n,volatile);II_D_IS_M_FP_I(n,const volatile)
#define II_D_IS_M_FP_I(n,CV) template<typename R,typename U,IP_ENM_P(n,typename T)> struct impl<R(U::*)(IP_ENM_P(n,T)) CV>:public true_type{};template<typename R,typename U,IP_ENM_P(n,typename T)> struct impl<R(U::*)(IP_ENM_P(n,T),...) CV>:public true_type{}
II_D_IS_M_FP_(1);II_D_IS_M_FP_(2);II_D_IS_M_FP_(3);II_D_IS_M_FP_(4);II_D_IS_M_FP_(5);II_D_IS_M_FP_(6);II_D_IS_M_FP_(7);II_D_IS_M_FP_(8);II_D_IS_M_FP_(9);II_D_IS_M_FP_(10);II_D_IS_M_FP_(11);II_D_IS_M_FP_(12);II_D_IS_M_FP_(13);II_D_IS_M_FP_(14);II_D_IS_M_FP_(15);II_D_IS_M_FP_(16);II_D_IS_M_FP_(17);II_D_IS_M_FP_(18);II_D_IS_M_FP_(19);II_D_IS_M_FP_(20);
#undef II_D_IS_M_FP_
#undef II_D_IS_M_FP_I
#endif
public: typedef bool_constant<impl<typename remove_cv<T>::type >::value>type;};}template<typename T>struct is_member_function_pointer: public is_member_function_pointer_helper::is_member_function_pointer<T>::type{};
#endif
namespace has_equal_to_operator_helper{typedef char no_t[7];template<typename T1,typename T2>no_t& operator==(const T1& lhs,const T2& rhs);}namespace has_equal_to_operator_impl{II_PGM_W_PU()II_PGM_W_FE()using namespace has_equal_to_operator_helper;template<typename T>struct has_equal_to_operator{typedef bool_constant<(sizeof(*(T*)0==*(T*)0)!=sizeof(has_equal_to_operator_helper::no_t))> type;};II_PGM_W_PP()}template<typename T>struct has_equal_to: public has_equal_to_operator_impl::has_equal_to_operator<T>::type{};namespace has_not_equal_to_operator_helper{typedef char no_t[7];template<typename T1,typename T2>no_t& operator!=(const T1& lhs,const T2& rhs);}namespace has_not_equal_to_operator_impl{using namespace has_not_equal_to_operator_helper;template<typename T>struct has_not_equal_to_operator{typedef bool_constant<(sizeof(*(T*)0!=*(T*)0)!=sizeof(has_not_equal_to_operator_helper::no_t))> type;};}template<typename T>struct has_not_equal_to: public has_not_equal_to_operator_impl::has_not_equal_to_operator<T>::type{};template<typename T>class function_return_type{template<typename U> struct impl{};
#if IUTEST_HAS_VARIADIC_TEMPLATES
template<typename R,typename ...Args>struct impl<R(*)(Args...)>{typedef R type;};template<typename R,typename ...Args>struct impl<R(*)(Args...,...)>{typedef R type;};template<typename R,typename U,typename ...Args>struct impl<R(U::*)(Args...)>{typedef R type;};template<typename R,typename U,typename ...Args>struct impl<R(U::*)(Args...,...)>{typedef R type;};
#define II_D_F_R_T_CV_(CV) template<typename R,typename U,typename ...Args>struct impl<R(U::*)(Args...) CV>{typedef R type;};template<typename R,typename U,typename ...Args>struct impl<R(U::*)(Args...,...) CV>{typedef R type;}
II_D_F_R_T_CV_(const);II_D_F_R_T_CV_(volatile);II_D_F_R_T_CV_(const volatile);
#undef II_D_F_R_T_CV_
#else
#define II_D_F_R_T_(n) template<typename R,IP_ENM_P(n,typename T)> struct impl<R(*)(IP_ENM_P(n,T))> {typedef R type;};template<typename R,IP_ENM_P(n,typename T)> struct impl<R(*)(IP_ENM_P(n,T),...)> {typedef R type;};II_D_F_R_T_I(n,IP_EMPTY());II_D_F_R_T_I(n,const);II_D_F_R_T_I(n,volatile);II_D_F_R_T_I(n,const volatile)
#define II_D_F_R_T_I(n,CV) template<typename R,typename U,IP_ENM_P(n,typename T)> struct impl<R(U::*)(IP_ENM_P(n,T)) CV> {typedef R type;};template<typename R,typename U,IP_ENM_P(n,typename T)> struct impl<R(U::*)(IP_ENM_P(n,T),...) CV> {typedef R type;}
template<typename R>struct impl<R(*)()>{typedef R type;};template<typename R,typename U>struct impl<R(U::*)()>{typedef R type;};
#define II_D_F_R_T_VOID_(CV) template<typename R,typename U>struct impl<R(U::*)() CV>{typedef R type;}
II_D_F_R_T_VOID_(const);II_D_F_R_T_VOID_(volatile);II_D_F_R_T_VOID_(const volatile);
#undef II_D_F_R_T_VOID_
II_D_F_R_T_(1);II_D_F_R_T_(2);II_D_F_R_T_(3);II_D_F_R_T_(4);II_D_F_R_T_(5);II_D_F_R_T_(6);II_D_F_R_T_(7);II_D_F_R_T_(8);II_D_F_R_T_(9);II_D_F_R_T_(10);II_D_F_R_T_(11);II_D_F_R_T_(12);II_D_F_R_T_(13);II_D_F_R_T_(14);II_D_F_R_T_(15);II_D_F_R_T_(16);II_D_F_R_T_(17);II_D_F_R_T_(18);II_D_F_R_T_(19);II_D_F_R_T_(20);
#undef II_D_F_R_T_
#undef II_D_F_R_T_I
#endif
public: typedef typename impl<typename remove_cv<T>::type >::type type;};
#if IUTEST_HAS_CXX_HDR_VARIANT&&IUTEST_HAS_VARIADIC_TEMPLATES
template<typename T>struct is_variant:public false_type{};template<typename ...T>struct is_variant< ::std::variant<T...> >:public true_type{};
#endif
}namespace iutest_compatible{struct IsNullLiteralHelper{class Object;static char IsNullLiteral(Object*);static char(&IsNullLiteral(...))[2];};}
#if IUTEST_HAS_EXCEPTIONS
#include <exception>
namespace iutest{namespace detail{inline ::std::string FormatCxxException(const char* description){iu_stringstream strm;if(description!=0){strm<<"C++ exception with description \"" <<description<<"\"";}else{strm<<"Unknown C++ exception";}return strm.str();}}}
#endif
#if IUTEST_HAS_HDR_CXXABI
#include <cxxabi.h>
#endif
#define II_AMB_E_B switch(::iutest::detail::AlwaysZero()) case 0: default:
#define II_S_UR_C_W(st) if(::iutest::detail::AlwaysTrue()) st
#ifndef IUTEST_BREAK
#if defined(__GUNC__)&&(defined(__i386__)||defined(__x86_64__))
#define IUTEST_BREAK() do { __asm { int 3 } } while(::iutest::detail::AlwaysFalse())
#elif defined(__clang__)||defined(__GNUC__)
#define IUTEST_BREAK() __builtin_trap()
#else
#define IUTEST_BREAK() *static_cast<volatile int*>(0)=1
#endif
#endif
namespace iutest{namespace type_traits=iutest_type_traits;namespace detail{
#if IUTEST_HAS_NULLPTR&&!defined(IUTEST_NO_NULL_TO_NULLPTR_T)
typedef ::std::nullptr_t iu_nullptr_convertible_t;
#else
typedef ::iutest_compatible::IsNullLiteralHelper::Object* iu_nullptr_convertible_t;
#endif
inline bool AlwaysTrue(){return true;}inline bool AlwaysFalse(){return !AlwaysTrue();}inline int AlwaysZero(){return 0;}inline bool IsTrue(bool b){return b;}using namespace iutest_type_traits;using namespace iutest_compatible;template<typename Ite>struct IteratorTraits{typedef typename Ite::value_type type;};template<typename T>struct IteratorTraits<T*>{typedef T type;};template<typename T>struct IteratorTraits<const T*>{typedef T type;};template<typename T>inline void Delete(T* ptr){delete ptr;}class None{};template<typename T>class NoneT1{};template<typename T>struct explicit_type_t{};
#define II_A_E_TT(t)
template<typename T>inline explicit_type_t<T>* explicit_type(){return 0;}template<typename T>class TypeUniqueCounter{static size_t value;public: static size_t count(){return value++;}};template<typename T>size_t TypeUniqueCounter<T>::value=0;template<typename T>inline size_t GetTypeUniqueCounter(){return TypeUniqueCounter<T>::count();}template<typename T>class auto_ptr{mutable T* m_ptr;public: explicit auto_ptr(T* p=0):m_ptr(p){}auto_ptr(const auto_ptr& rhs):m_ptr(rhs.m_ptr){rhs.m_ptr=0;}~auto_ptr(){if(m_ptr!=0) delete m_ptr;}T& operator *()const{return *m_ptr;}T* operator->()const{return m_ptr;}auto_ptr& operator=(auto_ptr& rhs){m_ptr=rhs.m_ptr;rhs.m_ptr=0;return *this;}T* get(){return m_ptr;}};template<typename T>class scoped_ptr{T* m_ptr;public: explicit scoped_ptr(T* p=0):m_ptr(p){}~scoped_ptr(){reset();}T& operator *()const{return *m_ptr;}T* operator->()const{return m_ptr;}T* get()const{return m_ptr;}T* release(){T* const p=m_ptr;m_ptr=0;return p;}void reset(T* p=0){if(m_ptr!=p){if(IsTrue(sizeof(T)> 0)){delete m_ptr;}m_ptr=p;}}private: IP_DIS_C_A_A(scoped_ptr);};
#define II_IS_NL(x) (sizeof(::iutest::detail::IsNullLiteralHelper::IsNullLiteral(x))==1)
struct IsContainerHelper{typedef int yes_t;typedef char no_t;template<typename T>static II_CXX_CE yes_t IsContainer(int II_A_E_TT(T),typename T::iterator* =0,typename T::const_iterator* =0){return 0;}template<typename T>static II_CXX_CE no_t IsContainer(long II_A_E_TT(T)){return 0;}};template<typename T>inline ::std::string GetTypeName(){
#if IUTEST_HAS_RTTI
const char* const name=typeid(T).name();
#if IUTEST_HAS_HDR_CXXABI
using abi::__cxa_demangle;int status=1;char* const read_name=__cxa_demangle(name,0,0,&status);::std::string str(status==0 ? read_name:name);free(read_name);return str;
#else
return name;
#endif
#else
return "<type>";
#endif
}
#if !IUTEST_HAS_RTTI
#define II_GTNS(type) template<>inline ::std::string GetTypeName<type>(){return #type;}template<>inline ::std::string GetTypeName<type*>(){return #type "*";}
#define II_GTNS2(type) II_GTNS(type) II_GTNS(unsigned type)
II_GTNS2(char)II_GTNS2(short)II_GTNS2(int)II_GTNS2(long)II_GTNS(float)II_GTNS(double)II_GTNS(bool)
#undef II_GTNS
#undef II_GTNS2
#endif
template<typename T>struct GetTypeNameProxy{static ::std::string GetTypeName(){return detail::GetTypeName<T>();}};}}
#include <unistd.h>
#include <locale.h>
#include <sys/stat.h>
#ifndef IUTEST_MAX_PATH
#if defined(FILENAME_MAX)&&FILENAME_MAX
#define IUTEST_MAX_PATH FILENAME_MAX
#else
#define IUTEST_MAX_PATH 1024
#endif
#endif
#define IUTEST_LOG_(level) ::iutest::detail::IUTestLog(::iutest::detail::IUTestLog::LOG_##level,__FILE__,__LINE__).GetStream()
#define IUTEST_CHECK_(condition) II_AMB_E_B if(!::iutest::detail::IsTrue(condition)) IUTEST_LOG_(FATAL)<<"Condition " #condition " failed. "
namespace iutest{namespace internal{namespace posix{const char* GetEnv(const char* name);int PutEnv(const char* expr);int SetEnv(const char* name,const char* value,int overwrite);const char* GetCWD(char* buf,size_t length);::std::string GetCWD();void SleepMillisec(unsigned int millisec);II_ATR_NR void Abort();inline void Abort(){abort();}
#if IUTEST_HAS_FILENO
inline int Fileno(FILE* fp){return fileno(fp);}
#else
inline int Fileno(FILE*){return -1;}
#endif
typedef struct stat StatStruct;inline int FileStat(int fd,StatStruct* buf){return fstat(fd,buf);}inline int Stat(const char* path,StatStruct* buf){return stat(path,buf);}inline bool IsDir(const StatStruct& st){return S_ISDIR(st.st_mode);}inline int Stat(FILE* fp,StatStruct* buf){int fd=Fileno(fp);return fd>=0 ? FileStat(fd,buf):fd;}}inline void SleepMilliseconds(int n){posix::SleepMillisec(static_cast<unsigned int>(n));}}namespace detail{namespace posix=internal::posix;char GetPathSeparator() II_CXX_NEX_S;bool IsPathSeparator(char c) II_CXX_NEX_S;bool IsAltPathSeparator(char c) II_CXX_NEX_S;const char* FindLastPathSeparator(const char* path,size_t length) II_CXX_NEX_S;size_t FindLastPathSeparatorPosition(const char* path,size_t length) II_CXX_NEX_S;bool SetEnvironmentVariable(const char* name,const char* value);bool GetEnvironmentVariable(const char* name,char* buf,size_t size);template<size_t SIZE>inline bool GetEnvironmentVariable(const char* name,char(&buf)[SIZE]){return GetEnvironmentVariable(name,buf,SIZE);}bool II_ATR_U GetEnvironmentVariable(const char* name,::std::string& var);bool II_ATR_U GetEnvironmentInt(const char* name,int& var);class IUTestLog{public: enum Level{LOG_INFO,LOG_WARNING,LOG_ERROR,LOG_FATAL,LOG_LEVEL_NUM};public: IUTestLog(Level level,const char* file,int line);~IUTestLog();public: iu_stringstream& GetStream(){return m_stream;}public: static int GetCount(Level level){return GetCountTable().count[level];}static bool HasWarning(){return GetCount(LOG_WARNING)> 0;}static bool HasError(){return GetCount(LOG_ERROR)> 0||GetCount(LOG_FATAL)> 0;}private: struct Count{int count[LOG_LEVEL_NUM];};static Count& GetCountTable(){static Count count={{0}};return count;}static void CountUp(int level);private: const Level kLevel;iu_stringstream m_stream;IP_DIS_C_A_A(IUTestLog);};template<int SIZE=BUFSIZ>class IUStreamBuffer{public: explicit IUStreamBuffer(FILE* fp):m_fp(fp){m_buf[0]='\0';fflush(fp);setvbuf(fp,m_buf,_IOFBF,SIZE);}~IUStreamBuffer(){fflush(m_fp);setvbuf(m_fp,0,_IONBF,0);}public: ::std::string GetStreamString(){return m_buf;}private: FILE* m_fp;char m_buf[SIZE];};}}namespace iutest{namespace internal{namespace posix{inline const char* GetEnv(const char* name){
#if defined(__SunOS_5_8)||defined(__SunOS_5_9)
const char* env=getenv(name);return(env!=0&&env[0]!='\0')?env:0;
#else
return getenv(name);
#endif
}inline int PutEnv(const char* expr){
#if defined(__STRICT_ANSI__)
(void)(expr);return -1;
#else
return putenv(const_cast<char*>(expr));
#endif
}inline int SetEnv(const char* name,const char* value,int overwrite){
#if defined(__STRICT_ANSI__)
(void)(name);(void)(value);(void)(overwrite);return -1;
#else
return setenv(name,value,overwrite);
#endif
}inline const char* GetCWD(char* buf,size_t length){const char* result=getcwd(buf,length);if(result==0&&buf!=0&&length>=1){buf[0]='\0';return buf;}return result;}inline ::std::string GetCWD(){char buf[260]={0};return GetCWD(buf,sizeof(buf));}inline int SleepMillisecFor(unsigned int millisec){volatile int x=0;for(unsigned int i=0;i<millisec;++i){x=x + 1;}return x;}inline void SleepMillisec(unsigned int millisec){
#if defined(_POSIX_C_SOURCE)&&_POSIX_C_SOURCE>=199309L
const timespec time={0,static_cast<long>(millisec) * 1000 * 1000};nanosleep(&time,0);
#else
(void)SleepMillisecFor(millisec);
#endif
}}}namespace detail{inline char GetPathSeparator() II_CXX_NEX_S{return '/';}inline bool IsPathSeparator(char c) II_CXX_NEX_S{return c=='/';}inline bool IsAltPathSeparator(char c) II_CXX_NEX_S{(void)(c);return false;}inline const char* FindLastPathSeparator(const char* path,size_t length) II_CXX_NEX_S{const char* ps=path;const char* pe=ps+length-1;while(pe>=ps){if(IsPathSeparator(*pe)){if((*(pe-1)&0x80)==0){return pe;}--pe;}--pe;}return 0;}inline size_t FindLastPathSeparatorPosition(const char* path,size_t length) II_CXX_NEX_S{const char* p=FindLastPathSeparator(path,length);if(p==0){return ::std::string::npos;}return p-path;}inline bool SetEnvironmentVariable(const char* name,const char* value){return internal::posix::SetEnv(name,value,1)==0 ? true:false;}inline bool GetEnvironmentVariable(const char* name,char* buf,size_t size){if(buf==0){return false;}const char* env=internal::posix::GetEnv(name);if(env==0){return false;}const int n=iu_snprintf(buf,size,"%s",env);if(n<0 || static_cast<size_t>(n)>=size){return false;}return true;}inline bool GetEnvironmentVariable(const char* name,::std::string& var){const char* env=internal::posix::GetEnv(name);if(env==0){return false;}var=env;return true;}inline bool GetEnvironmentInt(const char* name,int& var){const char* env=internal::posix::GetEnv(name);if(env==0){return false;}char* end=0;var=static_cast<int>(strtol(env,&end,0));return true;}::std::string FormatFileLocation(const char* file,int line);inline IUTestLog::IUTestLog(Level level,const char* file,int line):kLevel(level){CountUp(level);const char* const tag =(level==LOG_INFO)?"[  INFO ] ": (level==LOG_WARNING)?"[WARNING] ": (level==LOG_ERROR)?"[ ERROR ] ": "[ FATAL ] ";GetStream()<<"\r\n" <<tag<<FormatFileLocation(file,line).c_str()<<": ";}inline IUTestLog::~IUTestLog(){GetStream()<<"\r\n";fprintf(stderr,"%s",m_stream.str().c_str());if(kLevel==LOG_FATAL){fflush(stderr);posix::Abort();}}inline void IUTestLog::CountUp(int level){if(level<LOG_LEVEL_NUM&&level>=0){++GetCountTable().count[level];}}}}namespace iutest{namespace detail{
#if IUTEST_HAS_INLINE_VARIABLE
namespace kStrings{static inline const char* const DefaultXmlReportFileName="test_detail.xml";static inline const char* const UnknownFile="unknown file";static inline const char* const Null="(null)";}
#else
namespace helper{namespace{template<typename DMY>struct kStringsT{static const char* const DefaultXmlReportFileName;static const char* const UnknownFile;static const char* const Null;};template<typename DMY>const char* const kStringsT<DMY>::DefaultXmlReportFileName="test_detail.xml";template<typename DMY>const char* const kStringsT<DMY>::UnknownFile="unknown file";template<typename DMY>const char* const kStringsT<DMY>::Null="(null)";template struct kStringsT<void>;}}typedef helper::kStringsT<void> kStrings;
#endif
struct kValues{static const size_t MaxPrintContainerCount=32;static const size_t PrintArrayThreshold=18;static const size_t PrintArrayChunksize=PrintArrayThreshold/2;};}}
#if IUTEST_HAS_CXX_HDR_CODECVT
#include <locale>
#include <codecvt>
#endif
namespace iutest{namespace detail{inline ::std::string AnyStringToMultiByteString(const char* str,int num=-1){return num<0 ? str : ::std::string(str,num);}::std::string AnyStringToUTF8(const wchar_t* str,int num=-1);::std::string AnyStringToMultiByteString(const wchar_t* str,int num=-1);
#if IUTEST_HAS_CHAR16_T
::std::string AnyStringToUTF8(const char16_t* str,int num=-1);::std::string AnyStringToMultiByteString(const char16_t* str,int num=-1);
#endif
#if IUTEST_HAS_CHAR32_T
::std::string AnyStringToUTF8(const char32_t* str,int num=-1);::std::string AnyStringToMultiByteString(const char32_t* str,int num=-1);
#endif
::std::wstring MultiByteStringToWideString(const char* str);::std::string MultiByteStringToUTF8(const char* src,int num=-1);template<typename CharType>::std::string ShowAnyCString(const CharType* any_c_str){if(any_c_str==0){return kStrings::Null;}return AnyStringToMultiByteString(any_c_str);}
#if IUTEST_HAS_CXX_HDR_CODECVT
template<typename In,typename Out,typename State>struct codecvt:public ::std::codecvt<In,Out,State>{~codecvt(){}};template<typename In,typename Out,typename State>::std::basic_string<Out> CodeConvert(const In* str){::std::wstring_convert<codecvt<In,Out,State>,In> conv;return conv.to_bytes(str);}
#endif
namespace mbs_ptr_impl{template<typename T>struct to_mbs_ptr{const char* ptr(const char* arg){return arg;}};struct wcs_to_mbs_ptr{::std::string m_arg;const char* ptr(const wchar_t* arg){m_arg=ShowAnyCString(arg);return m_arg.c_str();}};template<>struct to_mbs_ptr<wchar_t>:public wcs_to_mbs_ptr{};template<>struct to_mbs_ptr<const wchar_t>:public wcs_to_mbs_ptr{};}template<typename CharType>struct mbs_ptr:public mbs_ptr_impl::to_mbs_ptr<CharType>{};}}
#if IUTEST_HAS_CXX_HDR_CUCHAR
#include <cuchar>
#endif
namespace iutest{namespace detail{const UInt32 kMaxCodePoint1=(static_cast<UInt32>(1)<<7)-1;const UInt32 kMaxCodePoint2=(static_cast<UInt32>(1)<<(5+6))-1;const UInt32 kMaxCodePoint3=(static_cast<UInt32>(1)<<(4+2*6))-1;const UInt32 kMaxCodePoint4=(static_cast<UInt32>(1)<<(3+3*6))-1;inline II_CXX_CE bool IsUtf16SurrogatePair(wchar_t first,wchar_t second){return(sizeof(wchar_t)==2)&&((first&0xFC00)==0xD800)&&((second&0xFC00)==0xDC00);}inline II_CXX_CE UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,wchar_t second){return(sizeof(wchar_t)==2) ?static_cast<UInt32>((((first&0x3FF)<<10)|(second&0x3FF))+0x10000) : static_cast<UInt32>(first);}inline UInt32 ChopLowBits(UInt32* bits,int n){const UInt32 lowbits=*bits&((static_cast<UInt32>(1)<<n)-1);*bits>>=n;return lowbits;}inline char* CodePointToUtf8(UInt32 code_point,char* buf,size_t size){if(code_point<=kMaxCodePoint1){buf[1]='\0';buf[0]=static_cast<char>(code_point);}else if(code_point<=kMaxCodePoint2){buf[2]='\0';buf[1]=static_cast<char>(0x80|ChopLowBits(&code_point,6));buf[0]=static_cast<char>(0xC0|code_point);}else if(code_point<=kMaxCodePoint3){buf[3]='\0';buf[2]=static_cast<char>(0x80|ChopLowBits(&code_point,6));buf[1]=static_cast<char>(0x80|ChopLowBits(&code_point,6));buf[0]=static_cast<char>(0xE0|code_point);}else if(code_point<=kMaxCodePoint4){buf[4]='\0';buf[3]=static_cast<char>(0x80|ChopLowBits(&code_point,6));buf[2]=static_cast<char>(0x80|ChopLowBits(&code_point,6));buf[1]=static_cast<char>(0x80|ChopLowBits(&code_point,6));buf[0]=static_cast<char>(0xF0|code_point);}else{iu_snprintf(buf,size,"(Invalid UTF16 0x%s)",ToHexString(code_point).c_str());}return buf;}inline ::std::string II_ATR_U AnyStringToUTF8(const wchar_t* str,int num){if(num==-1){num=static_cast<int>(wcslen(str));}std::string s;for(int i=0;i<num;++i){UInt32 code_point=0;if(str[i]==L'\0'){break;}else if(i+1 <num&&IsUtf16SurrogatePair(str[i],str[i+1])){code_point=CreateCodePointFromUtf16SurrogatePair(str[i],str[i+1]);++i;}else{code_point=static_cast<UInt32>(str[i]);}char buf[32];s+=CodePointToUtf8(code_point,buf,sizeof(buf));}return s;}inline ::std::string II_ATR_U AnyStringToMultiByteString(const wchar_t* str,int num){(void)(num);const size_t length=wcslen(str) * MB_CUR_MAX+1;char* mbs=new char [length];const size_t written=wcstombs(mbs,str,length-1);if(written==static_cast<size_t>(-1)){delete [] mbs;return ToHexString(str,num);}mbs[written]='\0';::std::string ret=mbs;delete [] mbs;return ret;}
#if IUTEST_HAS_CHAR16_T
inline::std::string II_ATR_U AnyStringToUTF8(const char16_t* str,int num){
#if IUTEST_HAS_CXX_HDR_CUCHAR
(void)(num);const size_t length=::std::char_traits<char16_t>::length(str);char16_t lead=0,trail=0;char32_t cp;char mbs[6];mbstate_t state={};IUTEST_CHECK_(mbsinit(&state)!=0);::std::string ret;for(size_t i=0;i<length;++i){lead=str[i];if(lead>0xD800&&lead<0xDC00){++i;trail=str[i];cp=(lead<<10)+trail+0x10000-(0xD800<<10)-0xDC00;}else{cp=lead;}const size_t len=::std::c32rtomb(mbs,cp,&state);if(len!=static_cast<size_t>(-1)){mbs[len]='\0';ret+=mbs;}}return ret;
#else
II_PGM_W_PU()II_PGM_W_CA()return AnyStringToUTF8(reinterpret_cast<const wchar_t*>(str),num);II_PGM_W_PP()
#endif
}inline::std::string II_ATR_U AnyStringToMultiByteString(const char16_t* str,int num){
#if IUTEST_HAS_CXX_HDR_CODECVT
(void)(num);return CodeConvert<char16_t,char,::std::mbstate_t>(str);
#elif IUTEST_HAS_CXX_HDR_CUCHAR
(void)(num);const size_t length=::std::char_traits<char16_t>::length(str);char16_t lead=0,trail=0;char32_t cp;char mbs[6];mbstate_t state={};IUTEST_CHECK_(mbsinit(&state)!=0);::std::string ret;for(size_t i=0;i<length;++i){lead=str[i];if(lead>0xD800&&lead<0xDC00){++i;trail=str[i];cp=(lead<<10)+trail+0x10000-(0xD800<<10)-0xDC00;}else{cp=lead;}const size_t len=::std::c32rtomb(mbs,cp,&state);if(len!=static_cast<size_t>(-1)){mbs[len]='\0';ret+=mbs;}}return ret;
#else
return AnyStringToMultiByteString(reinterpret_cast<const wchar_t*>(str),num);
#endif
}
#endif
#if IUTEST_HAS_CHAR32_T
inline::std::string II_ATR_U AnyStringToUTF8(const char32_t* str,int num){
#if IUTEST_HAS_CXX_HDR_CUCHAR
const size_t length=num<0 ? ::std::char_traits<char32_t>::length(str):num;char mbs[6];mbstate_t state={};IUTEST_CHECK_(mbsinit(&state)!=0);::std::string ret;for(size_t i=0;i<length;++i){const size_t len=::std::c32rtomb(mbs,str[i],&state);if(len!=static_cast<size_t>(-1)){mbs[len]='\0';ret+=mbs;}}return ret;
#else
return ToHexString(str,num);
#endif
}inline::std::string II_ATR_U AnyStringToMultiByteString(const char32_t* str,int num){
#if IUTEST_HAS_CXX_HDR_CODECVT
(void)(num);return CodeConvert<char32_t,char,::std::mbstate_t>(str);
#else
return AnyStringToUTF8(str,num);
#endif
}
#endif
inline ::std::wstring II_ATR_U MultiByteStringToWideString(const char* str){if(str==0){return L"";}const size_t length=strlen(str)+1;wchar_t* wcs=new wchar_t[length];if(mbstowcs(wcs,str,length)==static_cast<size_t>(-1)){delete[] wcs;return L"(convert error)";}::std::wstring ret=wcs;delete[] wcs;return ret;}inline ::std::string II_ATR_U MultiByteStringToUTF8(const char* src,int num){
#if(defined(__STDC_ISO_10646__))
if(num==-1){num=static_cast<int>(strlen(src));}::std::string str;const char* p=src;for(const char* end=src+num;p<end;){wchar_t wc=0;const int len=iu_mbtowc(&wc,p,MB_CUR_MAX);if(len>1){str+=AnyStringToUTF8(&wc,1);p+=len;}else{str+=*p;++p;}}return str;
#else
(void)(num);return src;
#endif
}}}
#include <time.h>
#if IUTEST_HAS_CXX_HDR_CHRONO
#include <chrono>
#endif
#include <sys/time.h>
namespace iutest{namespace detail{bool Localtime(time_t sec,struct tm* dst);::std::string FormatTimeInMillisec(TimeInMillisec msec);::std::string FormatTimeInMillisecAsSecond(TimeInMillisec msec);::std::string FormatTimeInMillisecAsIso8601(TimeInMillisec msec);time_t GetTime();TimeInMillisec GetTimeInMillis();unsigned int GetIndefiniteValue();class iuStopWatch{private: TimeInMillisec m_begin;public: iuStopWatch():m_begin(0){}public: static TimeInMillisec get_millisec(){return GetTimeInMillis();}public: void start(){m_begin=get_millisec();}TimeInMillisec stop()const{return get_millisec()-m_begin;}};}}namespace iutest{namespace detail{inline bool Localtime(time_t sec,struct tm* dst){return localtime_r(&sec,dst)!=0;}inline ::std::string FormatTimeInMillisec(TimeInMillisec msec){iu_stringstream ss;ss<<msec;return ss.str();}inline ::std::string FormatTimeInMillisecAsSecond(TimeInMillisec msec){iu_stringstream ss;ss<<static_cast<double>(msec)*1e-3;return ss.str();}inline ::std::string FormatTimeInMillisecAsIso8601(TimeInMillisec msec){time_t sec=static_cast<time_t>(msec / 1000);struct tm t;if(!Localtime(sec,&t)){return FormatTimeInMillisecAsSecond(msec);}iu_stringstream ss;ss<<(t.tm_year+1900);return ss.str()+"-"+ FormatIntWidth2(t.tm_mon+1)+"-"+ FormatIntWidth2(t.tm_mday)+"T"+ FormatIntWidth2(t.tm_hour)+":"+ FormatIntWidth2(t.tm_min)+":"+ FormatIntWidth2(t.tm_sec);}inline time_t GetTime(){return time(0);}inline TimeInMillisec GetTimeInMillis(){
#ifdef IUTEST_GetMillisec
return IUTEST_GetMillisec();
#elif IUTEST_HAS_CXX_HDR_CHRONO
return ::std::chrono::duration_cast< ::std::chrono::milliseconds >(::std::chrono::high_resolution_clock::now().time_since_epoch()).count();
#elif 1
timeval tv;gettimeofday(&tv,0);return static_cast<TimeInMillisec>(tv.tv_sec) * 1000+static_cast<TimeInMillisec>(tv.tv_usec) / 1000;
#endif
}inline unsigned int GetIndefiniteValue(){static unsigned int s=static_cast<unsigned int>(GetTimeInMillis());s=s*1664525+1013904223;return s;}}}
#if IUTEST_HAS_CXX_HDR_RANDOM
#include <random>
#endif
namespace iutest{namespace detail{class iuRandom{
#if IUTEST_HAS_CXX_HDR_RANDOM&&defined(IUTEST_USE_RANDOM_ENGINE_TYPENAME)
typedef IUTEST_USE_RANDOM_ENGINE_TYPENAME Engine;
#else
class Engine{public: typedef unsigned int result_type;public: explicit Engine(unsigned int s=0) II_CXX_NEX_S{seed(s);}result_type operator()(){return gen();}bool operator==(const Engine& rhs){return m_v1==rhs.m_v1&&m_v2==rhs.m_v2&&m_v3==rhs.m_v3&&m_v4==rhs.m_v4;}bool operator!=(const Engine& rhs){return m_v1!=rhs.m_v1||m_v2!=rhs.m_v2||m_v3!=rhs.m_v3||m_v4!=rhs.m_v4;}public: void seed(unsigned int s){m_v4=s;m_v3=1812433253 *((m_v4 ^(m_v4>>30))+1);m_v2=1812433253 *((m_v3 ^(m_v3>>30))+2);m_v1=1812433253 *((m_v2 ^(m_v2>>30))+3);}void discard(unsigned int z){for(unsigned int i=0;i<z;++i){gen();}}public:static II_CXX_C_O_C result_type _Min=0;static II_CXX_C_O_C result_type _Max=static_cast<result_type>(-1);static II_CXX_CE result_type(min)(){return 0;}static II_CXX_CE result_type(max)(){return static_cast<result_type>(-1);}private: result_type gen(){const unsigned int t=(m_v1 ^(m_v1<<11));m_v1=m_v2;m_v2=m_v3;m_v3=m_v4;m_v4=(m_v4 ^(m_v4>>19)) ^(t ^(t>>8));return m_v4;}private: unsigned int m_v1,m_v2,m_v3,m_v4;};
#endif
Engine m_engine;public: typedef unsigned int result_type;static II_CXX_CE result_type(min)(){return(Engine::min)();}static II_CXX_CE result_type(max)(){return(Engine::max)();}
#if defined(__clang__)&&(__clang_major__<3 ||(__clang_major__==3 && __clang_minor__<3))
static II_CXX_C_O_C result_type _Min=Engine::_Min;static II_CXX_C_O_C result_type _Max=Engine::_Max;
#endif
public: iuRandom(){init();}explicit iuRandom(unsigned int seed){init(seed);}public: void init(){init(GetIndefiniteValue());}void init(unsigned int seed){m_engine=Engine(seed);}public: result_type genrand(){return m_engine();}result_type genrand(unsigned int max){
#if IUTEST_HAS_CXX_HDR_RANDOM
::std::uniform_int_distribution<unsigned int> d(0,max-1);return d(m_engine);
#else
return genrand()%max;
#endif
}template<typename T>T genrand(T max){
#if IUTEST_HAS_CXX_HDR_RANDOM
::std::uniform_int_distribution<T> d(0,max-1);return d(m_engine);
#else
return genrand<T>()%max;
#endif
}float genrandf(){
#if IUTEST_HAS_CXX_HDR_RANDOM
return ::std::uniform_real_distribution<float>(0.0f,1.0f)(m_engine);
#else
return static_cast<float>(genrand())*(1.0f/4294967295.0f);
#endif
}template<typename T>T genrand(){return static_cast<T>(genrand(static_cast<unsigned int>(static_cast<T>(-1))));}public: result_type operator()(){return genrand();}result_type operator()(unsigned int max){return genrand(max);}public: template<typename It>void shuffle(It first,It last){
#if IUTEST_HAS_CXX_HDR_RANDOM
::std::shuffle(first,last,m_engine);
#else
::std::random_shuffle(first,last,*this);
#endif
}};
#define II_WA_GENRAND(type) template<> inline type iuRandom::genrand<type>()
II_WA_GENRAND(Int64){return(static_cast<Int64>(genrand())<<32)|genrand();}II_WA_GENRAND(UInt64){return(static_cast<UInt64>(genrand())<<32)|genrand();}II_WA_GENRAND(float){return genrandf();}II_WA_GENRAND(double){return static_cast<double>(genrandf());}
#undef II_WA_GENRAND
template<typename T>class iuTypedRandom{typedef T result_type;public: iuTypedRandom(){}explicit iuTypedRandom(unsigned int seed):m_rnd(seed){}result_type operator()(){return genrand();}result_type operator()(result_type max){return genrand(max);}result_type genrand(){return m_rnd.genrand<result_type>();}result_type genrand(result_type max){return m_rnd.genrand(max);}private: iuRandom m_rnd;};}}
#if IUTEST_HAS_CXX_HDR_REGEX
#include <regex>
#endif
namespace iutest{namespace detail{class iuFilterRegex{static bool match_impl(const char* begin,const char* end,const char* src);static bool match_impl_list(const char* begin,const char* end,const char* src);public: static bool match(const char* regex,const char* src);};
#if IUTEST_HAS_CXX_HDR_REGEX
class iuRegex{public: iuRegex(const char* pattern){Init(pattern);}iuRegex(const ::std::string& pattern){Init(pattern.c_str());}iuRegex(const iuRegex&rhs):m_re(rhs.m_re),m_pattern(rhs.m_pattern){}public: bool FullMatch(const char* str)const;bool PartialMatch(const char* str)const;const char* pattern()const{return m_pattern.c_str();}private: void Init(const char* pattern);private: ::std::regex m_re;::std::string m_pattern;IP_DIS_A(iuRegex);};
#endif
}namespace internal{
#if IUTEST_HAS_CXX_HDR_REGEX
class RE:public detail::iuRegex{public: RE(const char* pattern):detail::iuRegex(pattern){}RE(const ::std::string& pattern):detail::iuRegex(pattern){}public: static bool FullMatch(const ::std::string& str,const RE& re){return FullMatch(str.c_str(),re);}static bool PartialMatch(const ::std::string& str,const RE& re){return PartialMatch(str.c_str(),re);}static bool FullMatch(const char* str,const RE& re){const detail::iuRegex& r=re;return r.FullMatch(str);}static bool PartialMatch(const char* str,const RE& re){const detail::iuRegex& r=re;return r.PartialMatch(str);}};
#endif
}}namespace iutest{namespace detail{inline bool iuFilterRegex::match_impl(const char* begin,const char* end,const char* src){const char* tp=begin;if(*tp=='\0'){return false;}while(tp!=end){if(*tp=='*'){++tp;while(*tp=='*'){++tp;}if(tp==end){return true;}{const char nc=*tp;if(nc=='\0'){return true;}for(;;){while(*src!=nc){++src;if(*src=='\0'){return false;}}if(match_impl(tp+1,end,++src)){return true;}}}}else if(*tp=='?'){if(*src=='\0'){return false;}}else{if(*tp!=*src){return false;}}++tp;++src;}if(*src!='\0'){return false;}return true;}inline bool iuFilterRegex::match_impl_list(const char* begin,const char* end,const char* src){const char* tp=begin;const char* end2=tp;while(end2!=end){++end2;while(*end2!=':' && end2!=end){++end2;}if(match_impl(tp,end2,src)){return true;}tp=end2;if(*tp==':'){++tp;}}return false;}inline bool iuFilterRegex::match(const char* regex,const char* src){const char* tp=regex;const char* end=tp;while(*end!='\0' && *end!='-'){++end;}if(*end=='-'){if(tp!=end&&!match_impl_list(tp,end,src)){return false;}tp=end+1;while(*end!='\0'){++end;}if(match_impl_list(tp,end,src)){return false;}return true;}return match_impl_list(tp,end,src);}
#if IUTEST_HAS_CXX_HDR_REGEX
inline bool iuRegex::FullMatch(const char* str)const{return(str!=0)?::std::regex_match(str,m_re):false;}inline bool iuRegex::PartialMatch(const char* str)const{return(str!=0)?::std::regex_search(str,m_re):false;}inline void iuRegex::Init(const char* str){m_re.assign(str);m_pattern=str;}
#endif
}}namespace iutest{class UnitTest;class TestInfo;class TestCase;class TestPartResult;class TestProperty;class TestEventListener;namespace detail{class DefaultGlobalTestPartResultReporter;template<typename T,typename ::std::string(*GetXmlPath)()>class StderrXmlGeneratorListenerBase;}class TestEventListener{IP_DIS_C_A_A(TestEventListener);public: TestEventListener(){}virtual ~TestEventListener(){}public: virtual void OnTestProgramStart(const UnitTest& test)=0;virtual void OnTestIterationStart(const UnitTest& test,int iteration)=0;virtual void OnEnvironmentsSetUpStart(const UnitTest& test)=0;virtual void OnEnvironmentsSetUpEnd(const UnitTest& test)=0;virtual void OnTestCaseStart(const TestCase& test_case)=0;virtual void OnTestStart(const TestInfo& test_info)=0;virtual void OnTestPartResult(const TestPartResult& test_part_result)=0;virtual void OnTestRecordProperty(const TestProperty&){}virtual void OnTestEnd(const TestInfo& test_info)=0;virtual void OnTestCaseEnd(const TestCase& test_case)=0;virtual void OnEnvironmentsTearDownStart(const UnitTest& test)=0;virtual void OnEnvironmentsTearDownEnd(const UnitTest& test)=0;virtual void OnTestIterationEnd(const UnitTest& test,int iteration)=0;virtual void OnTestProgramEnd(const UnitTest& test)=0;};class EmptyTestEventListener:public TestEventListener{public: virtual void OnTestProgramStart(const UnitTest&) II_CXX_O{}virtual void OnTestIterationStart(const UnitTest&,int) II_CXX_O{}virtual void OnEnvironmentsSetUpStart(const UnitTest&) II_CXX_O{}virtual void OnEnvironmentsSetUpEnd(const UnitTest&) II_CXX_O{}virtual void OnTestCaseStart(const TestCase&) II_CXX_O{}virtual void OnTestStart(const TestInfo&) II_CXX_O{}virtual void OnTestPartResult(const TestPartResult&) II_CXX_O{}virtual void OnTestRecordProperty(const TestProperty&) II_CXX_O{}virtual void OnTestEnd(const TestInfo&) II_CXX_O{}virtual void OnTestCaseEnd(const TestCase&) II_CXX_O{}virtual void OnEnvironmentsTearDownStart(const UnitTest&) II_CXX_O{}virtual void OnEnvironmentsTearDownEnd(const UnitTest&) II_CXX_O{}virtual void OnTestIterationEnd(const UnitTest&,int) II_CXX_O{}virtual void OnTestProgramEnd(const UnitTest&) II_CXX_O{}};class TestEventRepeater:public TestEventListener{typedef ::std::vector<TestEventListener*> ListenerContainer;public: void Append(TestEventListener* listener){m_listeners.push_back(listener);}TestEventListener* Release(TestEventListener* listener);public: virtual void OnTestProgramStart(const UnitTest& test) II_CXX_O;virtual void OnTestIterationStart(const UnitTest& test,int iteration) II_CXX_O;virtual void OnEnvironmentsSetUpStart(const UnitTest& test) II_CXX_O;virtual void OnEnvironmentsSetUpEnd(const UnitTest& test) II_CXX_O;virtual void OnTestCaseStart(const TestCase& test_case) II_CXX_O;virtual void OnTestStart(const TestInfo& test_info) II_CXX_O;virtual void OnTestPartResult(const TestPartResult& test_part_result) II_CXX_O;virtual void OnTestRecordProperty(const TestProperty& test_property) II_CXX_O;virtual void OnTestEnd(const TestInfo& test_info) II_CXX_O;virtual void OnTestCaseEnd(const TestCase& test_case) II_CXX_O;virtual void OnEnvironmentsTearDownStart(const UnitTest& test) II_CXX_O;virtual void OnEnvironmentsTearDownEnd(const UnitTest& test) II_CXX_O;virtual void OnTestIterationEnd(const UnitTest& test,int iteration) II_CXX_O;virtual void OnTestProgramEnd(const UnitTest& test) II_CXX_O;private: ListenerContainer m_listeners;};class TestEventListeners{typedef ::std::vector<TestEventListener*> ListenerContainer;public: TestEventListeners():m_default_result_printer(0),m_default_xml_generator(0){}public: void Append(TestEventListener* listener){m_repeater.Append(listener);}TestEventListener* Release(TestEventListener* listener){return m_repeater.Release(listener);}public: TestEventListener* default_result_printer()const II_CXX_NEX_S{return m_default_result_printer;}TestEventListener* default_xml_generator()const II_CXX_NEX_S{return m_default_xml_generator;}private: TestEventListener* repeater(){return &m_repeater;}void OnTestProgramStart(const UnitTest& test){m_repeater.OnTestProgramStart(test);}void OnTestIterationStart(const UnitTest& test,int iteration){m_repeater.OnTestIterationStart(test,iteration);}void OnEnvironmentsSetUpStart(const UnitTest& test){m_repeater.OnEnvironmentsSetUpStart(test);}void OnEnvironmentsSetUpEnd(const UnitTest& test){m_repeater.OnEnvironmentsSetUpEnd(test);}void OnTestCaseStart(const TestCase& test_case){m_repeater.OnTestCaseStart(test_case);}void OnTestStart(const TestInfo& test_info){m_repeater.OnTestStart(test_info);}void OnTestPartResult(const TestPartResult& test_part_result){m_repeater.OnTestPartResult(test_part_result);}void OnTestRecordProperty(const TestProperty& test_property){m_repeater.OnTestRecordProperty(test_property);}void OnTestEnd(const TestInfo& test_info){m_repeater.OnTestEnd(test_info);}void OnTestCaseEnd(const TestCase& test_case){m_repeater.OnTestCaseEnd(test_case);}void OnEnvironmentsTearDownStart(const UnitTest& test){m_repeater.OnEnvironmentsTearDownStart(test);}void OnEnvironmentsTearDownEnd(const UnitTest& test){m_repeater.OnEnvironmentsTearDownEnd(test);}void OnTestIterationEnd(const UnitTest& test,int iteration){m_repeater.OnTestIterationEnd(test,iteration);}void OnTestProgramEnd(const UnitTest& test){m_repeater.OnTestProgramEnd(test);}private: void set_default_result_printer(TestEventListener* listener);void set_default_xml_generator(TestEventListener* listener);private: friend class UnitTestSource;friend class UnitTestImpl;friend class UnitTest;friend class TestInfo;friend class TestCase;friend class Test;friend class detail::DefaultGlobalTestPartResultReporter;friend class DefaultXmlGeneratorListener;friend class JunitXmlGeneratorListener;friend class DefaultResultPrintListener;template<typename T,typename ::std::string(*GetXmlPath)()>friend class detail::StderrXmlGeneratorListenerBase;TestEventRepeater m_repeater;TestEventListener* m_default_result_printer;TestEventListener* m_default_xml_generator;};}namespace iutest{inline TestEventListener* TestEventRepeater::Release(TestEventListener* listener){ListenerContainer::iterator it=::std::find(m_listeners.begin(),m_listeners.end(),listener);if(it==m_listeners.end()){return 0;}m_listeners.erase(it);return listener;}inline void TestEventRepeater::OnTestProgramStart(const UnitTest& test){for(ListenerContainer::iterator it=m_listeners.begin(),end=m_listeners.end();it!=end;++it){(*it)->OnTestProgramStart(test);}}inline void TestEventRepeater::OnTestIterationStart(const UnitTest& test,int iteration){for(ListenerContainer::iterator it=m_listeners.begin(),end=m_listeners.end();it!=end;++it){(*it)->OnTestIterationStart(test,iteration);}}inline void TestEventRepeater::OnEnvironmentsSetUpStart(const UnitTest& test){for(ListenerContainer::iterator it=m_listeners.begin(),end=m_listeners.end();it!=end;++it){(*it)->OnEnvironmentsSetUpStart(test);}}inline void TestEventRepeater::OnEnvironmentsSetUpEnd(const UnitTest& test){for(ListenerContainer::reverse_iterator it=m_listeners.rbegin(),end=m_listeners.rend();it!=end;++it){(*it)->OnEnvironmentsSetUpEnd(test);}}inline void TestEventRepeater::OnTestCaseStart(const TestCase& test_case){for(ListenerContainer::iterator it=m_listeners.begin(),end=m_listeners.end();it!=end;++it){(*it)->OnTestCaseStart(test_case);}}inline void TestEventRepeater::OnTestStart(const TestInfo& test_info){for(ListenerContainer::iterator it=m_listeners.begin(),end=m_listeners.end();it!=end;++it){(*it)->OnTestStart(test_info);}}inline void TestEventRepeater::OnTestPartResult(const TestPartResult& test_part_result){for(ListenerContainer::iterator it=m_listeners.begin(),end=m_listeners.end();it!=end;++it){(*it)->OnTestPartResult(test_part_result);}}inline void TestEventRepeater::OnTestRecordProperty(const TestProperty& test_property){for(ListenerContainer::iterator it=m_listeners.begin(),end=m_listeners.end();it!=end;++it){(*it)->OnTestRecordProperty(test_property);}}inline void TestEventRepeater::OnTestEnd(const TestInfo& test_info){for(ListenerContainer::reverse_iterator it=m_listeners.rbegin(),end=m_listeners.rend();it!=end;++it){(*it)->OnTestEnd(test_info);}}inline void TestEventRepeater::OnTestCaseEnd(const TestCase& test_case){for(ListenerContainer::reverse_iterator it=m_listeners.rbegin(),end=m_listeners.rend();it!=end;++it){(*it)->OnTestCaseEnd(test_case);}}inline void TestEventRepeater::OnEnvironmentsTearDownStart(const UnitTest& test){for(ListenerContainer::iterator it=m_listeners.begin(),end=m_listeners.end();it!=end;++it){(*it)->OnEnvironmentsTearDownStart(test);}}inline void TestEventRepeater::OnEnvironmentsTearDownEnd(const UnitTest& test){for(ListenerContainer::reverse_iterator it=m_listeners.rbegin(),end=m_listeners.rend();it!=end;++it){(*it)->OnEnvironmentsTearDownEnd(test);}}inline void TestEventRepeater::OnTestIterationEnd(const UnitTest& test,int iteration){for(ListenerContainer::reverse_iterator it=m_listeners.rbegin(),end=m_listeners.rend();it!=end;++it){(*it)->OnTestIterationEnd(test,iteration);}}inline void TestEventRepeater::OnTestProgramEnd(const UnitTest& test){for(ListenerContainer::reverse_iterator it=m_listeners.rbegin(),end=m_listeners.rend();it!=end;++it){(*it)->OnTestProgramEnd(test);}}inline void TestEventListeners::set_default_result_printer(TestEventListener* listener){delete Release(m_default_result_printer);if(listener!=0){Append(listener);}m_default_result_printer=listener;}inline void TestEventListeners::set_default_xml_generator(TestEventListener* listener){delete Release(m_default_xml_generator);if(listener!=0){Append(listener);}m_default_xml_generator=listener;}}
#define IUTEST_FLAG(name) II_FLAG(name)
#define II_FLAG(name) TestEnv::name()
namespace iutest{inline ::std::string EnvironmentString(const char* name){::std::string var;detail::GetEnvironmentVariable(name,var);return var;}class Environment{public: virtual ~Environment(){Release();}virtual void SetUp(){}virtual void TearDown(){}private: void Release();private: struct should_be_SetUp{};virtual should_be_SetUp* Setup() II_CXX_F{return 0;}};class TestFlag{public: class ScopedGuard{IP_DIS_C_A_A(ScopedGuard);int m_test_flags;public: ScopedGuard(){m_test_flags=TestFlag::GetInstance().m_test_flags;}~ScopedGuard(){TestFlag::GetInstance().m_test_flags=m_test_flags;}};public: enum Kind{SHUFFLE_TESTS=1,RUN_DISABLED_TESTS=2,FILTERING_TESTS=4,BREAK_ON_FAILURE=0x10,THROW_ON_FAILURE=0x40,WARNING_INTO_ERROR=0x80,CONSOLE_COLOR_ON=0x100,CONSOLE_COLOR_OFF=0x200,CONSOLE_COLOR_ANSI=0x400,PRINT_TIME=0x1000,FILELOCATION_STYLE_MSVC=0x2000,VERBOSE=0x4000,CATCH_EXCEPTION_EACH=0x10000,CATCH_EXCEPTION_GLOBAL=0x20000,CATCH_EXCEPTION=0x30000,SHOW_HELP=0x1000000,SHOW_VERSION=0x2000000,SHOW_FEATURE=0x4000000,SHOW_SPEC=0x8000000,SHOW_TESTS_LIST=0x20000000,SHOW_TESTS_LIST_WITH_WHERE= 0x40000000,SHOW_INFO_MASK=0xF000000,SHOW_MASK=0x7F000000,MASK=0x7FFFFFFF,DEFAULT=CATCH_EXCEPTION|PRINT_TIME};private: TestFlag() II_CXX_NEX_S: m_test_flags(DEFAULT){}public: static TestFlag& GetInstance(){static TestFlag flag;return flag;}public: static void SetFlag(int enable,int mask=-1){GetInstance().m_test_flags|=enable;GetInstance().m_test_flags&=mask;}static bool IsEnableFlag(int flag){return GetInstance().m_test_flags&flag?true:false;}private: template<int KIND>class Fragment{typedef Fragment<KIND> _Myt;public: Fragment() II_CXX_NEX_S{}Fragment(bool enabled){SetFlag(KIND,enabled?-1 : ~KIND);}_Myt& operator=(bool enabled){SetFlag(KIND,enabled?-1 : ~KIND);return *this;}operator bool()const{return IsEnableFlag(KIND);}};private: friend class TestEnv;int m_test_flags;};class TestPartResultReporterInterface;class TestEnv{typedef ::std::vector<Environment*> iuEnvironmentList;public: typedef TestFlag::Fragment<TestFlag::SHUFFLE_TESTS> shuffle;typedef TestFlag::Fragment<TestFlag::RUN_DISABLED_TESTS> also_run_disabled_tests;typedef TestFlag::Fragment<TestFlag::BREAK_ON_FAILURE> break_on_f;typedef TestFlag::Fragment<TestFlag::CATCH_EXCEPTION> catch_exceptions;typedef TestFlag::Fragment<TestFlag::THROW_ON_FAILURE> throw_on_f;typedef TestFlag::Fragment<TestFlag::WARNING_INTO_ERROR> warning_into_error;typedef TestFlag::Fragment<TestFlag::PRINT_TIME> print_time;typedef TestFlag::Fragment<TestFlag::SHOW_TESTS_LIST> list_tests;typedef TestFlag::Fragment<TestFlag::SHOW_TESTS_LIST_WITH_WHERE> list_tests_with_where;typedef TestFlag::Fragment<TestFlag::CATCH_EXCEPTION_EACH> catch_exceptions_each;typedef TestFlag::Fragment<TestFlag::CATCH_EXCEPTION_GLOBAL> catch_exceptions_global;typedef TestFlag::Fragment<TestFlag::FILELOCATION_STYLE_MSVC> file_location_style_msvc;typedef TestFlag::Fragment<TestFlag::VERBOSE> verbose;typedef class RandomSeedSet{public: RandomSeedSet() II_CXX_NEX_S{}RandomSeedSet(unsigned int seed){init_random(seed);}RandomSeedSet& operator=(unsigned int seed){init_random(seed);return *this;}operator unsigned int()const{return get_random_seed();}}random_seed;typedef class RepeatCountSet{public: RepeatCountSet() II_CXX_NEX_S{}RepeatCountSet(int count){set_repeat_count(count);}RepeatCountSet& operator=(int count){set_repeat_count(count);return *this;}operator int()const{return get_repeat_count();}}repeat;private: struct Variable{Variable():m_random_seed(0),m_current_random_seed(0),m_before_origin_random_seed(0),m_repeat_count(1),m_testpartresult_reporter(0){}unsigned int m_random_seed;unsigned int m_current_random_seed;unsigned int m_before_origin_random_seed;int m_repeat_count;::std::string m_output_option;::std::string m_test_filter;::std::string m_flagfile;
#if IUTEST_HAS_STREAM_RESULT
::std::string m_stream_result_to;
#endif
::std::string m_default_package_name;detail::iuRandom m_genrand;iuEnvironmentList m_environment_list;TestEventListeners m_event_listeners;TestPartResultReporterInterface* m_testpartresult_reporter;iu_stringstream m_ostream_formatter;::std::string m_locale_ctype;};static Variable& get_vars(){static Variable sVars;return sVars;}public: static detail::iuRandom& genrand(){return get_vars().m_genrand;}static unsigned int get_random_seed(){return get_vars().m_random_seed;}static unsigned int current_random_seed(){return get_vars().m_current_random_seed;}static int get_repeat_count(){return get_vars().m_repeat_count;}static const char* get_output_option(){return get_vars().m_output_option.c_str();}static const char* get_default_package_name(){return get_vars().m_default_package_name.c_str();}static const char* test_filter(){return get_vars().m_test_filter.c_str();}static const char* get_flagfile(){return get_vars().m_flagfile.c_str();}
#if IUTEST_HAS_STREAM_RESULT
static const char* get_stream_result_to(){return get_vars().m_stream_result_to.c_str();}
#endif
static void global_ostream_copyfmt(iu_ostream& os){os.copyfmt(get_vars().m_ostream_formatter);}static const char* get_locale_ctype(){return get_vars().m_locale_ctype.c_str();}static bool is_specific_locale_ctype(){return !get_vars().m_locale_ctype.empty();}static ::std::string get_report_xml_filepath();static ::std::string get_report_junit_xml_filepath();static TestEventListeners& event_listeners(){return get_vars().m_event_listeners;}static TestPartResultReporterInterface* GetGlobalTestPartResultReporter(){return get_vars().m_testpartresult_reporter;}static void SetGlobalTestPartResultReporter(TestPartResultReporterInterface* ptr){get_vars().m_testpartresult_reporter=ptr;}static bool has_output_option(){return !get_vars().m_output_option.empty();}private: static void init_random(unsigned int seed){get_vars().m_random_seed=seed;}static void set_repeat_count(int count){get_vars().m_repeat_count=count;}static void set_test_filter(const char* str){get_vars().m_test_filter=str==0?"*":str;TestFlag::SetFlag(TestFlag::FILTERING_TESTS);}static void set_flagfile_path(const char* str){get_vars().m_flagfile=str;}static void set_flagfile(const char* str){ParseFlagFileOption(str);LoadFlagFile();}
#if IUTEST_HAS_STREAM_RESULT
static void set_stream_result_to(const char* str){get_vars().m_stream_result_to=detail::NullableString(str);}
#endif
static const char* get_color_option(){if(TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ANSI)){return "ansi";}else if(TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ON)){return "yes";}else if(TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_OFF)){return "no";}return "auto";}static void set_color_option(const char* str){ParseColorOption(str);}static void set_output_option(const char* str){get_vars().m_output_option=detail::NullableString(str);}static void set_default_package_name(const char* str){get_vars().m_default_package_name=detail::NullableString(str);}static void set_locale_ctype(const char* str){get_vars().m_locale_ctype=detail::NullableString(str);}private: typedef const char*(*pfnOptionStringGet)();typedef void(*pfnOptionStringSet)(const char*);template<pfnOptionStringGet G,pfnOptionStringSet S>class OptionString{typedef OptionString<G,S> _Myt;typedef const _Myt& _Argt;protected: ::std::string m_option;public: friend bool operator==(const char* c_str_,_Argt rhs){return rhs.m_option==c_str_;}friend bool operator==(const ::std::string& str,_Argt rhs){return rhs.m_option==str;}friend bool operator==(_Argt lhs,const char* c_str_){return lhs.m_option==c_str_;}friend bool operator==(_Argt lhs,const ::std::string& str){return lhs.m_option==str;}friend bool operator!=(const char* c_str_,_Argt rhs){return rhs.m_option!=c_str_;}friend bool operator!=(const ::std::string& str,_Argt rhs){return rhs.m_option!=str;}friend bool operator!=(_Argt lhs,const char* c_str_){return lhs.m_option!=c_str_;}friend bool operator!=(_Argt lhs,const ::std::string& str){return lhs.m_option!=str;}operator ::std::string()const{return m_option;}public: bool empty()const{return m_option.empty();}const char* c_str()const{return m_option.c_str();}size_t length()const{return m_option.length();}public: OptionString():m_option(G()){}const _Myt& operator=(const char* c_str_){m_option=detail::NullableString(c_str_);S(c_str_);return *this;}const _Myt& operator=(const ::std::string& str){m_option=str;S(str.c_str());return *this;}};public: typedef OptionString<get_color_option,set_color_option> color;typedef OptionString<test_filter,set_test_filter> filter;typedef OptionString<get_flagfile,set_flagfile> flagfile;typedef OptionString<get_output_option,set_output_option> output;
#if IUTEST_HAS_STREAM_RESULT
typedef OptionString<get_stream_result_to,set_stream_result_to> stream_result_to;
#endif
typedef OptionString<get_default_package_name,set_default_package_name> default_package_name;typedef OptionString<get_locale_ctype,set_locale_ctype> locale_ctype;typedef class OStreamFormatter:public iu_stringstream{public: OStreamFormatter(){copyfmt(get_vars().m_ostream_formatter);}virtual ~OStreamFormatter(){get_vars().m_ostream_formatter.copyfmt(*this);}}ostream_formatter;private: static iuEnvironmentList& environments(){return get_vars().m_environment_list;}public: static Environment* AddGlobalTestEnvironment(Environment* env){if(env==0){return 0;}environments().push_back(env);return env;}static Environment* ReleaseGlobalTestEnvironment(Environment* env){if(env==0){return 0;}iuEnvironmentList& list=environments();iuEnvironmentList::iterator it=::std::find(list.begin(),list.end(),env);if(it==list.end()){return 0;}list.erase(it);return env;}static ::std::string AddDefaultPackageName(const char* t_c_name);private: static void ReleaseGlobalTestEnvironment(){for(iuEnvironmentList::iterator it=environments().begin();it!=environments().end();){Environment* p=*it;it=environments().erase(it);delete p;}}public: template<typename CharType>static void ParseCommandLine(int* pargc,CharType** argv){if(argv==0){return;}int argc=*pargc;for(int i=0;i<argc;){if(ParseCommandLineElem(argv[i])){--argc;for(int k=i;k<argc;++k){CharType* tmp=argv[k];argv[k]=argv[k+1];argv[k+1]=tmp;}}else{++i;}}*pargc=argc;}template<typename CharType>static void ParseCommandLine(::std::vector< ::std::basic_string<CharType> >& argv){typedef ::std::vector< ::std::basic_string<CharType> > argv_t;for(typename argv_t::iterator it=argv.begin();it!=argv.end();){if(ParseCommandLineElem(it->c_str())){it=argv.erase(it);}else{++it;}}}static bool LoadFlagFile();private: template<typename CharType>static bool ParseCommandLineElem(CharType* argv){typedef typename detail::mbs_ptr<CharType> formatter;formatter argv_format;const char* str=argv_format.ptr(argv);return ParseCommandLineElemA(str);}static bool ParseCommandLineElemA(const char* str);static bool ParseIutestOptionCommandLineElemA(const char* str);static bool SetFlag(int enable,int mask=-1);private: static void LoadEnvironmentVariable();static void SetUp();private: static inline const char* ParseOptionSettingStr(const char* opt){const char* eq=strchr(opt,'=');if(eq==0){return 0;}return eq+1;}static bool ParseColorOption(const char* option);static bool ParseOutputOption(const char* option);static bool ParseFileLocationOption(const char* option);static bool ParseFilterOption(const char* option);static bool ParseFlagFileOption(const char* option);static bool ParseYesNoFlagCommandLine(const char* str,TestFlag::Kind flag,int def);static int ParseYesNoOption(const char* option);static bool IsYes(const char* option);static bool IsNo(const char* option);private: friend class UnitTest;};class iu_global_format_stringstream:public iu_stringstream{public: iu_global_format_stringstream(){TestEnv::global_ostream_copyfmt(*this);}explicit iu_global_format_stringstream(const char* str):iu_stringstream(str){TestEnv::global_ostream_copyfmt(*this);}explicit iu_global_format_stringstream(const ::std::string& str):iu_stringstream(str){TestEnv::global_ostream_copyfmt(*this);}};}namespace iutest{namespace detail{class IOutStream{public: virtual ~IOutStream(){}public: virtual bool Write(const void* buf,size_t size,size_t cnt)=0;public: virtual int Printf(const char* fmt,...) II_ATR_F_P(2,3){va_list va;va_start(va,fmt);const ::std::string str=StringFormat(fmt,va);va_end(va);const size_t len=str.length();Write(str.c_str(),len,1);return static_cast<int>(len);}};class IInStream{public: virtual ~IInStream(){}public: virtual bool Read(void* buf,size_t size,size_t cnt)=0;virtual size_t GetSize()=0;public: virtual ::std::string ReadAll(){::std::string str;const size_t size=GetSize();if(size!=0){char* buf=new char[size+1];buf[size]='\0';if(Read(buf,size,1)){str=buf;}delete [] buf;}return str;}};class FileOutStream:public IOutStream{protected: FILE* m_fp;public: explicit FileOutStream(FILE* fp) II_CXX_NEX_S: m_fp(fp){}public: virtual bool Write(const void* buf,size_t size,size_t cnt) II_CXX_O{if(fwrite(buf,size,cnt,m_fp)<cnt){return false;}return true;}};}class IFile:public detail::IOutStream,public detail::IInStream{public: enum OpenFlag{OpenRead=1,OpenWrite=2,OpenAppend=3};public: virtual ~IFile(){}public: bool Open(const char* filename,int mode){return OpenImpl(filename,mode);}
#if IUTEST_HAS_STD_FILESYSTEM
bool Open(const ::std::filesystem::path& path,int mode){return Open(path.string().c_str(),mode);}
#endif
virtual void Close()=0;private: virtual bool OpenImpl(const char* filename,int mode)=0;};namespace detail{class IFileSystem{public: IFileSystem(){SetInstance(this);}virtual ~IFileSystem(){SetInstance(0);}public: virtual void Initialize(){}public: static IFileSystem* GetInstance(){return GetInstanceVariable().pInstance;}public: static IFile* New(){IFileSystem* fs=GetInstance();if(fs==0){return 0;}IFile* p=fs->Create();return p;}static void Free(IFile* ptr){IFileSystem* fs=GetInstance();if(fs==0){return;}fs->Delete(ptr);}static bool ReadAll(const char* filename,::std::string& dst){IFile* fp=detail::IFileSystem::New();if(fp==0){return false;}if(!fp->Open(filename,IFile::OpenRead)){detail::IFileSystem::Free(fp);return false;}dst=fp->ReadAll();detail::IFileSystem::Free(fp);return true;}private: virtual IFile* Create()=0;virtual void Delete(IFile*)=0;private: struct InstanceVariable{IFileSystem* pInstance;};static InstanceVariable& GetInstanceVariable(){static InstanceVariable v;return v;}static void SetInstance(IFileSystem* pFileSystem){GetInstanceVariable().pInstance=pFileSystem;}};}}namespace iutest{template<typename FILE>class FileSystem:public detail::IFileSystem{private: virtual IFile* Create() II_CXX_O{return new FILE;}virtual void Delete(IFile* ptr) II_CXX_O{detail::Delete<FILE>(static_cast<FILE*>(ptr));}};class StdioFile:public IFile{protected: FILE* m_fp;public: StdioFile() II_CXX_NEX_S:m_fp(0){}virtual ~StdioFile(){Close();}public: virtual void Close() II_CXX_O{if(m_fp!=0){fclose(m_fp);m_fp=0;}}virtual bool Write(const void* buf,size_t size,size_t cnt) II_CXX_O{if(fwrite(buf,size,cnt,m_fp)<cnt){return false;}if(fflush(m_fp)!=0){return false;}return true;}virtual bool Read(void* buf,size_t size,size_t cnt) II_CXX_O{if(fread(buf,size,cnt,m_fp)<cnt){return false;}return true;}virtual size_t GetSize() II_CXX_O{return GetSize(m_fp);}public: static size_t GetSize(FILE* fp){if(fp==0){return 0;}internal::posix::StatStruct st;if(internal::posix::Stat(fp,&st)!=0){return GetSizeBySeekSet(fp);}return static_cast<size_t>(st.st_size);}static size_t GetSizeBySeekSet(FILE* fp){if(fp==0){return 0;}const long pre=ftell(fp);if((pre!=-1)&&(fseek(fp,0,SEEK_END)==0)){const size_t size=static_cast<size_t>(ftell(fp));IUTEST_UNUSED_RETURN(fseek(fp,pre,SEEK_SET));return size;}return 0;}private: virtual bool OpenImpl(const char* filename,int mode) II_CXX_O{Close();switch(mode){case IFile::OpenRead: m_fp=fopen(filename,"rb");break;case IFile::OpenWrite: m_fp=fopen(filename,"wb");break;case IFile::OpenAppend: m_fp=fopen(filename,"ab");break;default: break;}return m_fp!=0;}};class StdErrorFile:public StdioFile{public: StdErrorFile() II_CXX_NEX_S{}virtual ~StdErrorFile(){Close();}public: virtual void Close() II_CXX_O{m_fp=0;}private: virtual bool OpenImpl(const char*,int) II_CXX_O{m_fp=stderr;return true;}};class StringStreamFile:public IFile{public: virtual ~StringStreamFile(){Close();}public: virtual void Close() II_CXX_O{}virtual bool Write(const void* buf,size_t size,size_t cnt) II_CXX_O{for(size_t i=0;i<cnt;++i){ss.write(static_cast<const char*>(buf),size);}return true;}virtual bool Read(void* buf,size_t size,size_t cnt) II_CXX_O{char* p=static_cast<char*>(buf);for(size_t i=0;i<cnt;++i){ss.read(p,size);p+=size;}return true;}virtual size_t GetSize() II_CXX_O{::std::stringstream::pos_type pre=ss.tellg();ss.seekg(0,::std::ios::end);::std::stringstream::pos_type size=ss.tellg();ss.seekg(pre,::std::ios::beg);return static_cast<size_t>(size);}virtual ::std::string ReadAll() II_CXX_O{return ss.str();}private: virtual bool OpenImpl(const char*,int) II_CXX_O{ss.clear();return true;}protected: ::std::stringstream ss;};namespace detail{class NoEffectFile:public IFile{public: virtual void Close() II_CXX_O{}virtual bool Write(const void*,size_t,size_t) II_CXX_O{return true;}virtual bool Read(void*,size_t,size_t) II_CXX_O{return true;}virtual size_t GetSize() II_CXX_O{return 0;}private: virtual bool OpenImpl(const char*,int) II_CXX_O{return true;}};}}namespace iutest{inline void Environment::Release(){TestEnv::ReleaseGlobalTestEnvironment(this);}inline ::std::string TestEnv::get_report_xml_filepath(){const ::std::string& option=get_vars().m_output_option;const char spec[]="xml";const size_t length=sizeof(spec)-1;if(option.compare(0,length,spec)==0){if((option.length()> length+1)&&(option.at(length)==':')){return option.substr(length+1);}return detail::kStrings::DefaultXmlReportFileName;}return "";}inline::std::string TestEnv::get_report_junit_xml_filepath(){const ::std::string& option=get_vars().m_output_option;const char spec[]="junit";const size_t length=sizeof(spec)-1;if(option.compare(0,length,spec)==0){if((option.length()> length+1)&&(option.at(length)==':')){return option.substr(length+1);}return detail::kStrings::DefaultXmlReportFileName;}return "";}inline::std::string TestEnv::AddDefaultPackageName(const char* t_c_name){::std::string str=TestEnv::get_default_package_name();if(str.empty()){return t_c_name;}if(strchr(t_c_name,'.')!=0){return t_c_name;}str+=".";str+=t_c_name;return str;}inline bool TestEnv::ParseCommandLineElemA(const char* str){if(*str=='-'){++str;if(*str=='-'){++str;bool iuoption=false;{const char* const base_str=str;if(*str=='g'){++str;iuoption=true;}if(*str=='i' && *(str+1)=='u'){str+=2;iuoption=true;}const char option_prefix[]="test_";for(int i=0,size=sizeof(option_prefix)/sizeof(option_prefix[0])-1;i<size;++i,++str){if(*str!=option_prefix[i]){iuoption=false;str=base_str;break;}}}if(iuoption){if(ParseIutestOptionCommandLineElemA(str)){return true;}TestFlag::SetFlag(TestFlag::SHOW_HELP);}else{if(detail::IsStringEqual(str,"help")){return SetFlag(TestFlag::SHOW_HELP);}if(detail::IsStringEqual(str,"version")){return SetFlag(TestFlag::SHOW_VERSION);}if(detail::IsStringEqual(str,"feature")){return SetFlag(TestFlag::SHOW_FEATURE);}if(detail::IsStringEqual(str,"spec")){return SetFlag(TestFlag::SHOW_SPEC);}if(detail::IsStringEqual(str,"verbose")){return SetFlag(TestFlag::VERBOSE);}}}else{if(detail::IsStringEqual(str,"v")){return SetFlag(TestFlag::SHOW_VERSION);}if(detail::IsStringEqual(str,"h")|| detail::IsStringEqual(str,"?")){return SetFlag(TestFlag::SHOW_HELP);}}}return false;}inline bool TestEnv::ParseIutestOptionCommandLineElemA(const char* str){if(detail::IsStringForwardMatching(str,"output")){return ParseOutputOption(ParseOptionSettingStr(str));}if(detail::IsStringEqual(str,"list_tests")){return SetFlag(TestFlag::SHOW_TESTS_LIST);}if(detail::IsStringEqual(str,"list_tests_with_where")){return SetFlag(TestFlag::SHOW_TESTS_LIST_WITH_WHERE);}if(detail::IsStringForwardMatching(str,"color")){return ParseColorOption(ParseOptionSettingStr(str));}if(detail::IsStringEqual(str,"shuffle")){return SetFlag(TestFlag::SHUFFLE_TESTS);}if(detail::IsStringForwardMatching(str,"random_seed")){const char* opt=ParseOptionSettingStr(str);if(opt!=0){char* end=0;const long seed=strtol(opt,&end,0);init_random(static_cast<unsigned int>(seed));return true;}}if(detail::IsStringEqual(str,"also_run_disabled_tests")){return SetFlag(TestFlag::RUN_DISABLED_TESTS);}if(detail::IsStringForwardMatching(str,"break_on_f")){return ParseYesNoFlagCommandLine(str,TestFlag::BREAK_ON_FAILURE,1);}if(detail::IsStringForwardMatching(str,"catch_exceptions")){return ParseYesNoFlagCommandLine(str,TestFlag::CATCH_EXCEPTION,-1);}if(detail::IsStringForwardMatching(str,"throw_on_f")){return ParseYesNoFlagCommandLine(str,TestFlag::THROW_ON_FAILURE,1);}if(detail::IsStringForwardMatching(str,"warning_into_error")){return ParseYesNoFlagCommandLine(str,TestFlag::WARNING_INTO_ERROR,1);}if(detail::IsStringForwardMatching(str,"print_time")){return ParseYesNoFlagCommandLine(str,TestFlag::PRINT_TIME,-1);}if(detail::IsStringForwardMatching(str,"repeat")){const char* opt=ParseOptionSettingStr(str);if(opt!=0){char* end=0;const long count=strtol(opt,&end,0);set_repeat_count(static_cast<int>(count));return true;}}if(detail::IsStringForwardMatching(str,"filter")){return ParseFilterOption(ParseOptionSettingStr(str));}if(detail::IsStringForwardMatching(str,"flagfile")){return ParseFlagFileOption(ParseOptionSettingStr(str));}
#if IUTEST_HAS_STREAM_RESULT
if(detail::IsStringForwardMatching(str,"stream_result_to")){const char* opt=ParseOptionSettingStr(str);if(opt!=0){set_stream_result_to(opt);return true;}}
#endif
if(detail::IsStringForwardMatching(str,"file_location")){return ParseFileLocationOption(ParseOptionSettingStr(str));}if(detail::IsStringForwardMatching(str,"default_package_name")){const char* opt=ParseOptionSettingStr(str);if(opt!=0){set_default_package_name(opt);return true;}}if(detail::IsStringForwardMatching(str,"locale_ctype")){const char* opt=ParseOptionSettingStr(str);set_locale_ctype(opt);return true;}return false;}inline bool TestEnv::SetFlag(int enable,int mask){TestFlag::SetFlag(enable,mask);return true;}inline void TestEnv::LoadEnvironmentVariable(){}inline void TestEnv::SetUp(){unsigned int seed=get_random_seed();if((seed==0)||(get_vars().m_current_random_seed!=0&&TestFlag::IsEnableFlag(TestFlag::SHUFFLE_TESTS))){const unsigned int gen_seeed=detail::GetIndefiniteValue();if(get_vars().m_current_random_seed==gen_seeed|| get_vars().m_before_origin_random_seed==gen_seeed){seed=get_vars().m_current_random_seed;}seed+=gen_seeed;get_vars().m_before_origin_random_seed=gen_seeed;}get_vars().m_current_random_seed=seed;genrand().init(seed);}inline bool TestEnv::ParseColorOption(const char* option){if(option==0){return false;}if(IsYes(option)){TestFlag::SetFlag(TestFlag::CONSOLE_COLOR_ON,~(TestFlag::CONSOLE_COLOR_OFF|TestFlag::CONSOLE_COLOR_ANSI));}else if(IsNo(option)){TestFlag::SetFlag(TestFlag::CONSOLE_COLOR_OFF,~(TestFlag::CONSOLE_COLOR_ON|TestFlag::CONSOLE_COLOR_ANSI));}else if(detail::IsStringCaseEqual(option,"auto")){TestFlag::SetFlag(0,~(TestFlag::CONSOLE_COLOR_ON|TestFlag::CONSOLE_COLOR_OFF|TestFlag::CONSOLE_COLOR_ANSI));}else if(detail::IsStringCaseEqual(option,"ansi")){TestFlag::SetFlag(TestFlag::CONSOLE_COLOR_ON|TestFlag::CONSOLE_COLOR_ANSI,~TestFlag::CONSOLE_COLOR_OFF);}else{return false;}return true;}inline bool TestEnv::ParseOutputOption(const char* option){if(option==0){get_vars().m_output_option="";return false;}get_vars().m_output_option=option;return true;}inline bool TestEnv::ParseFileLocationOption(const char* option){if(option==0){return false;}if(detail::IsStringCaseEqual(option,"auto")){TestFlag::SetFlag(0,~TestFlag::FILELOCATION_STYLE_MSVC);}else if(detail::IsStringCaseEqual(option,"vs")){TestFlag::SetFlag(TestFlag::FILELOCATION_STYLE_MSVC);}else if(detail::IsStringCaseEqual(option,"gcc")){TestFlag::SetFlag(0,~TestFlag::FILELOCATION_STYLE_MSVC);}else{return false;}return true;}inline bool TestEnv::ParseFilterOption(const char* option){if(option!=0&&*option=='@'){const char* path=option+1;::std::string filter;if(!detail::IFileSystem::ReadAll(path,filter)){fprintf(stderr,"Unable to open filter file \"%s\".\n",path);fflush(stderr);return false;}detail::StringReplaceToLF(filter);filter=detail::StringRemoveComment(filter);detail::StringReplace(filter,'\n',":");set_test_filter(filter.c_str());return true;}set_test_filter(option);return true;}inline bool TestEnv::ParseFlagFileOption(const char* option){if(option==0||option[0]=='\0'){return false;}set_flagfile_path(option);return true;}inline bool TestEnv::LoadFlagFile(){const char* path=get_flagfile();if(path==0||path[0]=='\0'){return true;}::std::string flags;if(!detail::IFileSystem::ReadAll(path,flags)){fprintf(stderr,"Unable to open flag file \"%s\".\n",path);fflush(stderr);return false;}detail::StringReplaceToLF(flags);::std::vector< ::std::string>argv;detail::StringSplit(flags,'\n',argv);ParseCommandLine(argv);return true;}inline bool TestEnv::ParseYesNoFlagCommandLine(const char* str,TestFlag::Kind flag,int def){const char* option=ParseOptionSettingStr(str);const int yesno=option!=0?ParseYesNoOption(option):def;if(yesno<0){return false;}TestFlag::SetFlag(flag,yesno?TestFlag::MASK : ~(flag));return true;}inline int TestEnv::ParseYesNoOption(const char* option){if(option!=0){if(IsYes(option)){return 1;}if(IsNo(option)){return 0;}}return -1;}inline bool TestEnv::IsYes(const char* option){if(detail::IsStringCaseEqual(option,"yes")|| detail::IsStringCaseEqual(option,"y")|| detail::IsStringCaseEqual(option,"on")|| detail::IsStringCaseEqual(option,"true")|| detail::IsStringCaseEqual(option,"t")|| detail::IsStringEqual(option,"1")){return true;}return false;}inline bool TestEnv::IsNo(const char* option){if(detail::IsStringCaseEqual(option,"no")|| detail::IsStringCaseEqual(option,"n")|| detail::IsStringCaseEqual(option,"off")|| detail::IsStringCaseEqual(option,"false")|| detail::IsStringCaseEqual(option,"f")|| detail::IsStringEqual(option,"0")){return true;}return false;}}namespace iutest{template<typename T>std::string PrintToString(const T& v);namespace detail{inline void PrintBytesInObjectTo(const unsigned char* buf,size_t size,iu_ostream* os){const size_t kMaxCount=detail::kValues::MaxPrintContainerCount;*os<<size<<"-Byte object < ";if(buf!=IUTEST_NULLPTR&&size>0){for(size_t i=0;i<size;++i){if(i==kMaxCount){*os<<"... ";break;}const unsigned char n=buf[i];*os<<ToHex((n>>4)&0xF)<<ToHex(n&0xF)<<" ";}}*os<<">";}namespace printer_internal{namespace formatter{template<bool convertible>struct Printer{template<typename T>static void Print(const T& value,iu_ostream* os){const unsigned char* ptr=const_cast<const unsigned char*>(reinterpret_cast<const volatile unsigned char*>(&value));const size_t size=sizeof(T);PrintBytesInObjectTo(ptr,size,os);}};template<>struct Printer<true>{template<typename T>static void Print(const T& value,iu_ostream* os){const BiggestInt v=value;*os<<v;}};}class TypeWithoutFormatter{public: template<typename T>static void PrintValue(const T& value,iu_ostream* os){formatter::Printer<iutest_type_traits::is_convertible<const T&,BiggestInt>::value>::Print(value,os);}};template<typename Elem,typename Traits,typename T>::std::basic_ostream<Elem,Traits>& operator<<(::std::basic_ostream<Elem,Traits>& os,const T& value){TypeWithoutFormatter::PrintValue(value,&os);return os;}}namespace printer_internal2{template<typename T>void DefaultPrintNonContainerTo(const T& value,iu_ostream* os){using namespace ::iutest::detail::printer_internal;*os<<value;}}template<typename T>void UniversalPrint(const T& value,iu_ostream* os);template<typename T>inline void DefaultPrintTo(IsContainerHelper::yes_t,iutest_type_traits::false_type,const T& container,iu_ostream* os){const size_t kMaxCount=kValues::MaxPrintContainerCount;size_t count=0;*os<<"{";for(typename T::const_iterator it=container.begin(),end=container.end();it!=end;++it,++count){if(count>0){*os<<",";if(count==kMaxCount){*os<<" ...";break;}}*os<<" ";UniversalPrint(*it,os);}if(count>0){*os<<" ";}*os<<"}";}template<typename T>inline void DefaultPrintNonContainerTo(const T& value,iu_ostream* os){printer_internal2::DefaultPrintNonContainerTo(value,os);}template<typename T>inline void DefaultPrintTo(IsContainerHelper::no_t,iutest_type_traits::false_type,const T& value,iu_ostream* os){DefaultPrintNonContainerTo(value,os);}template<typename T>inline void DefaultPtrPrintTo(T* ptr,iu_ostream* os,typename iutest_type_traits::enable_if_t<iutest_type_traits::is_convertible<T*,const void*> >::type*& = iutest_type_traits::enabler::value){*os<<reinterpret_cast<iu_uintptr_t>(ptr);}template<typename T>inline void DefaultPtrPrintTo(T* ptr,iu_ostream* os,typename iutest_type_traits::disable_if_t<iutest_type_traits::is_convertible<T*,const void*> >::type*& = iutest_type_traits::enabler::value){*os<<reinterpret_cast<const void*>(reinterpret_cast<type_least_t<8>::UInt>(ptr));}template<typename T>inline void DefaultPrintTo(IsContainerHelper::no_t,iutest_type_traits::true_type,T* ptr,iu_ostream* os){if(ptr==IUTEST_NULLPTR){*os<<kStrings::Null;}else{DefaultPtrPrintTo<T>(ptr,os);}}template<typename T>inline void II_ATR_U UniversalTersePrint(const T& value,iu_ostream* os){UniversalPrint(value,os);}inline void II_ATR_U UniversalTersePrint(const char* str,iu_ostream* os){if(str==IUTEST_NULLPTR){*os<<kStrings::Null;}else{UniversalPrint(::std::string(str),os);}}template<size_t N>void II_ATR_U UniversalTersePrint(const char(&str)[N],iu_ostream* os){return UniversalTersePrint(static_cast<const char*>(str),os);}inline void II_ATR_U UniversalTersePrint(const wchar_t* str,iu_ostream* os){UniversalPrint(detail::ShowAnyCString(str),os);}template<size_t N>void II_ATR_U UniversalTersePrint(const wchar_t(&str)[N],iu_ostream* os){UniversalPrint(detail::ShowAnyCString(str),os);}
#if IUTEST_HAS_CHAR16_T
inline void II_ATR_U UniversalTersePrint(const char16_t* str,iu_ostream* os){UniversalPrint(detail::ShowAnyCString(str),os);}template<size_t N>void II_ATR_U UniversalTersePrint(const char16_t(&str)[N],iu_ostream* os){UniversalPrint(detail::ShowAnyCString(str),os);}
#endif
#if IUTEST_HAS_CHAR32_T&&(IUTEST_HAS_CXX_HDR_CUCHAR||IUTEST_HAS_CXX_HDR_CODECVT)
inline void II_ATR_U UniversalTersePrint(const char32_t* str,iu_ostream* os){UniversalPrint(detail::ShowAnyCString(str),os);}template<size_t N>void II_ATR_U UniversalTersePrint(const char32_t(&str)[N],iu_ostream* os){UniversalPrint(detail::ShowAnyCString(str),os);}
#endif
template<typename T>inline void PrintTo(const T& value,iu_ostream* os){DefaultPrintTo(IsContainerHelper::IsContainer<T>(0),iutest_type_traits::is_pointer<T>(),value,os);}inline void PrintTo(bool b,iu_ostream* os){*os<<(b?"true" : "false");}inline void PrintTo(const char* c,iu_ostream* os){*os<<c;}inline void PrintTo(const ::std::string& str,iu_ostream* os){*os<<str.c_str();}template<typename CharT,typename Traits,typename Alloc>inline void PrintTo(const ::std::basic_string<CharT,Traits,Alloc>& str,iu_ostream* os){UniversalTersePrint(str.c_str(),os);}template<typename T>inline void PrintTo(const floating_point<T>& f,iu_ostream* os){iu_stringstream ss;ss<<::std::setprecision(::std::numeric_limits<T>::digits10+2)<<f.raw();*os<<ss.str()<<"(0x" <<ToHexString(f.bits())<<")";}template<typename T1,typename T2>inline void PrintTo(const ::std::pair<T1,T2>& value,iu_ostream* os){*os<<"(";UniversalPrint(value.first,os);*os<<", ";UniversalPrint(value.second,os);*os<<")";}template<typename T>void PrintToChar(const T value,iu_ostream* os){if(value==0){*os<<"\\0";}else if(value<0x20){*os<<static_cast<int>(value);}else{const T str[2]={value,0};*os<<"\'" <<detail::ShowAnyCString(str)<<"\'";}}inline void PrintTo(const char value,iu_ostream* os){PrintToChar(value,os);}inline void PrintTo(const wchar_t value,iu_ostream* os){PrintToChar(value,os);}
#if IUTEST_HAS_CHAR16_T
inline void PrintTo(const char16_t value,iu_ostream* os){PrintToChar(value,os);}
#endif
#if IUTEST_HAS_CHAR32_T
inline void PrintTo(const char32_t value,iu_ostream* os){PrintToChar(value,os);}
#endif
inline void PrintTo(const unsigned char value,iu_ostream* os){*os<<static_cast<unsigned int>(value);}
#if IUTEST_HAS_CXX_HDR_STRING_VIEW
template<typename CharT,typename Traits>inline void PrintTo(const ::std::basic_string_view<CharT,Traits>& value,iu_ostream* os){const ::std::basic_string<CharT,Traits> str{value};UniversalTersePrint(str.c_str(),os);}
#endif
#if IUTEST_HAS_CXX_HDR_OPTIONAL
template<typename T>inline void PrintTo(const ::std::optional<T>& value,iu_ostream* os){if(value){UniversalPrint(value.value(),os);}else{*os<<"nullopt";}}
#endif
#if IUTEST_HAS_CXX_HDR_VARIANT
template<typename... Types>inline void PrintTo(const ::std::variant<Types...>& value,iu_ostream* os){if(value.valueless_by_exception()){*os<<"valueless_by_exception";}else{std::visit([&os](const auto& v){UniversalPrint(v,os);},value);}}inline void PrintTo(const ::std::monostate&,iu_ostream* os){*os<<"monostate";}
#endif
#if IUTEST_HAS_CXX_HDR_ANY
inline void PrintTo(const ::std::any& value,iu_ostream* os){*os<<"-Any type-name: " <<value.type().name();DefaultPrintNonContainerTo(value,os);}
#endif
#if IUTEST_HAS_STD_FILESYSTEM
inline ::std::string FileSystemFileTypeToString(const ::std::filesystem::file_type& value){switch(value){IP_NS_E_C_R_S(::std::filesystem::file_type,none);IP_NS_E_C_R_S(::std::filesystem::file_type,not_found);IP_NS_E_C_R_S(::std::filesystem::file_type,regular);IP_NS_E_C_R_S(::std::filesystem::file_type,directory);IP_NS_E_C_R_S(::std::filesystem::file_type,symlink);IP_NS_E_C_R_S(::std::filesystem::file_type,block);IP_NS_E_C_R_S(::std::filesystem::file_type,character);IP_NS_E_C_R_S(::std::filesystem::file_type,fifo);IP_NS_E_C_R_S(::std::filesystem::file_type,socket);IP_NS_E_C_R_S(::std::filesystem::file_type,unknown);default: break;}return PrintToString(static_cast<int>(value));}template<>inline void PrintTo<::std::filesystem::path>(const ::std::filesystem::path& value,iu_ostream* os){*os<<value.generic_string();}inline void PrintTo(const ::std::filesystem::file_type& value,iu_ostream* os){*os<<FileSystemFileTypeToString(value);}inline void PrintTo(const ::std::filesystem::perms& value,iu_ostream* os){*os<<ToOctString(static_cast<UInt16>(value));}inline void PrintTo(const ::std::filesystem::file_status& value,iu_ostream* os){*os<<FileSystemFileTypeToString(value.type())<<": ";PrintTo(value.permissions(),os);}inline void PrintTo(const ::std::filesystem::space_info& value,iu_ostream* os){*os<<"cpacity: " <<detail::FormatSizeByte(value.capacity)<< ", free: " <<detail::FormatSizeByte(value.free)<< ", available: " <<detail::FormatSizeByte(value.available);}inline void PrintTo(const ::std::filesystem::directory_entry& value,iu_ostream* os){PrintTo(value.path(),os);}inline void PrintTo(const ::std::filesystem::directory_iterator& value,iu_ostream* os){PrintTo(*value,os);}
#endif
#if IUTEST_HAS_NULLPTR
inline void PrintTo(const ::std::nullptr_t&,iu_ostream* os){*os<<"nullptr";}
#endif
#if IUTEST_HAS_TUPLE
template<typename T,int I,int SIZE>inline void PrintTupleElemTo(const T& t,iu_ostream* os,typename iutest_type_traits::enable_if<I==0,void>::type*& = iutest_type_traits::enabler::value){(void)(t);(void)(os);}template<typename T,int I,int SIZE>inline void PrintTupleElemTo(const T& t,iu_ostream* os,typename iutest_type_traits::enable_if<I==1,void>::type*& = iutest_type_traits::enabler::value){PrintTo(tuples::get<SIZE-I>(t),os);}template<typename T,int I,int SIZE>inline void PrintTupleElemTo(const T& t,iu_ostream* os,typename iutest_type_traits::enable_if<(I&(~1))!=0,void>::type*& = iutest_type_traits::enabler::value){PrintTo(tuples::get<SIZE-I>(t),os);*os<<", ";PrintTupleElemTo<T,I-1,SIZE>(t,os);}template<typename T>inline void PrintTupleTo(const T& t,iu_ostream* os){*os<<"(";PrintTupleElemTo<T,tuples::tuple_size<T>::value,tuples::tuple_size<T>::value>(t,os);*os<<")";}
#if IUTEST_HAS_VARIADIC_TEMPLATES&&IUTEST_HAS_TUPLE
template<typename ...Args>inline void PrintTo(const tuples::tuple<Args...>& t,iu_ostream* os){PrintTupleTo(t,os);}
#else
#define II_D_T_PT(n) template<IP_ENM_P(n,typename A)>inline void PrintTo(const tuples::tuple<IP_ENM_P(n,A)>& t,iu_ostream* os){PrintTupleTo(t,os);}
inline void PrintTo(const tuples::tuple<>& t,iu_ostream* os){PrintTupleTo(t,os);}II_D_T_PT(1)II_D_T_PT(2)II_D_T_PT(3)II_D_T_PT(4)II_D_T_PT(5)II_D_T_PT(6)II_D_T_PT(7)II_D_T_PT(8)II_D_T_PT(9)
#undef II_D_T_PT
#endif
#endif
template<typename T>inline void PrintRawArrayTo(const T* a,size_t cnt,iu_ostream* os){UniversalPrint<T>(a[0],os);for(size_t i=1;i<cnt;++i){*os<<", ";UniversalPrint<T>(a[i],os);}}template<typename T>inline void II_ATR_U UniversalPrintArray(const T* begin,size_t N,iu_ostream* os){if(N==0){*os<<"{}";}else{*os<<"{ ";const size_t kThreshold=kValues::PrintArrayThreshold;const size_t kChunksize=kValues::PrintArrayChunksize;if(N<=kThreshold){PrintRawArrayTo(begin,N,os);}else{PrintRawArrayTo(begin,kChunksize,os);*os<<", ..., ";PrintRawArrayTo(begin+N - kChunksize,kChunksize,os);}*os<<" }";}}inline void II_ATR_U UniversalPrintArray(const char* begin,size_t N,iu_ostream* os){(void)(N);UniversalTersePrint(begin,os);}inline void II_ATR_U UniversalPrintArray(const wchar_t* begin,size_t N,iu_ostream* os){(void)(N);UniversalTersePrint(begin,os);}template<typename T>inline void II_ATR_U UniversalPrintTo(const T& value,iu_ostream* os){PrintTo(value,os);}template<typename T>class iuUniversalPrinter{public: static void Print(const T& value,iu_ostream* os){UniversalPrintTo(value,os);}};template<typename T,size_t SIZE>class iuUniversalPrinter<T[SIZE]>{public: static void Print(const T(&a)[SIZE],iu_ostream* os){UniversalPrintArray(a,SIZE,os);}};template<typename T>inline void UniversalPrint(const T& value,iu_ostream* os){iuUniversalPrinter<T>::Print(value,os);}}template<typename T>inline ::std::string PrintToString(const T& v){iu_global_format_stringstream strm;detail::UniversalTersePrint(v,&strm);return strm.str();}
#if IUTEST_HAS_VARIADIC_TEMPLATES
template<typename T>inline ::std::string PrintToStrings(const char* separate,const T& v){(void)(separate);return PrintToString(v);}template<typename T,typename ...Args>inline ::std::string PrintToStrings(const char* separate,const T& v,Args... args){::std::string str=PrintToString(v);str+=separate;str+=PrintToStrings(separate,args...);return str;}
#endif
}namespace iutest{namespace detail{::std::string FormatFileLocation(const char* file,int line);::std::string FormatCompilerIndependentFileLocation(const char* file,int line);class iuStreamMessage{public: iuStreamMessage(){}explicit iuStreamMessage(const char* message):m_stream(message){}iuStreamMessage(const iuStreamMessage& rhs):m_stream(rhs.GetString()){}public: ::std::string GetString()const{return m_stream.str();}public: template<typename T>iuStreamMessage& operator<<(const T& value){m_stream<<PrintToString(value);return *this;}template<typename T,size_t SIZE>iuStreamMessage& operator<<(const T(&value)[SIZE]){m_stream<<PrintToString(value);return *this;}iuStreamMessage& operator<<(iu_basic_iomanip val){m_stream<<val;return *this;}public: void add_message(const char* str){append(str);}private: void append(const char* str);private: iuStreamMessage& operator=(const iuStreamMessage&);private: iu_global_format_stringstream m_stream;};inline iu_ostream& operator<<(iu_ostream& os,const iuStreamMessage& msg){return os<<msg.GetString();}class iuCodeMessage{::std::string m_message;const char* m_file;int m_line;public: iuCodeMessage(const char* file,int line,const char* message):m_message(message),m_file(file?file:kStrings::UnknownFile),m_line(line){}iuCodeMessage(const char* file,int line,const iuStreamMessage& message):m_message(message.GetString()),m_file(file?file:kStrings::UnknownFile),m_line(line){}public: const char* message()const{return m_message.c_str();}const char* file_name()const II_CXX_NEX_S{return m_file;}int line_number()const II_CXX_NEX_S{return m_line;}public: template<typename T>iuCodeMessage& operator<<(const T& value){m_message+=(iuStreamMessage()<<value).GetString();return *this;}public: void add_message(const ::std::string& str);public: ::std::string make_message()const;::std::string make_newline_message()const{return make_message()+"\n";}};}}namespace iutest{namespace detail{inline void iuStreamMessage::append(const char* str){if(str==0){m_stream<<kStrings::Null;}else{m_stream<<str;}}inline ::std::string iuCodeMessage::make_message()const{::std::string str=FormatFileLocation(m_file,m_line);str+=": ";str+=message();return str;}inline ::std::string FormatFileLocation(const char* file,int line){const char* const file_name=file==0?kStrings::UnknownFile:file;if(line<0){return file_name;}iu_stringstream strm;if(TestFlag::IsEnableFlag(TestFlag::FILELOCATION_STYLE_MSVC)){strm<<file_name<<"(" <<line<<")";}else{strm<<file_name<<":" <<line;}return strm.str();}inline ::std::string FormatCompilerIndependentFileLocation(const char* file,int line){const char* const file_name=file==0?kStrings::UnknownFile:file;if(line<0){return file_name;}iu_stringstream strm;strm<<file_name<<":" <<line;return strm.str();}inline void iuCodeMessage::add_message(const ::std::string& str){m_message+=str;}}namespace detail{class DefaultGlobalTestPartResultReporter;}class TestPartResultReporterInterface{public: virtual ~TestPartResultReporterInterface(){}virtual void ReportTestPartResult(const TestPartResult& result)=0;};class TestPartResult:public detail::iuCodeMessage{public: enum Type{kAssumeFailure=-3,kSkip=-2,kWarning=-1,kSuccess,kNonFatalFailure,kFatalFailure};public: TestPartResult(const char* file,int line,const char* message,Type type):detail::iuCodeMessage(file,line,message),m_type(type){}public: static bool type_is_failed(Type type) II_CXX_NEX_S{if(iutest::IUTEST_FLAG(warning_into_error)){if(type==kWarning){return true;}}return type>kSuccess;}public: bool failed()const II_CXX_NEX_S{return type_is_failed(m_type);;}bool passed()const II_CXX_NEX_S{return !failed();}bool warning()const II_CXX_NEX_S{return m_type==kWarning;}bool skipped()const II_CXX_NEX_S{return m_type==kSkip;}bool assume_failed()const II_CXX_NEX_S{return m_type==kAssumeFailure;}bool succeeded()const II_CXX_NEX_S{return m_type==kSuccess;}bool nonfatally_failed()const II_CXX_NEX_S{return m_type==kNonFatalFailure;}bool fatally_failed()const II_CXX_NEX_S{return m_type==kFatalFailure;}const char* summary()const{return message();}Type type()const II_CXX_NEX_S{return m_type;}private: Type m_type;};inline iu_ostream& operator<<(iu_ostream& os,const TestPartResult& result){return os<<result.make_message();}class TestProperty{public: TestProperty(const ::std::string& key,const ::std::string& value):m_key(key),m_value(value){}public: void SetValue(const ::std::string& value){m_value=value;}const char* key()const{return m_key.c_str();}const char* value()const{return m_value.c_str();}public: bool Validate(const char** ban_list,size_t size)const{return ValidateName(m_key,ban_list,ban_list+size);}template<typename Ite>static bool ValidateName(const ::std::string& name,Ite begin,Ite end){return ::std::find(begin,end,name)==end;}template<typename T,size_t N>static bool ValidateName(const ::std::string& name,T(&ar)[N]){return ValidateName(name,ar,ar+N);}private: friend class TestResult;::std::string m_key;::std::string m_value;};class TestResult{typedef ::std::vector<TestPartResult> TestPartResults;typedef ::std::vector<TestProperty> TestPropertys;public: TestResult():m_elapsedmsec(0){}public: bool Passed()const{return !Failed();}bool Failed()const{for(TestPartResults::const_iterator it=m_test_part_results.begin(),end=m_test_part_results.end();it!=end;++it){if(it->failed()){return true;}}return false;}bool Skipped()const{for(TestPartResults::const_iterator it=m_test_part_results.begin(),end=m_test_part_results.end();it!=end;++it){if(it->skipped()||it->assume_failed()){return Passed();}}return false;}bool HasFatalFailure()const{return HasResult(TestPartResult::kFatalFailure);}bool HasNonfatalFailure()const{return HasResult(TestPartResult::kNonFatalFailure);}bool HasAssumeFailure()const{return HasResult(TestPartResult::kAssumeFailure);}bool HasWarning()const{return HasResult(TestPartResult::kWarning);}TimeInMillisec elapsed_time()const II_CXX_NEX_S{return m_elapsedmsec;}int total_part_count()const{return static_cast<int>(m_test_part_results.size());}int test_property_count()const{return static_cast<int>(m_test_propertys.size());}const TestPartResult& GetTestPartResult(int index)const{return m_test_part_results[index];}const TestProperty& GetTestProperty(int index)const{return m_test_propertys[index];}public: int total_error_count()const{int count=0;for(TestPartResults::const_iterator it=m_test_part_results.begin(),end=m_test_part_results.end();it!=end;++it){if(it->failed()){++count;}}return count;}private: void AddTestPartResult(const TestPartResult& result){m_test_part_results.push_back(result);}void set_elapsed_time(TimeInMillisec time) II_CXX_NEX_S{m_elapsedmsec=time;}private: void RecordProperty(const TestProperty& prop){for(TestPropertys::iterator it=m_test_propertys.begin(),end=m_test_propertys.end();it!=end;++it){if(detail::IsStringEqual(it->key(),prop.key())){it->m_value=prop.m_value;return;}}m_test_propertys.push_back(prop);}void ClearResult(){m_test_part_results.clear();}void Clear(){m_test_part_results.clear();m_test_propertys.clear();m_elapsedmsec=0;}bool HasResult(TestPartResult::Type eType)const{for(TestPartResults::const_iterator it=m_test_part_results.begin(),end=m_test_part_results.end();it!=end;++it){if(it->type()==eType){return true;}}return false;}private: friend class UnitTestImpl;friend class TestInfo;friend class TestCase;friend class detail::DefaultGlobalTestPartResultReporter;TestPartResults m_test_part_results;TestPropertys m_test_propertys;TimeInMillisec m_elapsedmsec;IP_DIS_C_A_A(TestResult);};}
#include <list>
namespace iutest{namespace detail{II_PGM_W_PU()II_PGM_W_D_NE_T()template<typename It>void RandomShuffle(It begin,It last,iuRandom& r){r.shuffle(begin,last);}template<typename T,typename Fn>void RandomShuffle(::std::vector<T>& list,Fn& r){RandomShuffle(list.begin(),list.end(),r);}template<typename T,typename Fn>T FindList(const ::std::vector<T>& list,Fn& f){for(typename ::std::vector<T>::const_iterator it=list.begin(),end=list.end();it!=end;++it){if(f(*it)){return *it;}}return 0;}template<typename T,typename Fn>int CountIf(const ::std::vector<T>& list,Fn f){int count=0;for(typename ::std::vector<T>::const_iterator it=list.begin(),end=list.end();it!=end;++it){if(f(*it)){++count;}}return count;}template<typename T,typename Fn>int SumOverList(const ::std::vector<T>& list,Fn f){int count=0;for(typename ::std::vector<T>::const_iterator it=list.begin(),end=list.end();it!=end;++it){count+=((*it)->*f)();}return count;}template<typename T,typename Fn>int CountIfOverList(const ::std::vector<T>& list,Fn f){int count=0;for(typename ::std::vector<T>::const_iterator it=list.begin(),end=list.end();it!=end;++it){if(((*it)->*f)()){++count;}}return count;}template<typename T,typename Fn>bool AnyOverList(const ::std::vector<T>& list,Fn f){for(typename ::std::vector<T>::const_iterator it=list.begin(),end=list.end();it!=end;++it){if(((*it)->*f)()){return true;}}return false;}II_PGM_W_PP()}}namespace iutest{typedef detail::iuStreamMessage Message;template<typename T>inline ::std::string StreamableToString(const T& value){return(Message()<<value).GetString();}namespace detail{void DefaultReportTestPartResult(const TestPartResult& test_part_result);}class AssertionResult{public: AssertionResult(bool result):m_result(result){}AssertionResult(const AssertionResult& rhs):m_message(rhs.m_message),m_result(rhs.m_result){}bool failed()const II_CXX_NEX_S{return !m_result;}bool passed()const II_CXX_NEX_S{return m_result;}const char* message()const{return m_message.c_str();}const char* failure_message()const{return message();}II_CXX_E_C operator bool()const{return m_result;}public: template<typename T>AssertionResult& operator<<(const T& value){Message msg;msg<<value;m_message+=msg.GetString();return *this;}public: AssertionResult operator !()const{return AssertionResult(failed())<<message();}AssertionResult operator&&(const AssertionResult& rhs)const{return AssertionResult(m_result&&rhs.passed())<<message()<<" && " <<rhs.message();}AssertionResult operator||(const AssertionResult& rhs)const{return AssertionResult(m_result||rhs.passed())<<message()<<" || " <<rhs.message();}public: static AssertionResult Success(){return AssertionResult(true);}static AssertionResult Failure(){return AssertionResult(false);}template<typename T>static AssertionResult Is(const T& b){return AssertionResult(b?true:false);}static AssertionResult Is(const AssertionResult& ar){return AssertionResult(ar);}private: IP_DIS_A(AssertionResult);::std::string m_message;bool m_result;};template<typename R>struct AssertionReturnType{R value;AssertionReturnType(){}AssertionReturnType(const R& v):value(v){}};template<>struct AssertionReturnType<void>{AssertionReturnType(){}};template<typename T>inline AssertionReturnType<T> AssertionReturn(const T& ret){return AssertionReturnType<T>(ret);}inline AssertionReturnType<void> AssertionReturn(void){return AssertionReturnType<void>();}class AssertionHelper{public: AssertionHelper(const char* file,int line,const char* message,TestPartResult::Type type):m_part_result(file,line,message,type){}AssertionHelper(const char* file,int line,const ::std::string& message,TestPartResult::Type type):m_part_result(file,line,message.c_str(),type){}public: class ScopedMessage: public detail::iuCodeMessage{public: ScopedMessage(const detail::iuCodeMessage& msg):detail::iuCodeMessage(msg){ScopedTrace::GetInstance().list.push_back(this);}~ScopedMessage(){ScopedTrace::GetInstance().list.remove(this);}};private: class ScopedTrace{public:typedef ::std::list<ScopedMessage*> msg_list;msg_list list;static ScopedTrace& GetInstance(){static ScopedTrace inst;return inst;}public: void append_message(TestPartResult& part_result){if(list.size()){part_result.add_message("\niutest trace:");for(msg_list::iterator it=list.begin(),end=list.end();it!=end;++it){part_result.add_message("\n");part_result.add_message((*it)->make_message().c_str());}}}};private: template<typename R>struct ReturnTypedFixed;public: class Fixed:public Message{public: template<typename T>Fixed& operator<<(T val){Message::operator<<(val);return *this;}template<typename T,size_t SIZE>Fixed& operator<<(const T(&val)[SIZE]){Message::operator<<(val);return *this;}Fixed& operator<<(iu_basic_iomanip val){Message::operator<<(val);return *this;}Fixed& operator<<(const AssertionReturnType<void>&){return *this;}template<typename R>ReturnTypedFixed<R> operator<<(const AssertionReturnType<R>& ret){return ReturnTypedFixed<R>(*this,ret);}};private: template<typename R>struct ReturnTypedFixed{Fixed fixed;AssertionReturnType<R> ret;ReturnTypedFixed(const Fixed& f,const AssertionReturnType<R>& r):fixed(f),ret(r){}};public: void operator=(const Fixed& fixed){OnFixed(fixed);
#if IUTEST_HAS_EXCEPTIONS&&IUTEST_USE_THROW_ON_ASSERTION_FAILURE
{switch(m_part_result.type()){case TestPartResult::kSkip: case TestPartResult::kAssumeFailure: case TestPartResult::kFatalFailure: throw m_part_result.type();default: break;}}
#endif
}template<typename R>R operator=(const ReturnTypedFixed<R>& fixed){this->operator=(fixed.fixed);return fixed.ret.value;}private: void OnFixed(const Fixed& fixed){const ::std::string append_message=fixed.GetString();if(!append_message.empty()){m_part_result.add_message(" " + append_message);}ScopedTrace::GetInstance().append_message(m_part_result);if(TestEnv::GetGlobalTestPartResultReporter()!=IUTEST_NULLPTR){TestEnv::GetGlobalTestPartResultReporter()->ReportTestPartResult(m_part_result);}else{detail::DefaultReportTestPartResult(m_part_result);}if(m_part_result.failed()&& TestFlag::IsEnableFlag(iutest::TestFlag::BREAK_ON_FAILURE)){IUTEST_BREAK();}}private: friend class TestInfo;TestPartResult m_part_result;private: IP_DIS_M_A_C_A_A(AssertionHelper);};}namespace iutest{inline AssertionResult AssertionSuccess(){return AssertionResult::Success();}inline AssertionResult AssertionFailure(){return AssertionResult::Failure();}inline const char* GetAssertionResultMessage(const AssertionResult& ar){return ar.message();}namespace internal{template<typename T1,typename T2>inline ::std::string FormatForComparisonFailureMessage(const T1& value,const T2&){return PrintToString(value);}inline ::std::string GetBooleanAssertionFailureMessage(const AssertionResult& ar,const char* expr,const char* actual,const char* expected){::std::string str="error: Value of: ";str+=expr;str+="\n  Actual: ";str+=actual;if(!detail::IsEmpty(ar.message())){str+=" (";str+=ar.message();str+=")";}str+="\nExpected: ";str+=expected;return str;}inline AssertionResult EqFailure(const char* expected_expression,const char* actual_expression,const ::std::string& expected,const ::std::string& actual,bool ignoring_case=false){iu_global_format_stringstream strm;strm<<"error: Value of " <<actual_expression<< "\n  Actual: " <<actual<< "\nExpected: " <<expected_expression;if(ignoring_case){strm<<" (ignoring case)";}if(!detail::IsStringEqual(expected_expression,expected.c_str())){strm<<"\nWhich is: " <<expected;}return AssertionFailure()<<strm.str();}template<typename T1,typename T2>inline AssertionResult CmpHelperOpFailure(const char* expr1,const char* expr2,const char* op,const T1& val1,const T2& val2){return AssertionFailure()<<"error: Expected: " <<expr1<<" " <<op<<" " <<expr2<< "\n  Actual: " <<FormatForComparisonFailureMessage(val1,val2)<< " vs " <<FormatForComparisonFailureMessage(val2,val1);}
#define II_D_C_H_EX_P_BASE_(op_name,op) template<typename T1,typename T2> bool iuOperator##op_name(const T1& v1,const T2& v2){return v1 op v2;}
#if IUTEST_HAS_CXX_HDR_VARIANT&&IUTEST_HAS_VARIADIC_TEMPLATES
#define II_D_C_H_EX_P_VARIANT_(op_name,op) template<typename ...V1,typename ...V2> bool iuOperator##op_name(const ::std::variant<V1...>&& v1,const ::std::variant<V2...>& v2){return v1 op v2;}template<typename T1,typename ...V> bool iuOperator##op_name(const T1& v1,const ::std::variant<V...>& v2 ,typename detail::enable_if< !detail::is_variant<T1>::value,void>::type*& = detail::enabler::value){::std::variant<V...> vv1(v1);return vv1 op v2;}template<typename ...V,typename T2> bool iuOperator##op_name(const ::std::variant<V...>& v1,const T2& v2 ,typename detail::enable_if< !detail::is_variant<T2>::value,void>::type*& = detail::enabler::value){::std::variant<V...> vv2(v2);return v1 op vv2;}
#else
#define II_D_C_H_EX_P_VARIANT_(op_name,op)
#endif
#define II_D_C_H_EX_P_(op_name,op) II_D_C_H_EX_P_BASE_(op_name,op) II_D_C_H_EX_P_VARIANT_(op_name,op)
#define II_D_C_H_I_(op_name,op,type1,type2) inline AssertionResult II_ATR_U CmpHelper##op_name(const char* expr1,const char* expr2,type1 val1,type2 val2){if(iuOperator##op_name(val1,val2)){return AssertionSuccess();}else{return CmpHelperOpFailure(expr1,expr2,#op,val1,val2);}}
#define II_D_C_H_(op_name,op) II_D_C_H_EX_P_(op_name,op) template<typename T1,typename T2> II_D_C_H_I_(op_name,op,const T1&,const T2&) II_D_C_H_I_(op_name,op,BiggestInt,BiggestInt)
template<typename T1,typename T2>bool iuOperatorEQ(const T1& v1,const T2& v2){II_PGM_W_PU()II_PGM_W_D_S_C()return v1==v2;II_PGM_W_PP()}II_D_C_H_EX_P_VARIANT_(EQ,==)II_D_C_H_(NE,!=)II_D_C_H_(LE,<=)II_D_C_H_(LT,<)II_D_C_H_(GE,>=)II_D_C_H_(GT,>)
#undef II_D_C_H_EX_P_
#undef II_D_C_H_EX_P_BASE
#undef II_D_C_H_EX_P_VARIANT
#undef II_D_C_H_I_
#undef II_D_C_H_
template<bool IsNullLiteral>class NullHelper{public: template<typename T>static AssertionResult CompareEq(const char* expr,const T* val){if(IUTEST_NULLPTR==val){return AssertionSuccess();}return AssertionFailure()<<"error: Value of " <<expr<< "\n  Actual: " <<val<< "\nExpected: 0";}template<typename T>static AssertionResult CompareNe(const char* expr,const T* val){if(IUTEST_NULLPTR!=val){return AssertionSuccess();}return AssertionFailure()<<"error: Value of " <<expr<< "\n  Actual: 0\nExpected: not 0";}};template<>class NullHelper<true>{public: static AssertionResult CompareEq(const char*,void*){return AssertionSuccess();}static AssertionResult CompareNe(const char* expr,void*){return AssertionFailure()<<"error: Value of " <<expr<< "\n  Actual: 0\nExpected: not 0";}};template<typename T1,typename T2>inline AssertionResult CmpHelperSame(const char* exp_s,const char* act_s,const T1& expected,const T2& actual){if(&expected==&actual){return AssertionSuccess();}return AssertionFailure()<<"error: Expected: &(" <<exp_s<<") == &(" <<act_s<< ")\n  Actual: " <<FormatForComparisonFailureMessage(&expected,&actual)<< " vs " <<FormatForComparisonFailureMessage(&actual,&expected);}template<typename T1,typename T2>inline AssertionResult CmpHelperEQ(const char* exp_s,const char* act_s,const T1& expected,const T2& actual){if(iuOperatorEQ(actual,expected)){return AssertionSuccess();}return EqFailure(exp_s,act_s,FormatForComparisonFailureMessage(expected,actual),FormatForComparisonFailureMessage(actual,expected));}template<typename T>inline AssertionResult CmpHelperMemCmpEQ(const char* exp_s,const char* act_s,const T& expected,const T& actual){II_PGM_W_PU()II_PGM_W_D_S_C()if(memcmp(&actual,&expected,sizeof(T))==0){return AssertionSuccess();}return EqFailure(exp_s,act_s,FormatForComparisonFailureMessage(expected,actual),FormatForComparisonFailureMessage(actual,expected));II_PGM_W_PP()}template<typename T>inline AssertionResult CmpHelperMemCmpNE(const char* exp_s,const char* act_s,const T& expected,const T& actual){II_PGM_W_PU()II_PGM_W_D_S_C()if(memcmp(&actual,&expected,sizeof(T))!=0){return AssertionSuccess();}return AssertionFailure()<<"error: Expected: " <<exp_s<<" != " <<act_s<< "\n  Actual: " <<FormatForComparisonFailureMessage(expected,actual);II_PGM_W_PP()}template<typename RawType>inline AssertionResult CmpHelperFloatingPointEQ(const char* expr1,const char* expr2,RawType val1,RawType val2){floating_point<RawType> f1(val1),f2(val2);if(f1.AlmostEquals(f2)){return AssertionSuccess();}return EqFailure(expr1,expr2,detail::ShowStringQuoted(FormatForComparisonFailureMessage(f1,f2)),detail::ShowStringQuoted(FormatForComparisonFailureMessage(f2,f1)));}template<typename RawType>inline AssertionResult CmpHelperFloatingPointLE(const char* expr1,const char* expr2,RawType val1,RawType val2){if(val1<val2){return AssertionSuccess();}floating_point<RawType> f1(val1),f2(val2);if(f1.AlmostEquals(f2)){return AssertionSuccess();}return EqFailure(expr1,expr2,detail::ShowStringQuoted(FormatForComparisonFailureMessage(f1,f2)),detail::ShowStringQuoted(FormatForComparisonFailureMessage(f2,f1)));}namespace bkw{template<bool IsNullLiteral>class EqHelper{template<typename T,bool has_equal_to_operator>struct CmpHelper{static AssertionResult Compare(const char* expr1,const char* expr2,const T& val1,const T& val2){return CmpHelperEQ(expr1,expr2,val1,val2);}};template<typename T>struct CmpHelper<T,false>{static AssertionResult Compare(const char* expr1,const char* expr2,const T& val1,const T& val2){return CmpHelperMemCmpEQ(expr1,expr2,val1,val2);}};public: template<typename T>static AssertionResult Compare(const char* expr1,const char* expr2,const T& val1,const T& val2){return CmpHelper<T,detail::has_equal_to<T>::value>::Compare(expr1,expr2,val1,val2);}public: template<typename T1,typename T2>static AssertionResult Compare(const char* expr1,const char* expr2,const T1& val1,const T2& val2){return CmpHelperEQ(expr1,expr2,val1,val2);}};template<>class EqHelper<true>{public:template<typename T1,typename T2>static AssertionResult Compare(const char* expr1,const char* expr2,const T1& val1,const T2& val2,typename detail::enable_if< !detail::is_pointer<T2>::value,void>::type*& = detail::enabler::value){return CmpHelperEQ(expr1,expr2,val1,val2);}template<typename T2>static AssertionResult Compare(const char* expr1,const char* expr2,detail::IsNullLiteralHelper::Object* val1,T2* val2){(void)(val1);return CmpHelperEQ(expr1,expr2,static_cast<T2*>(IUTEST_NULLPTR),val2);}};template<bool IsNullLiteral>class AlmostEqHelper:public EqHelper<false>{public: template<typename T1,typename T2>static AssertionResult Compare(const char* expr1,const char* expr2,const T1& val1,const T2& val2){return EqHelper<false>::Compare(expr1,expr2,val1,static_cast<T1>(val2));}template<typename T>static AssertionResult Compare(const char* expr1,const char* expr2,const float& val1,const T& val2){return CmpHelperFloatingPointEQ<float>(expr1,expr2,val1,static_cast<float>(val2));}template<typename T>static AssertionResult Compare(const char* expr1,const char* expr2,const double& val1,const T& val2){return CmpHelperFloatingPointEQ<double>(expr1,expr2,val1,static_cast<double>(val2));}};template<>class AlmostEqHelper<true>:public EqHelper<true>{};template<bool IsNullLiteral>class NeHelper{template<typename T,bool has_not_equal_to_operator>struct CmpHelper{static AssertionResult Compare(const char* expr1,const char* expr2,const T& val1,const T& val2){return CmpHelperNE(expr1,expr2,val1,val2);}};template<typename T>struct CmpHelper<T,false>{static AssertionResult Compare(const char* expr1,const char* expr2,const T& val1,const T& val2){return CmpHelperMemCmpNE(expr1,expr2,val1,val2);}};public: template<typename T>static AssertionResult Compare(const char* expr1,const char* expr2,const T& val1,const T& val2){return CmpHelper<T,detail::has_not_equal_to<T>::value>::Compare(expr1,expr2,val1,val2);}public: template<typename T1,typename T2>static AssertionResult Compare(const char* expr1,const char* expr2,const T1& val1,const T2& val2){return CmpHelperNE(expr1,expr2,val1,val2);}};template<>class NeHelper<true>{public:template<typename T1,typename T2>static AssertionResult Compare(const char* expr1,const char* expr2,const T1& val1,const T2& val2,typename detail::enable_if< !detail::is_pointer<T2>::value,void>::type*& = detail::enabler::value){return CmpHelperNE(expr1,expr2,val1,val2);}template<typename T2>static AssertionResult Compare(const char* expr1,const char* expr2,detail::IsNullLiteralHelper::Object* val1,T2* val2){(void)(val1);return CmpHelperNE(expr1,expr2,static_cast<T2*>(IUTEST_NULLPTR),val2);}};}using bkw::EqHelper;using bkw::AlmostEqHelper;using bkw::NeHelper;template<typename RawType>inline AssertionResult II_ATR_U CmpHelperNearFloatingPoint(const char* expr1,const char* expr2,const char* absc,RawType val1,RawType val2,RawType abs_v){RawType diff=val1>val2?val1-val2:val2-val1;if(diff<abs_v){return AssertionSuccess();}floating_point<RawType> f1(diff),f2(abs_v);if(f1.AlmostEquals(f2)){return AssertionSuccess();}return AssertionFailure()<<"error: Value of: abs(" <<expr1<<" - " <<expr2<<") <= " <<absc<< "\n  Actual: abs(" <<val1<<" - " <<val2<<") : " <<diff<< "\nExpected: " <<FormatForComparisonFailureMessage(abs_v,diff);}inline AssertionResult II_ATR_U DoubleNearPredFormat(const char* expr1,const char* expr2,const char* absc,double val1,double val2,double abs_v){return CmpHelperNearFloatingPoint(expr1,expr2,absc,val1,val2,abs_v);}template<typename T,typename A>inline AssertionResult II_ATR_U CmpHelperNear(const char* expr1,const char* expr2,const char* absc,const T& val1,const T& val2,const A& abs_v){T diff=val1>val2?val1-val2:val2-val1;if(diff<=abs_v){return AssertionSuccess();}return AssertionFailure()<<"error: Value of: abs(" <<expr1<<" - " <<expr2<<") <= " <<absc<< "\n  Actual: abs(" <<val1<<" - " <<val2<<") : " <<diff<< "\nExpected: " <<FormatForComparisonFailureMessage(abs_v,diff);}template<typename A>inline AssertionResult II_ATR_U CmpHelperNear(const char* expr1,const char* expr2,const char* absc,double val1,double val2,const A& abs_v){return CmpHelperNearFloatingPoint<double>(expr1,expr2,absc,val1,val2,static_cast<double>(abs_v));}template<typename A>inline AssertionResult II_ATR_U CmpHelperNear(const char* expr1,const char* expr2,const char* absc,float val1,float val2,const A& abs_v){return CmpHelperNearFloatingPoint<float>(expr1,expr2,absc,val1,val2,static_cast<float>(abs_v));}namespace StrEqHelper{
#define II_DECL_SE_C_H_NULL_(T)
#define II_DECL_SE_C_H_SV_(T) inline bool II_ATR_U Compare(detail::iu_nullable_basic_string_view<T> val1 ,detail::iu_nullable_basic_string_view<T> val2){return val1==val2;}inline bool II_ATR_U Compare(const T* val1,const T* val2){if(val1==IUTEST_NULLPTR||val2==IUTEST_NULLPTR){return val1==val2;}return Compare(detail::iu_nullable_basic_string_view<T>(val1) ,detail::iu_nullable_basic_string_view<T>(val2));}
#define II_DECL_SE_C_H_(T) II_DECL_SE_C_H_SV_(T) II_DECL_SE_C_H_NULL_(T)
II_DECL_SE_C_H_(char)II_DECL_SE_C_H_(wchar_t)
#if IUTEST_HAS_CHAR16_T
II_DECL_SE_C_H_(char16_t)
#endif
#if IUTEST_HAS_CHAR32_T
II_DECL_SE_C_H_(char32_t)
#endif
#undef II_DECL_SE_C_H_
#undef II_DECL_SE_C_H_SV_
}template<typename T1,typename T2>inline AssertionResult II_ATR_U CmpHelperSTREQ(const char* expr1,const char* expr2,T1 val1,T2 val2,typename detail::enable_if<!detail::is_integral<T1>::value||!detail::is_pointer<T2>::value,void>::type*& = detail::enabler::value){if(StrEqHelper::Compare(val1,val2)){return AssertionSuccess();}return EqFailure(expr1,expr2,detail::ShowStringQuoted(FormatForComparisonFailureMessage(val1,val2)),detail::ShowStringQuoted(FormatForComparisonFailureMessage(val2,val1)));}template<typename T>inline AssertionResult II_ATR_U CmpHelperSTREQ(const char* expr1,const char* expr2,detail::iu_nullptr_convertible_t,T val2){if(StrEqHelper::Compare(IUTEST_NULLPTR,val2)){return AssertionSuccess();}return EqFailure(expr1,expr2,detail::ShowStringQuoted(FormatForComparisonFailureMessage<T,T>(IUTEST_NULLPTR,val2)),detail::ShowStringQuoted(FormatForComparisonFailureMessage<T,T>(val2,IUTEST_NULLPTR)));}namespace StrNeHelper{template<typename T1,typename T2>inline bool II_ATR_U Compare(const T1& val1,const T2& val2){return !StrEqHelper::Compare(val1,val2);}}template<typename T1,typename T2>inline AssertionResult II_ATR_U CmpHelperSTRNE(const char* expr1,const char* expr2,T1 val1,T2 val2,typename detail::enable_if<((!detail::is_integral<T2>::value||!detail::is_pointer<T1>::value) &&(!detail::is_integral<T1>::value||!detail::is_pointer<T2>::value)),void>::type*& = detail::enabler::value){if(StrNeHelper::Compare(val1,val2)){return AssertionSuccess();}return AssertionFailure()<<"error: Expected: " <<expr1<<" != " <<expr2<< "\n  Actual: " <<detail::ShowStringQuoted(FormatForComparisonFailureMessage(val2,val1))<< " vs " <<detail::ShowStringQuoted(FormatForComparisonFailureMessage(val1,val2));}template<typename T>inline AssertionResult II_ATR_U CmpHelperSTRNE(const char* expr1,const char* expr2,detail::iu_nullptr_convertible_t,T val2){if(!StrEqHelper::Compare(IUTEST_NULLPTR,val2)){return AssertionSuccess();}return AssertionFailure()<<"error: Expected: " <<expr1<<" != " <<expr2<< "\n  Actual: " <<detail::ShowStringQuoted(FormatForComparisonFailureMessage<T,T>(val2,IUTEST_NULLPTR))<< " vs " <<detail::ShowStringQuoted(FormatForComparisonFailureMessage<T,T>(IUTEST_NULLPTR,val2));}template<typename T>inline AssertionResult II_ATR_U CmpHelperSTRNE(const char* expr1,const char* expr2,T val1,detail::iu_nullptr_convertible_t){if(!StrEqHelper::Compare(val1,IUTEST_NULLPTR)){return AssertionSuccess();}return AssertionFailure()<<"error: Expected: " <<expr1<<" != " <<expr2<< "\n  Actual: " <<detail::ShowStringQuoted(FormatForComparisonFailureMessage<T,T>(IUTEST_NULLPTR,val1))<< " vs " <<detail::ShowStringQuoted(FormatForComparisonFailureMessage<T,T>(val1,IUTEST_NULLPTR));}namespace StrCaseEqHelper{inline bool II_ATR_U Compare(const char* val1,const char* val2){if(val1==IUTEST_NULLPTR||val2==IUTEST_NULLPTR){return val1==val2;}return detail::iu_stricmp(val1,val2)==0;}inline bool II_ATR_U Compare(const wchar_t* val1,const wchar_t* val2){if(val1==IUTEST_NULLPTR||val2==IUTEST_NULLPTR){return val1==val2;}return detail::iu_wcsicmp(val1,val2)==0;}template<typename Elem,typename Traits,typename Ax>inline bool II_ATR_U Compare(const ::std::basic_string<Elem,Traits,Ax>& val1,const ::std::basic_string<Elem,Traits,Ax>& val2){return Compare(val1.c_str(),val2.c_str());}template<typename Elem,typename Traits,typename Ax>inline bool II_ATR_U Compare(const Elem* val1,const ::std::basic_string<Elem,Traits,Ax>& val2){return Compare(val1,val2.c_str());}template<typename Elem,typename Traits,typename Ax>inline bool II_ATR_U Compare(const ::std::basic_string<Elem,Traits,Ax>& val1,const Elem* val2){return Compare(val1.c_str(),val2);}template<typename T1,typename T2>inline AssertionResult II_ATR_U Assertion(const char* expr1,const char* expr2,const T1& val1,const T2& val2){if(Compare(val1,val2)){return AssertionSuccess();}return EqFailure(expr1,expr2,detail::ShowStringQuoted(FormatForComparisonFailureMessage(val1,val2)),detail::ShowStringQuoted(FormatForComparisonFailureMessage(val2,val1)),true);}}inline AssertionResult II_ATR_U CmpHelperSTRCASEEQ(const char* expr1,const char* expr2,const char* val1,const char* val2){return StrCaseEqHelper::Assertion(expr1,expr2,val1,val2);}inline AssertionResult II_ATR_U CmpHelperSTRCASEEQ(const char* expr1,const char* expr2,const wchar_t* val1,const wchar_t* val2){return StrCaseEqHelper::Assertion(expr1,expr2,val1,val2);}template<typename Elem,typename Traits,typename Ax>inline AssertionResult II_ATR_U CmpHelperSTRCASEEQ(const char* expr1,const char* expr2,const ::std::basic_string<Elem,Traits,Ax>& val1,const ::std::basic_string<Elem,Traits,Ax>& val2){return CmpHelperSTRCASEEQ(expr1,expr2,val1.c_str(),val2.c_str());}template<typename Elem,typename Traits,typename Ax>inline AssertionResult II_ATR_U CmpHelperSTRCASEEQ(const char* expr1,const char* expr2,const Elem* val1,const ::std::basic_string<Elem,Traits,Ax>& val2){return CmpHelperSTRCASEEQ(expr1,expr2,val1,val2.c_str());}template<typename Elem,typename Traits,typename Ax>inline AssertionResult II_ATR_U CmpHelperSTRCASEEQ(const char* expr1,const char* expr2,const ::std::basic_string<Elem,Traits,Ax>& val1,const Elem* val2){return CmpHelperSTRCASEEQ(expr1,expr2,val1.c_str(),val2);}namespace StrCaseNeHelper{template<typename T1,typename T2>inline bool II_ATR_U Compare(const T1& val1,const T2& val2){return !StrCaseEqHelper::Compare(val1,val2);}template<typename T1,typename T2>inline AssertionResult II_ATR_U Assertion(const char* expr1,const char* expr2,const T1& val1,const T2& val2){if(Compare(val1,val2)){return AssertionSuccess();}return AssertionFailure()<<"error: Expected: " <<expr1<<" != " <<expr2<<" (ignoring case)"<< "\n  Actual: " <<detail::ShowStringQuoted(FormatForComparisonFailureMessage(val2,val1))<< " vs " <<detail::ShowStringQuoted(FormatForComparisonFailureMessage(val1,val2));}}inline AssertionResult II_ATR_U CmpHelperSTRCASENE(const char* expr1,const char* expr2,const char* val1,const char* val2){return StrCaseNeHelper::Assertion(expr1,expr2,val1,val2);}inline AssertionResult II_ATR_U CmpHelperSTRCASENE(const char* expr1,const char* expr2,const wchar_t* val1,const wchar_t* val2){return StrCaseNeHelper::Assertion(expr1,expr2,val1,val2);}template<typename Elem,typename Traits,typename Ax>inline AssertionResult II_ATR_U CmpHelperSTRCASENE(const char* expr1,const char* expr2,const ::std::basic_string<Elem,Traits,Ax>& val1,const ::std::basic_string<Elem,Traits,Ax>& val2){return CmpHelperSTRCASENE(expr1,expr2,val1.c_str(),val2.c_str());}template<typename Elem,typename Traits,typename Ax>inline AssertionResult II_ATR_U CmpHelperSTRCASENE(const char* expr1,const char* expr2,const Elem* val1,const ::std::basic_string<Elem,Traits,Ax>& val2){return CmpHelperSTRCASENE(expr1,expr2,val1,val2.c_str());}template<typename Elem,typename Traits,typename Ax>inline AssertionResult II_ATR_U CmpHelperSTRCASENE(const char* expr1,const char* expr2,const ::std::basic_string<Elem,Traits,Ax>& val1,const Elem* val2){return CmpHelperSTRCASENE(expr1,expr2,val1.c_str(),val2);}}inline AssertionResult II_ATR_U FloatLE(const char* expr1,const char* expr2,float val1,float val2){return internal::CmpHelperFloatingPointLE<float>(expr1,expr2,val1,val2);}inline AssertionResult II_ATR_U DoubleLE(const char* expr1,const char* expr2,double val1,double val2){return internal::CmpHelperFloatingPointLE<double>(expr1,expr2,val1,val2);}}
#define IUTEST_ASSERT_PRED1(pred,v1) II_PRD1_(pred,v1,II_A_FAIL)
#define IUTEST_EXPECT_PRED1(pred,v1) II_PRD1_(pred,v1,II_E_FAIL)
#define IUTEST_INFORM_PRED1(pred,v1) II_PRD1_(pred,v1,II_I_FAIL)
#define IUTEST_ASSUME_PRED1(pred,v1) II_PRD1_(pred,v1,II_M_FAIL)
#define IUTEST_ASSERT_PRED_FORMAT1(pd_fmt,v1) II_PRD_FMT1_(pd_fmt,v1,II_A_FAIL)
#define IUTEST_EXPECT_PRED_FORMAT1(pd_fmt,v1) II_PRD_FMT1_(pd_fmt,v1,II_E_FAIL)
#define IUTEST_INFORM_PRED_FORMAT1(pd_fmt,v1) II_PRD_FMT1_(pd_fmt,v1,II_I_FAIL)
#define IUTEST_ASSUME_PRED_FORMAT1(pd_fmt,v1) II_PRD_FMT1_(pd_fmt,v1,II_M_FAIL)
#define IUTEST_ASSERT_PRED2(pred,v1,v2) II_PRD2_(pred,v1,v2,II_A_FAIL)
#define IUTEST_EXPECT_PRED2(pred,v1,v2) II_PRD2_(pred,v1,v2,II_E_FAIL)
#define IUTEST_INFORM_PRED2(pred,v1,v2) II_PRD2_(pred,v1,v2,II_I_FAIL)
#define IUTEST_ASSUME_PRED2(pred,v1,v2) II_PRD2_(pred,v1,v2,II_M_FAIL)
#define IUTEST_ASSERT_PRED_FORMAT2(pd_fmt,v1,v2) II_PRD_FMT2_(pd_fmt,v1,v2,II_A_FAIL)
#define IUTEST_EXPECT_PRED_FORMAT2(pd_fmt,v1,v2) II_PRD_FMT2_(pd_fmt,v1,v2,II_E_FAIL)
#define IUTEST_INFORM_PRED_FORMAT2(pd_fmt,v1,v2) II_PRD_FMT2_(pd_fmt,v1,v2,II_I_FAIL)
#define IUTEST_ASSUME_PRED_FORMAT2(pd_fmt,v1,v2) II_PRD_FMT2_(pd_fmt,v1,v2,II_M_FAIL)
#define IUTEST_ASSERT_PRED3(pred,v1,v2,v3) II_PRD3_(pred,v1,v2,v3,II_A_FAIL)
#define IUTEST_EXPECT_PRED3(pred,v1,v2,v3) II_PRD3_(pred,v1,v2,v3,II_E_FAIL)
#define IUTEST_INFORM_PRED3(pred,v1,v2,v3) II_PRD3_(pred,v1,v2,v3,II_I_FAIL)
#define IUTEST_ASSUME_PRED3(pred,v1,v2,v3) II_PRD3_(pred,v1,v2,v3,II_M_FAIL)
#define IUTEST_ASSERT_PRED_FORMAT3(pd_fmt,v1,v2,v3) II_PRD_FMT3_(pd_fmt,v1,v2,v3,II_A_FAIL)
#define IUTEST_EXPECT_PRED_FORMAT3(pd_fmt,v1,v2,v3) II_PRD_FMT3_(pd_fmt,v1,v2,v3,II_E_FAIL)
#define IUTEST_INFORM_PRED_FORMAT3(pd_fmt,v1,v2,v3) II_PRD_FMT3_(pd_fmt,v1,v2,v3,II_I_FAIL)
#define IUTEST_ASSUME_PRED_FORMAT3(pd_fmt,v1,v2,v3) II_PRD_FMT3_(pd_fmt,v1,v2,v3,II_M_FAIL)
#define IUTEST_ASSERT_PRED4(pred,v1,v2,v3,v4) II_PRD4_(pred,v1,v2,v3,v4,II_A_FAIL)
#define IUTEST_EXPECT_PRED4(pred,v1,v2,v3,v4) II_PRD4_(pred,v1,v2,v3,v4,II_E_FAIL)
#define IUTEST_INFORM_PRED4(pred,v1,v2,v3,v4) II_PRD4_(pred,v1,v2,v3,v4,II_I_FAIL)
#define IUTEST_ASSUME_PRED4(pred,v1,v2,v3,v4) II_PRD4_(pred,v1,v2,v3,v4,II_M_FAIL)
#define IUTEST_ASSERT_PRED_FORMAT4(pd_fmt,v1,v2,v3,v4) II_PRD_FMT4_(pd_fmt,v1,v2,v3,v4,II_A_FAIL)
#define IUTEST_EXPECT_PRED_FORMAT4(pd_fmt,v1,v2,v3,v4) II_PRD_FMT4_(pd_fmt,v1,v2,v3,v4,II_E_FAIL)
#define IUTEST_INFORM_PRED_FORMAT4(pd_fmt,v1,v2,v3,v4) II_PRD_FMT4_(pd_fmt,v1,v2,v3,v4,II_I_FAIL)
#define IUTEST_ASSUME_PRED_FORMAT4(pd_fmt,v1,v2,v3,v4) II_PRD_FMT4_(pd_fmt,v1,v2,v3,v4,II_M_FAIL)
#define IUTEST_ASSERT_PRED5(pred,v1,v2,v3,v4,v5) II_PRD5_(pred,v1,v2,v3,v4,v5,II_A_FAIL)
#define IUTEST_EXPECT_PRED5(pred,v1,v2,v3,v4,v5) II_PRD5_(pred,v1,v2,v3,v4,v5,II_E_FAIL)
#define IUTEST_INFORM_PRED5(pred,v1,v2,v3,v4,v5) II_PRD5_(pred,v1,v2,v3,v4,v5,II_I_FAIL)
#define IUTEST_ASSUME_PRED5(pred,v1,v2,v3,v4,v5) II_PRD5_(pred,v1,v2,v3,v4,v5,II_M_FAIL)
#define IUTEST_ASSERT_PRED_FORMAT5(pd_fmt,v1,v2,v3,v4,v5) II_PRD_FMT5_(pd_fmt,v1,v2,v3,v4,v5,II_A_FAIL)
#define IUTEST_EXPECT_PRED_FORMAT5(pd_fmt,v1,v2,v3,v4,v5) II_PRD_FMT5_(pd_fmt,v1,v2,v3,v4,v5,II_E_FAIL)
#define IUTEST_INFORM_PRED_FORMAT5(pd_fmt,v1,v2,v3,v4,v5) II_PRD_FMT5_(pd_fmt,v1,v2,v3,v4,v5,II_I_FAIL)
#define IUTEST_ASSUME_PRED_FORMAT5(pd_fmt,v1,v2,v3,v4,v5) II_PRD_FMT5_(pd_fmt,v1,v2,v3,v4,v5,II_M_FAIL)
#if IUTEST_HAS_VARIADIC_TEMPLATES
#define IUTEST_ASSERT_PRED(pred,...) II_PRD_(pred,II_A_FAIL,__VA_ARGS__)
#define IUTEST_EXPECT_PRED(pred,...) II_PRD_(pred,II_E_FAIL,__VA_ARGS__)
#define IUTEST_INFORM_PRED(pred,...) II_PRD_(pred,II_I_FAIL,__VA_ARGS__)
#define IUTEST_ASSUME_PRED(pred,...) II_PRD_(pred,II_M_FAIL,__VA_ARGS__)
#endif
#define IUTEST_ASSERT_PRED_FORMAT(pd_fmt,...) II_PRD_FMT_(pd_fmt,II_A_FAIL,__VA_ARGS__)
#define IUTEST_EXPECT_PRED_FORMAT(pd_fmt,...) II_PRD_FMT_(pd_fmt,II_E_FAIL,__VA_ARGS__)
#define IUTEST_INFORM_PRED_FORMAT(pd_fmt,...) II_PRD_FMT_(pd_fmt,II_I_FAIL,__VA_ARGS__)
#define IUTEST_ASSUME_PRED_FORMAT(pd_fmt,...) II_PRD_FMT_(pd_fmt,II_M_FAIL,__VA_ARGS__)
#define IUTEST_ASSERT_THROW_PRED_FORMAT2(pd_fmt,st,exp_e,exp_e_v) II_T_PRD_FMT2_(pd_fmt,st,exp_e,exp_e_v,II_A_FAIL)
#define IUTEST_EXPECT_THROW_PRED_FORMAT2(pd_fmt,st,exp_e,exp_e_v) II_T_PRD_FMT2_(pd_fmt,st,exp_e,exp_e_v,II_E_FAIL)
#define IUTEST_INFORM_THROW_PRED_FORMAT2(pd_fmt,st,exp_e,exp_e_v) II_T_PRD_FMT2_(pd_fmt,st,exp_e,exp_e_v,II_I_FAIL)
#define IUTEST_ASSUME_THROW_PRED_FORMAT2(pd_fmt,st,exp_e,exp_e_v) II_T_PRD_FMT2_(pd_fmt,st,exp_e,exp_e_v,II_M_FAIL)
#define II_PRD1_(pred,v1,on_f) II_T_ASRT_(::iutest::AssertPred1Helper(#pred,#v1,pred,v1),on_f)
#define II_PRD_FMT1_(pd_fmt,v1,on_f) II_T_ASRT_(pd_fmt(#v1,v1),on_f)
#define II_PRD2_(pred,v1,v2,on_f) II_T_ASRT_(::iutest::AssertPred2Helper(#pred,#v1,#v2,pred,v1,v2),on_f)
#define II_PRD_FMT2_(pd_fmt,v1,v2,on_f) II_T_ASRT_(pd_fmt(#v1,#v2,v1,v2),on_f)
#define II_PRD3_(pred,v1,v2,v3,on_f) II_T_ASRT_(::iutest::AssertPred3Helper(#pred,#v1,#v2,#v3,pred,v1,v2,v3),on_f)
#define II_PRD_FMT3_(pd_fmt,v1,v2,v3,on_f) II_T_ASRT_(pd_fmt(#v1,#v2,#v3,v1,v2,v3),on_f)
#define II_PRD4_(pred,v1,v2,v3,v4,on_f) II_T_ASRT_(::iutest::AssertPred4Helper(#pred,#v1,#v2,#v3,#v4,pred,v1,v2,v3,v4),on_f)
#define II_PRD_FMT4_(pd_fmt,v1,v2,v3,v4,on_f) II_T_ASRT_(pd_fmt(#v1,#v2,#v3,#v4,v1,v2,v3,v4),on_f)
#define II_PRD5_(pred,v1,v2,v3,v4,v5,on_f) II_T_ASRT_(::iutest::AssertPred5Helper(#pred,#v1,#v2,#v3,#v4,#v5,pred,v1,v2,v3,v4,v5),on_f)
#define II_PRD_FMT5_(pd_fmt,v1,v2,v3,v4,v5,on_f) II_T_ASRT_(pd_fmt(#v1,#v2,#v3,#v4,#v5,v1,v2,v3,v4,v5),on_f)
#if IUTEST_HAS_VARIADIC_TEMPLATES
#define II_PRD_(pred,on_f,...) II_T_ASRT_(::iutest::AssertPredVariadicHelper(#pred,#__VA_ARGS__,pred,__VA_ARGS__),on_f)
#endif
#define II_PRD_FMT_(pd_fmt,on_f,...) II_T_ASRT_(pd_fmt(#__VA_ARGS__,__VA_ARGS__),on_f)
#define II_T_PRD_FMT2_(pd_fmt,st,exp_e,exp_e_v,on_f) IUTEST_TEST_THROW_VALUE_(st,exp_e,exp_e_v,on_f,pd_fmt)
namespace iutest{template<typename PRED,typename T1>AssertionResult AssertPred1Helper(const char* pred_str,const char* expr1,PRED pred,T1 val1){if((*pred)(val1)){return AssertionSuccess();}return AssertionFailure()<<"error: " <<pred_str<<"(" <<expr1<<") evaluates to false, where "<< "\n" <<expr1<<" : " <<val1;}template<typename PRED,typename T1,typename T2>AssertionResult AssertPred2Helper(const char* pred_str,const char* expr1,const char* expr2,PRED pred,T1 val1,T2 val2){if((*pred)(val1,val2)){return AssertionSuccess();}return AssertionFailure()<<"error: " <<pred_str<<"("<<expr1<<", " <<expr2<< ") evaluates to false, where "<< "\n" <<expr1<<" : " <<val1<< "\n" <<expr2<<" : " <<val2;}template<typename PRED,typename T1,typename T2,typename T3>AssertionResult AssertPred3Helper(const char* pred_str,const char* expr1,const char* expr2,const char* expr3,PRED pred,T1 val1,T2 val2,T3 val3){if((*pred)(val1,val2,val3)){return AssertionSuccess();}return AssertionFailure()<<"error: " <<pred_str<<"("<<expr1<<", " <<expr2<<", " <<expr3<< ") evaluates to false, where "<< "\n" <<expr1<<" : " <<val1<< "\n" <<expr2<<" : " <<val2<< "\n" <<expr3<<" : " <<val3;}template<typename PRED,typename T1,typename T2,typename T3,typename T4>AssertionResult AssertPred4Helper(const char* pred_str,const char* expr1,const char* expr2,const char* expr3,const char* expr4,PRED pred,T1 val1,T2 val2,T3 val3,T4 val4){if((*pred)(val1,val2,val3,val4)){return AssertionSuccess();}return AssertionFailure()<<"error: " <<pred_str<<"("<<expr1<<", " <<expr2<<", " <<expr3<<", " <<expr4<< ") evaluates to false, where "<< "\n" <<expr1<<" : " <<val1<< "\n" <<expr2<<" : " <<val2<< "\n" <<expr3<<" : " <<val3<< "\n" <<expr4<<" : " <<val4;}template<typename PRED,typename T1,typename T2,typename T3,typename T4,typename T5>AssertionResult AssertPred5Helper(const char* pred_str,const char* expr1,const char* expr2,const char* expr3,const char* expr4,const char* expr5,PRED pred,T1 val1,T2 val2,T3 val3,T4 val4,T5 val5){if((*pred)(val1,val2,val3,val4,val5)){return AssertionSuccess();}return AssertionFailure()<<"error: " <<pred_str<<"("<<expr1<<", " <<expr2<<", " <<expr3<<", " <<expr4<<", " <<expr5<< ") evaluates to false, where "<< "\n" <<expr1<<" : " <<val1<< "\n" <<expr2<<" : " <<val2<< "\n" <<expr3<<" : " <<val3<< "\n" <<expr4<<" : " <<val4<< "\n" <<expr5<<" : " <<val5;}
#if IUTEST_HAS_VARIADIC_TEMPLATES
template<typename PRED,typename ...Args>AssertionResult AssertPredVariadicHelper(const char* pred_str,const char* params,PRED pred,Args... args){if((*pred)(args...)){return AssertionSuccess();}return AssertionFailure()<<"error: " <<pred_str<<"("<<params<<") evaluates to false, where "<< "\n" <<PrintToStrings("\n",args...);}
#endif
}
#define IUTEST_PACKAGE(name) II_PKG_(name)
#define II_CC_PKG_(tcn_) II_CC_PKG_I(tcn_)
#define II_CC_PKG_I(tcn_) iuTest_ConcatTestCaseName(iuTest_GetTestCasePackageName(static_cast<iuTest_TestCasePackage*>(0)) ,#tcn_)
#define II_GET_PKGN_() iuTest_GetTestCasePackageName(static_cast<iuTest_TestCasePackage*>(0))
#define II_PKG_C_NS_(name) class iuTest_TestCasePackage;namespace{const int IP_CAT(k_iutest_package_##name##_dmy_,IUTEST_PP_UNIQUEID) II_ATR_U=::iutest::detail::package_name_server< iuTest_TestCasePackage>::setname(iuTest_GetTestCaseParentPackageName(static_cast<iuTest_TestCaseParentPackage*>(0))+#name ".");}
#define II_PKG_P_NS_(name) class iuTest_TestCaseParentPackage;namespace{const int IP_CAT(k_iutest_package_##name##_parent_dmy_,IUTEST_PP_UNIQUEID) II_ATR_U=::iutest::detail::package_name_server<iuTest_TestCaseParentPackage> ::setname(iuTest_GetTestCasePackageName(static_cast<iuTest_TestCasePackage*>(0)));}
#define II_PKG_(name) namespace name{II_PKG_C_NS_(name) II_PKG_P_NS_(name) }namespace name
class iuTest_TestCasePackage;class iuTest_TestCaseParentPackage;namespace iutest{namespace detail{template<typename T>class package_name_server{static ::std::string& getname_(){static ::std::string s;return s;}public: static ::std::string getname(){return getname_();}static int setname(const ::std::string& s){::std::string& name=getname_();if(name.empty()){name=s;}return 0;}};}}template<typename T>::std::string iuTest_GetTestCasePackageName(T*){return ::iutest::detail::package_name_server<T>::getname();}template<typename T>::std::string iuTest_GetTestCaseParentPackageName(T*){return ::iutest::detail::package_name_server<T>::getname();}inline ::std::string II_ATR_U iuTest_ConcatTestCaseName(const ::std::string& package,const char* t_c_name){return package+t_c_name;}
#define II_T_CLS_N_(t_c_,tn_) II_T_C_N_I(II_TO_VN_(t_c_),II_TO_VN_(tn_))
#define II_T_C_N_I(t_c_,tn_) II_T_C_N_I_(t_c_,tn_)
#define II_T_C_N_I_(t_c_,tn_) iu_##t_c_##_x_iutest_x_##tn_##_Test
#define II_T_INST_N_(t_c_,tn_) II_T_INST_N_I(II_TO_VN_(t_c_),II_TO_VN_(tn_))
#define II_T_INST_N_I(t_c_,tn_) II_T_INST_N_I_(t_c_,tn_)
#define II_T_INST_N_I_(t_c_,tn_) s_##t_c_##_x_iutest_x_##tn_##_Instance
#define II_TO_VN_(name_) II_TO_VN_I((II_A_TN_PP_##name_,name_,dmy_))
#define II_TO_VN_I(tuple_) IUTEST_PP_EXPAND(II_TO_VN_I_ tuple_)
#define II_TO_VN_I_(dmy,name_,...) name_
#define II_TO_N_(name_) II_TO_N_I((II_A_TN_PP_##name_,name_,name_,dmy_))
#define II_TO_N_I(tuple_) IUTEST_PP_EXPAND(II_TO_N_I_ tuple_)
#define II_TO_N_I_(dmy,dmy_2,name_,...) name_
#define II_TO_N_STR_(name_) IUTEST_PP_TOSTRING(II_TO_N_(name_))
#define II_A_TN_PP_UNPAREN_(...) __VA_ARGS__
#define II_ALS_TN(name_) UNPAREN_(dmy,IP_CAT(iutest_japanese_var,__LINE__),name_)
#define II_ALS_TN_F_(name_,var_) UNPAREN_(dmy,var_,name_)
#define II_CK_TF_I(tf_) IUTEST_STATIC_ASSERT_MSG((! ::iutest::detail::is_useful_testfixture<void(int(tf_))>::value) ,#tf_ " is fixture class, mistake the IUTEST_F?");
#define II_CK_TF_(tf_) II_CK_TF_I(tf_)
#define II_CK_TF(tf_) II_CK_TF_(II_TO_VN_(tf_))
#ifndef IUTEST_TEST_STRICT_
#define IUTEST_TEST_STRICT_(t_c_,tn_,p_c_,tid_) II_CK_TF(t_c_) IUTEST_TEST_(t_c_,tn_,p_c_,tid_)
#endif
#define II_TEST_F_(mcr,tf_,tn_) mcr(tf_,tn_,II_TO_VN_(tf_) ,::iutest::internal::GetTypeId<II_TO_VN_(tf_)>())
#define II_TEST_F_A_(mcr,tf_,tn_) II_TEST_F_(mcr,IUTEST_PP_IF(IP_IS_B_PAR(tf_) ,II_ALS_TN_F_,IP_EMPTY()) tf_,tn_)
#define IUTEST_TEST_F_(tf_,tn_) II_TEST_F_A_(IUTEST_TEST_,tf_,tn_)
#define IUTEST_TEST_(t_c_,tn_,p_c_,tid_) class II_T_CLS_N_(t_c_,tn_):public p_c_{IP_DIS_C_A_A(II_T_CLS_N_(t_c_,tn_));public: II_T_CLS_N_(t_c_,tn_)(){}protected: virtual void Body() II_CXX_O;};::iutest::detail::TestInstance<II_T_CLS_N_(t_c_,tn_)> II_T_INST_N_(t_c_,tn_)(II_CC_PKG_(II_TO_N_(t_c_)),II_TO_N_STR_(tn_) ,tid_,p_c_::SetUpTestCase,p_c_::TearDownTestCase);void II_T_CLS_N_(t_c_,tn_)::Body()
#define II_P_T_CLS_N_(t_c_,tn_) II_PMZ_T_C_N_I(II_TO_VN_(t_c_),II_TO_VN_(tn_))
#define II_PMZ_T_C_N_I(t_c_,tn_) II_PMZ_T_C_N_I_(t_c_,tn_)
#define II_PMZ_T_C_N_I_(t_c_,tn_) IP_CAT(IP_CAT(iu_##t_c_##_x_Test_,tn_),__LINE__)
#define II_TEST_PMZ_(t_c_,tn_,mtd_,p_c_,tid_,...) class II_T_CLS_N_(t_c_,tn_);class II_P_T_CLS_N_(t_c_,tn_):public p_c_{IP_DIS_C_A_A(II_P_T_CLS_N_(t_c_,tn_));public: II_P_T_CLS_N_(t_c_,tn_)(){}static ::std::string MakeTestName(){return ::iutest::detail::MakeIndexTestName(II_TO_N_STR_(tn_),::iutest::detail::GetTypeUniqueCounter< II_T_CLS_N_(t_c_,tn_)>());}protected: virtual void Body() II_CXX_O{mtd_(__VA_ARGS__);}};::iutest::detail::TestInstance<II_P_T_CLS_N_(t_c_,tn_)> IP_CAT(II_T_INST_N_(t_c_,tn_),__LINE__)(II_CC_PKG_(II_TO_N_(t_c_)) ,II_P_T_CLS_N_(t_c_,tn_)::MakeTestName().c_str() ,#__VA_ARGS__,tid_,p_c_::SetUpTestCase,p_c_::TearDownTestCase)
#define II_MSG_AT(file_,line_,msg_,rt_) ::iutest::AssertionHelper(file_,line_,msg_,rt_)=::iutest::AssertionHelper::Fixed()
#define II_MSG(msg_,rt_) II_MSG_AT(__FILE__,__LINE__,msg_,rt_)
#define II_A_FAIL(msg) II_A_FAIL_AT(msg,__FILE__,__LINE__)
#define II_A_FAIL_AT(msg,file,line) return II_MSG_AT(file,line,msg,::iutest::TestPartResult::kFatalFailure)
#define II_E_FAIL(msg) II_E_FAIL_AT(msg,__FILE__,__LINE__)
#define II_E_FAIL_AT(msg,file,line) II_MSG_AT(file,line,msg,::iutest::TestPartResult::kNonFatalFailure)
#define II_I_FAIL(msg) II_I_FAIL_AT(msg,__FILE__,__LINE__)
#define II_I_FAIL_AT(msg,file,line) II_MSG_AT(file,line,msg,::iutest::TestPartResult::kWarning)
#define II_M_FAIL(msg) II_M_FAIL_AT(msg,__FILE__,__LINE__)
#define II_M_FAIL_AT(msg,file,line) return II_MSG_AT(file,line,msg,::iutest::TestPartResult::kAssumeFailure)
#define IUTEST_SKIP_MESSAGE(msg) IUTEST_SKIP_MESSAGE_AT(msg,__FILE__,__LINE__)
#define IUTEST_SKIP_MESSAGE_AT(msg,file,line) return II_MSG_AT(file,line,msg,::iutest::TestPartResult::kSkip)
#define II_T_ASRT_(expression,on_f) II_AMB_E_B if(const ::iutest::AssertionResult iutest_ar=(expression)) ;else on_f(iutest_ar.message())
#if IUTEST_HAS_EXCEPTIONS
#define II_SEH_THROUGH(st) (void)(st)
#define IUTEST_TEST_THROW_(st,exp_e,on_f) II_AMB_E_B if(const char* msg=""){try{II_S_UR_C_W(II_SEH_THROUGH(st));msg="\nExpected: " #st " throws an exception of type " #exp_e ".\n  Actual: it throws nothing.";goto IP_CAT(iutest_label_throw,__LINE__);}catch(exp_e const&){}catch(...){msg="\nExpected: " #st " throws an exception of type " #exp_e ".\n  Actual: it throws a different type.";goto IP_CAT(iutest_label_throw,__LINE__);}}else IP_CAT(iutest_label_throw,__LINE__):on_f(msg)
#define IUTEST_TEST_THROW_VALUE_(st,exp_e,exp_e_v,on_f,pd_fmt) II_AMB_E_B if(::iutest::AssertionResult iutest_ar=::iutest::AssertionSuccess()){try{II_S_UR_C_W(II_SEH_THROUGH(st));iutest_ar<<"\nExpected: " #st " throws an exception of type " #exp_e ".\n  Actual: it throws nothing.";goto IP_CAT(iutest_label_throw_value,__LINE__);}catch(exp_e const& e){if(const ::iutest::AssertionResult ar = pd_fmt("e",#exp_e_v,e,exp_e_v)){}else{iutest_ar<<"\nExpected: " #st " throws an exception of value\n" <<ar.message();goto IP_CAT(iutest_label_throw_value,__LINE__);}}catch(...){iutest_ar<<"\nExpected: " #st " throws an exception of type " #exp_e ".\n  Actual: it throws a different type.";goto IP_CAT(iutest_label_throw_value,__LINE__);}}else IP_CAT(iutest_label_throw_value,__LINE__):on_f(iutest_ar.message())
#define IUTEST_TEST_THROW_VALUE_EQ_(st,exp_e,exp_e_v,on_f) IUTEST_TEST_THROW_VALUE_(st,exp_e,exp_e_v,on_f ,::iutest::internal::bkw::EqHelper<II_IS_NL(exp_e_v)>::Compare)
#define IUTEST_TEST_THROW_VALUE_NE_(st,exp_e,exp_e_v,on_f) IUTEST_TEST_THROW_VALUE_(st,exp_e,exp_e_v,on_f ,::iutest::internal::bkw::NeHelper<II_IS_NL(exp_e_v)>::Compare)
#define IUTEST_TEST_THROW_VALUE_STREQ_(st,exp_e,exp_e_v,on_f) IUTEST_TEST_THROW_VALUE_(st,exp_e,exp_e_v,on_f ,::iutest::internal::CmpHelperSTREQ)
#define IUTEST_TEST_THROW_VALUE_STRCASEEQ_(st,exp_e,exp_e_v,on_f) IUTEST_TEST_THROW_VALUE_(st,exp_e,exp_e_v,on_f ,::iutest::internal::CmpHelperSTRCASEEQ)
#define IUTEST_TEST_ANY_THROW_(st,on_f) II_AMB_E_B if(::iutest::detail::AlwaysTrue()){try{II_SEH_THROUGH(st);goto IP_CAT(iutest_label_anythrow,__LINE__);}catch(...){}}else IP_CAT(iutest_label_anythrow,__LINE__):on_f("\nExpected: " #st " throws an exception.\n  Actual: it doesn's throws.")
#define IUTEST_TEST_NO_THROW_(st,on_f) II_AMB_E_B if(::iutest::AssertionResult iutest_ar=::iutest::AssertionSuccess()){try{II_SEH_THROUGH(st);}catch(const ::std::exception& e){iutest_ar<<"\nExpected: " #st " doesn't throw an exception.\n  Actual: it throws. what is \"" <<e.what()<<"\"";goto IP_CAT(iutest_label_nothrow,__LINE__);}catch(const char *e){iutest_ar<<"\nExpected: " #st " doesn't throw an exception.\n  Actual: it throws. \"" <<e<<"\"";goto IP_CAT(iutest_label_nothrow,__LINE__);}catch(...){iutest_ar<<"\nExpected: " #st " doesn't throw an exception.\n  Actual: it throws.";goto IP_CAT(iutest_label_nothrow,__LINE__);}}else IP_CAT(iutest_label_nothrow,__LINE__):on_f(iutest_ar.message())
#endif
#define IUTEST_TEST_BOOLEAN_(expression,text,actual,expected,on_f) II_AMB_E_B if(const ::iutest::AssertionResult iutest_ar=::iutest::AssertionResult::Is(expression)) ;else on_f(::iutest::internal::GetBooleanAssertionFailureMessage(iutest_ar,text,#actual,#expected).c_str())
#define IUTEST_ASSERT_EXIT(cond) do { if(!(cond)){ II_MSG(#cond,::iutest::TestPartResult::kFatalFailure);exit(1);}}while(::iutest::detail::AlwaysFalse())
#define II_S() II_MSG("Succeeded.\n",::iutest::TestPartResult::kSuccess)
#define II_F() II_A_FAIL("Failed.\n")
#define II_ADD_F() II_E_FAIL("Failed.\n")
#define II_ADD_F_AT(file_,line_) II_E_FAIL_AT("Failed.\n",file_,line_)
#define II_S_MSG(msg_) const ::iutest::AssertionHelper::ScopedMessage IP_CAT(scoped_message_,IUTEST_PP_COUNTER)=::iutest::detail::iuCodeMessage(__FILE__,__LINE__,::iutest::Message()<<(msg_))
#define II_TRGH_A_A_(expr,todo) todo
#define IUTEST_TEST_EQ(expected,actual,on_f) II_PRD_FMT2_(::iutest::internal::bkw::EqHelper<II_IS_NL(expected)>::Compare ,expected,actual,on_f)
#define IUTEST_TEST_ALMOST_EQ(expected,actual,on_f) II_PRD_FMT2_(::iutest::internal::bkw::AlmostEqHelper<II_IS_NL(expected)>::Compare ,expected,actual,on_f)
#define IUTEST_TEST_NE(v1,v2,on_f) II_PRD_FMT2_(::iutest::internal::bkw::NeHelper<II_IS_NL(v1)>::Compare ,v1,v2,on_f)
#define IUTEST_TEST_LE(v1,v2,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperLE ,v1,v2,on_f)
#define IUTEST_TEST_LT(v1,v2,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperLT ,v1,v2,on_f)
#define IUTEST_TEST_GE(v1,v2,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperGE ,v1,v2,on_f)
#define IUTEST_TEST_GT(v1,v2,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperGT ,v1,v2,on_f)
#define IUTEST_TEST_TRUE(expr,text,on_f) IUTEST_TEST_BOOLEAN_(expr,text,false,true,on_f)
#define IUTEST_TEST_FALSE(expr,text,on_f) IUTEST_TEST_BOOLEAN_(!(expr),text,true,false,on_f)
#define IUTEST_TEST_FLOAT_EQ(expected,actual,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperFloatingPointEQ<float> ,expected,actual,on_f)
#define IUTEST_TEST_DOUBLE_EQ(expected,actual,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperFloatingPointEQ<double> ,expected,actual,on_f)
#if IUTEST_HAS_LONG_DOUBLE
#define IUTEST_TEST_LONG_DOUBLE_EQ(expected,actual,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperFloatingPointEQ<long double> ,expected,actual,on_f)
#endif
#define IUTEST_TEST_NEAR(v1,v2,abs_v,on_f) II_PRD_FMT3_(::iutest::internal::CmpHelperNear ,v1,v2,abs_v,on_f)
#define IUTEST_TEST_STREQ(expected,actual,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperSTREQ ,expected,actual,on_f)
#define IUTEST_TEST_STRNE(v1,v2,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperSTRNE ,v1,v2,on_f)
#define IUTEST_TEST_STRCASEEQ(expected,actual,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperSTRCASEEQ ,expected,actual,on_f)
#define IUTEST_TEST_STRCASENE(v1,v2,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperSTRCASENE ,v1,v2,on_f)
#define IUTEST_TEST_SAME(v1,v2,on_f) II_PRD_FMT2_(::iutest::internal::CmpHelperSame ,v1,v2,on_f)
#define IUTEST_TEST_NULL(v,on_f) II_TRGH_A_A_(v==IUTEST_NULLPTR ,II_PRD_FMT1_(::iutest::internal::NullHelper<II_IS_NL(v)>::CompareEq ,v,on_f))
#define IUTEST_TEST_NOTNULL(v,on_f) II_TRGH_A_A_(v!=IUTEST_NULLPTR ,II_PRD_FMT1_(::iutest::internal::NullHelper<II_IS_NL(v)>::CompareNe ,v,on_f))
#define IUTEST_TEST_NO_FAILURE_(st,on_f) II_AMB_E_B if(::iutest::detail::AlwaysTrue()){::iutest::detail::NewTestPartResultCheckHelper::Counter< ::iutest::detail::NewTestPartResultCheckHelper::CondGt< ::iutest::TestPartResult::kSuccess> > iutest_failure_checker;II_S_UR_C_W({(void)0;st;}) if(iutest_failure_checker.count()> 0){goto IP_CAT(iutest_label_test_no_failure_,__LINE__);}}else IP_CAT(iutest_label_test_no_failure_,__LINE__):on_f("\nExpected: " #st " doesn't generate new failure.\n  Actual: it does.")
#define IUTEST_TEST_NO_FATAL_FAILURE_(st,on_f) II_AMB_E_B if(::iutest::detail::AlwaysTrue()){::iutest::detail::NewTestPartResultCheckHelper::Counter< ::iutest::detail::NewTestPartResultCheckHelper::CondEq< ::iutest::TestPartResult::kFatalFailure> > iutest_failure_checker;II_S_UR_C_W({(void)0;st;}) if(iutest_failure_checker.count()> 0){goto IP_CAT(iutest_label_test_no_fatalfailure_,__LINE__);}}else IP_CAT(iutest_label_test_no_fatalfailure_,__LINE__):on_f("\nExpected: " #st " doesn't generate new fatal failure.\n  Actual: it does.")
#define IUTEST_TEST_SKIP() II_AMB_E_B if(::iutest::detail::AlwaysTrue()) IUTEST_SKIP_MESSAGE(::iutest::UnitTest::SkipTest()?"Skipped. " : "Skipped. but already failed. ")
#define IUTEST_TEST_COMPILEERROR(e) IUTEST_PRAGMA_MESSAGE("IUTEST_TEST_COMPILEERROR( " #e " )")
#if IUTEST_HAS_STATIC_ASSERT
#define IUTEST_TEST_STATICASSERT(e) IUTEST_TEST_COMPILEERROR(e)
#else
#define IUTEST_TEST_STATICASSERT(e) IUTEST_TEST_COMPILEERROR("static_assert")
#endif
namespace iutest{namespace detail{
#ifndef IUTEST_VPRINTF
#define IUTEST_VPRINTF(f,a) vprintf(f,a)
#endif
class iuLogger{public: virtual ~iuLogger() II_CXX_DF_F virtual void output(const char* fmt,...) II_ATR_F_P(2,3){va_list va;va_start(va,fmt);voutput(fmt,va);va_end(va);}virtual void voutput(const char* fmt,va_list va)=0;};class iuConsole{public: enum Color{black,red,green,yellow,blue,magenta,cyan,white};public: static inline void output(const char *fmt,...) II_ATR_F_P(1,2);static inline void voutput(const char* fmt,va_list va) II_ATR_F_P(1,0);static inline void color_output(Color color,const char *fmt,...) II_ATR_F_P(2,3);public: static inline void nl_output(const char *fmt,...) II_ATR_F_P(1,2);static inline void nl_voutput(const char* fmt,va_list va) II_ATR_F_P(1,0);public: static iuLogger* SetLogger(iuLogger* logger){iuLogger* pre=GetLoggerInstanceVariable().pInstance;GetLoggerInstanceVariable().pInstance=logger;return pre;}public: static bool IsColorModeOff(){return TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_OFF);}static bool IsColorModeOn(){return TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ON);}static bool IsColorModeAnsi(){return TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ANSI);}private: static inline void color_output_impl(Color color,const char* fmt,va_list va) II_ATR_F_P(2,0);static inline bool IsShouldUseColor(bool use_color);static inline bool HasColorConsole();static inline bool IsStringEqual(const char* str1,const char* str2){return strcmp(str1,str2)==0;}private: struct LoggerInstanceVariable{iuLogger* pInstance;};static LoggerInstanceVariable& GetLoggerInstanceVariable(){static LoggerInstanceVariable sLogger;return sLogger;}static iuLogger* GetLogger(){return GetLoggerInstanceVariable().pInstance;}};inline void iuConsole::output(const char *fmt,...){va_list va;va_start(va,fmt);voutput(fmt,va);va_end(va);}inline void iuConsole::voutput(const char* fmt,va_list va){iuLogger* pLogger=GetLogger();if(pLogger!=0){pLogger->voutput(fmt,va);}else{nl_voutput(fmt,va);}}inline void iuConsole::color_output(Color color,const char *fmt,...){va_list va;va_start(va,fmt);if(IsShouldUseColor(true)){color_output_impl(color,fmt,va);}else{voutput(fmt,va);}va_end(va);}inline void iuConsole::nl_output(const char *fmt,...){va_list va;va_start(va,fmt);nl_voutput(fmt,va);va_end(va);}inline void iuConsole::nl_voutput(const char* fmt,va_list va){IUTEST_VPRINTF(fmt,va);}inline void iuConsole::color_output_impl(Color color,const char* fmt,va_list va){(void)(fmt);(void)(va);{output("\033[1;3%cm",'0' + color);voutput(fmt,va);output("\033[m");}}inline bool iuConsole::IsShouldUseColor(bool use_color){if(IsColorModeOn()){return true;}else if(IsColorModeOff()){return false;}static bool has_color=HasColorConsole();return use_color&&has_color;}inline bool iuConsole::HasColorConsole(){return false;}}}namespace iutest{namespace detail{class iuOptionMessage{public: static void ShowHelp();static void ShowVersion();static void ShowFeature();static void ShowSpec();};inline void iuOptionMessage::ShowHelp(){detail::iuConsole::color_output(detail::iuConsole::cyan,"--------------------------------------------------\nName\n    iutest - iris unit test framework\n--------------------------------------------------\nCommand Line Options\n\n    --help, -h                       : Generate help message.\n    --iutest_list_tests              : List up tests.\n    --iutest_list_tests_with_where   : List up tests with where.\n    --iutest_color=<yes|no|auto|ansi>: Console color enable.\n    --iutest_flagfile=<file>         : Set the flag from the file.\n    --iutest_filter=<filter>         : Select the test run.\n    --iutest_shuffle                 : Do shuffle test.\n    --iutest_random_seed=<seed>      : Set random seed.\n    --iutest_also_run_disabled_tests : Run disabled tests.\n    --iutest_break_on_f[=0|1]  : When that failed to break.\n    --iutest_throw_on_f[=0|1]  : When that failed to throw.\n    --iutest_catch_exceptions=<0|1>  : Catch exceptions enable.\n    --iutest_print_time=<0|1>        : Setting the display of elapsed time.\n    --iutest_default_package_name=<name>\n            : Set default root package name.\n    --iutest_output=<xml|junit>[:path]\n            : Path of xml report.\n    --iutest_repeat=<count>\n            : Set the number of repetitions of the test.\n              use a negative count to repeat forever.\n"
#if IUTEST_HAS_STREAM_RESULT
"    --iutest_stream_result_to=<host:port>\n                                     : Set stream test results server.\n"
#endif
"    --iutest_file_location=<auto|vs|gcc>\n                                     : Format file location messages.\n    --verbose                        : Verbose option.\n    --feature                        : Show iutest feature.\n    --version, -v                    : Show iutest version.\n\n--------------------------------------------------\nLicense\n\n    Copyright (c) 2011-2018, Takazumi-Shirayanagi\n\n    This software is released under the new BSD License, see LICENSE\n\n");}inline void iuOptionMessage::ShowVersion(){detail::iuConsole::output("iutest version %x.%x.%x.%x\n",IUTEST_MAJORVER,IUTEST_MINORVER,IUTEST_BUILD,IUTEST_REVISION);}
#define II_S_M(mcr) II_S_M_I(#mcr,IUTEST_PP_TOSTRING(mcr))
#define II_S_M_I(name,value) detail::iuConsole::output("#define %s  %s\n",name,value)
#define II_S_E_M(mcr) IUTEST_PP_IF(mcr,II_S_M_I(#mcr,IUTEST_PP_TOSTRING(mcr)),IP_EMPTY())
#define II_S_D_M(mcr) IUTEST_PP_IF(mcr,IP_EMPTY(),II_S_M_I(#mcr,IUTEST_PP_TOSTRING(mcr)))
#define II_S_F_M(m) m(IUTEST_HAS_ANY_PARAM_TEST);m(IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT);m(IUTEST_HAS_ASSERTION_RETURN);m(IUTEST_HAS_AUTOFIXTURE_PARAM_TEST);m(IUTEST_HAS_COMBINE);m(IUTEST_HAS_CONCAT);m(IUTEST_HAS_CSVPARAMS);m(IUTEST_HAS_EXCEPTIONS);m(IUTEST_HAS_GENRAND);m(IUTEST_HAS_IGNORE_TEST);m(IUTEST_HAS_LONG_DOUBLE);m(IUTEST_HAS_LIB);m(IUTEST_HAS_MATCHERS);m(IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF);m(IUTEST_HAS_MATCHER_EACH);m(IUTEST_HAS_MATCHER_ELEMENTSARE);m(IUTEST_HAS_MATCHER_FLOATINGPOINT_NEAR);m(IUTEST_HAS_MATCHER_POINTWISE);m(IUTEST_HAS_MATCHER_REGEX);m(IUTEST_HAS_MATCHER_VARIADIC);m(IUTEST_HAS_MINIDUMP);m(IUTEST_HAS_PACKAGE);m(IUTEST_HAS_PAIRWISE);m(IUTEST_HAS_PARAM_METHOD_TEST);m(IUTEST_HAS_PARAM_TEST);m(IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR);m(IUTEST_HAS_PEEP);m(IUTEST_HAS_PEEP_CLASS);m(IUTEST_HAS_PEEP_FUNC);m(IUTEST_HAS_PEEP_STATIC_FUNC);m(IUTEST_HAS_PRINT_TO);m(IUTEST_HAS_RANDOMVALUES);m(IUTEST_HAS_REGEX);m(IUTEST_HAS_REPORT_SKIPPED);m(IUTEST_HAS_SOCKET);m(IUTEST_HAS_SPI_LAMBDA_SUPPORT);m(IUTEST_HAS_STATIC_ASSERT);m(IUTEST_HAS_STATIC_ASSERT_TYPEEQ);m(IUTEST_HAS_STREAM_BUFFER);m(IUTEST_HAS_STREAM_RESULT);m(IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE);m(IUTEST_HAS_TESTNAME_ALIAS);m(IUTEST_HAS_TESTNAME_ALIAS_JP);m(IUTEST_HAS_TYPED_TEST);m(IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME);m(IUTEST_HAS_TYPED_TEST_P);m(IUTEST_HAS_VALUESGEN);m(IUTEST_HAS_VARIADIC_COMBINE);m(IUTEST_HAS_VARIADIC_PAIRWISE);m(IUTEST_HAS_VARIADIC_VALUES)
inline void iuOptionMessage::ShowFeature(){II_S_F_M(II_S_E_M);II_S_F_M(II_S_D_M);}inline void iuOptionMessage::ShowSpec(){II_S_M(IUTEST_PLATFORM);II_S_M(IUTEST_CHECK_STRICT);II_S_M(IUTEST_CPLUSPLUS);II_S_M(IUTEST_HAS_ANALYSIS_ASSUME);II_S_M(IUTEST_HAS_ATTRIBUTE);II_S_M(IUTEST_HAS_AUTO);II_S_M(IUTEST_HAS_CATCH_SEH_EXCEPTION_ASSERTION);II_S_M(IUTEST_HAS_CHAR16_T);II_S_M(IUTEST_HAS_CHAR16_T_PRINTABLE);II_S_M(IUTEST_HAS_CHAR32_T);II_S_M(IUTEST_HAS_CHAR32_T_PRINTABLE);II_S_M(IUTEST_HAS_CLOCK);II_S_M(IUTEST_HAS_CONCEPTS);II_S_M(IUTEST_HAS_CONSTEXPR);II_S_M(IUTEST_HAS_CONSTEXPR_IF);II_S_M(IUTEST_HAS_COUNTER_MACRO);II_S_M(IUTEST_HAS_CTIME);II_S_M(IUTEST_HAS_CXX_HDR_ANY);II_S_M(IUTEST_HAS_CXX_HDR_ARRAY);II_S_M(IUTEST_HAS_CXX_HDR_CHARCONV);II_S_M(IUTEST_HAS_CXX_HDR_CHRONO);II_S_M(IUTEST_HAS_CXX_HDR_CODECVT);II_S_M(IUTEST_HAS_CXX_HDR_CSTDINT);II_S_M(IUTEST_HAS_CXX_HDR_CUCHAR);II_S_M(IUTEST_HAS_CXX_HDR_FILESYSTEM);II_S_M(IUTEST_HAS_CXX_HDR_OPTIONAL);II_S_M(IUTEST_HAS_CXX_HDR_RANDOM);II_S_M(IUTEST_HAS_CXX_HDR_REGEX);II_S_M(IUTEST_HAS_CXX_HDR_STRING_VIEW);II_S_M(IUTEST_HAS_CXX_HDR_TYPE_TARITS);II_S_M(IUTEST_HAS_CXX_HDR_VARIANT);II_S_M(IUTEST_HAS_CXX_HDR_VERSION);II_S_M(IUTEST_HAS_CXX11);II_S_M(IUTEST_HAS_CXX14);II_S_M(IUTEST_HAS_CXX1Z);II_S_M(IUTEST_HAS_CXX17);II_S_M(IUTEST_HAS_CXX2A);II_S_M(IUTEST_HAS_DECLTYPE);II_S_M(IUTEST_HAS_DEFAULT_FUNCTIONS);II_S_M(IUTEST_HAS_DELETED_FUNCTIONS);II_S_M(IUTEST_HAS_EXCEPTIONS);II_S_M(IUTEST_HAS_EXPLICIT_CONVERSION);II_S_M(IUTEST_HAS_EXTERN_TEMPLATE);II_S_M(IUTEST_HAS_GETTIMEOFDAY);II_S_M(IUTEST_HAS_HDR_CXXABI);II_S_M(IUTEST_HAS_HDR_SYSTIME);II_S_M(IUTEST_HAS_IF_EXISTS);II_S_M(IUTEST_HAS_INITIALIZER_LIST);II_S_M(IUTEST_HAS_INLINE_VARIABLE);II_S_M(IUTEST_HAS_INT128);II_S_M(IUTEST_HAS_IOMANIP);II_S_M(IUTEST_HAS_LAMBDA);II_S_M(IUTEST_HAS_LAMBDA_STATEMENTS);II_S_M(IUTEST_HAS_MOVE_ASSIGNMENT_DEFAULT_FUNCTION);II_S_M(IUTEST_HAS_NOEXCEPT);II_S_M(IUTEST_HAS_NULLPTR);II_S_M(IUTEST_HAS_OVERRIDE_AND_FINAL);II_S_M(IUTEST_HAS_RTTI);II_S_M(IUTEST_HAS_RVALUE_REFS);II_S_M(IUTEST_HAS_SEH);II_S_M(IUTEST_HAS_STD_BEGIN_END);II_S_M(IUTEST_HAS_STD_DECLVAL);II_S_M(IUTEST_HAS_STD_EMPLACE);II_S_M(IUTEST_HAS_STD_FILESYSTEM);II_S_M(IUTEST_HAS_STD_QUICK_EXIT);II_S_M(IUTEST_HAS_STD_STR_TO_VALUE);II_S_M(IUTEST_HAS_STD_TO_CHARS);II_S_M(IUTEST_HAS_STRINGSTREAM);II_S_M(IUTEST_HAS_STRONG_ENUMS);II_S_M(IUTEST_HAS_STRSTREAM);II_S_M(IUTEST_HAS_TUPLE);II_S_M(IUTEST_HAS_VARIADIC_TEMPLATES);II_S_M(IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES);II_S_M(IUTEST_HAS_VARIADIC_TUPLES);II_S_M(IUTEST_HAS_WANT_SECURE_LIB);II_S_M(IUTEST_USE_OWN_LIST);II_S_M(IUTEST_USE_OWN_STRING_VIEW);II_S_M(IUTEST_USE_THROW_ON_ASSERTION_FAILURE);II_S_M(IUTEST_WCHAR_UNSIGNED);
#ifdef II_LSTDCXX_V
II_S_M(II_LSTDCXX_V);
#endif
#ifdef __GLIBCXX__
II_S_M(__GLIBCXX__);
#endif
#ifdef __GLIBCPP__
II_S_M(__GLIBCPP__);
#endif
#ifdef _GLIBCXX_USE_CXX11_ABI
II_S_M(_GLIBCXX_USE_CXX11_ABI);
#endif
#ifdef _LIBCPP_VERSION
II_S_M(_LIBCPP_VERSION);
#endif
#ifdef __POSIX_VISIBLE
II_S_M(__POSIX_VISIBLE);
#endif
#undef II_S_M
}}}namespace iutest{class TestInfo;class TestCase;class TestPartResult;namespace detail{class iuITestInfoMediator{protected: TestInfo* m_test_info;public: explicit iuITestInfoMediator(TestInfo* p=0) II_CXX_NEX_S:m_test_info(p){}public: virtual ~iuITestInfoMediator() II_CXX_DF_F virtual bool HasFatalFailure()const=0;virtual bool HasNonfatalFailure()const=0;virtual bool HasFailure()const=0;virtual bool IsSkipped()const=0;TestInfo* ptr()const II_CXX_NEX_S{return m_test_info;}};class iuITestCaseMediator{protected: TestCase* m_test_case;public: explicit iuITestCaseMediator(TestCase* p=0) II_CXX_NEX_S:m_test_case(p){}public: virtual ~iuITestCaseMediator() II_CXX_DF_F virtual const char* test_case_name()const=0;virtual const char* type_param()const=0;TestCase* ptr()const II_CXX_NEX_S{return m_test_case;}};}}namespace iutest{template<typename T>class WithParamInterface;template<typename T>class TestWithParam;namespace detail{::std::string MakeIndexName(size_t index);}class Test{IP_DIS_C_A_A(Test);public: Test():test_info_(0),m_test_info(0),m_random_seed(0){CurrentTestObserver::s_current=this;}virtual ~Test(){CurrentTestObserver::s_current=0;}public: static const TestInfo* GetCurrentTestInfo(){const Test* curr=GetCurrentTest();if(curr==0||curr->m_test_info==0){return 0;}return curr->m_test_info->ptr();}static Test* GetCurrentTest(){return CurrentTestObserver::GetCurrentTest();}static bool HasFatalFailure(){return GetCurrentTest()->m_test_info->HasFatalFailure();}static bool HasNonfatalFailure(){return GetCurrentTest()->m_test_info->HasNonfatalFailure();}static bool HasFailure(){return GetCurrentTest()->m_test_info->HasFailure();}static bool IsSkipped(){return GetCurrentTest()->m_test_info->IsSkipped();}static void RecordProperty(const ::std::string& key,const ::std::string& value);template<typename T>static void RecordProperty(const ::std::string& key,const T& value){RecordPropertyString(key,PrintToString(value));}unsigned int genrand(){return m_random.genrand();}unsigned int genrand(unsigned int max){return m_random.genrand(max);}float genrandf(){return m_random.genrandf();}unsigned int random_seed()const II_CXX_NEX_S{return m_random_seed;}detail::iuRandom& random_engine(){return m_random;}protected: virtual void SetUp(){}virtual void Body(){}virtual void TearDown(){}public: static void SetUpTestCase(){}static void TearDownTestCase(){}private: void Run(detail::iuITestInfoMediator* test_info);static void RecordPropertyString(const ::std::string& key,const ::std::string& value);private: struct should_be_SetUp{};virtual should_be_SetUp* Setup() II_CXX_F{return 0;}private: template<typename DMY>class Observer{public: static Test* s_current;public: static Test* GetCurrentTest() II_CXX_NEX_S{return s_current;}};typedef Observer<void> CurrentTestObserver;private: class TestRecordPropertyHelper{public: static void RecordProperty(const TestProperty& prop);};protected: const TestInfo* test_info_;private: friend class UnitTest;friend class UnitTestImpl;friend class TestInfo;detail::iuITestInfoMediator* m_test_info;detail::iuRandom m_random;unsigned int m_random_seed;};template<typename ParamType>struct TestParamInfo{TestParamInfo(const ParamType& p,size_t i):param(p),index(i){}ParamType param;size_t index;};template<typename T>class WithParamInterface{public: typedef T ParamType;typedef TestParamInfo<T> TestParamInfoType;protected: virtual ~WithParamInterface(){}public: static const ParamType& GetParam(){IUTEST_CHECK_(s_params!=0)<<"GetParam() can only use the value-parameterized test";;return *s_params;}
#if IUTEST_HAS_TUPLE
template<int N>static const typename tuples::tuple_element<N,ParamType>::type& GetParam(){return tuples::get<N>(GetParam());}
#endif
static const ::std::string MakeTestParamName(const TestParamInfoType& info){return detail::MakeIndexName(info.index);}static void SetParam(const ParamType* params) II_CXX_NEX_S{s_params=params;}private: static const ParamType* s_params;};template<typename T>const T* WithParamInterface<T>::s_params=0;template<typename T>class TestWithParam:public Test,public WithParamInterface<T>{};namespace detail{template<typename T>class is_useful_testfixture:public iutest_type_traits::false_type{};namespace is_useful_tf_helper{template<typename T>class is_override_setup{template<bool b,typename U>struct impl{typedef iutest_type_traits::false_type type;};template<typename U>struct impl<true,U>{typedef int yes_t;typedef char no_t;static no_t check(void(Test::*)());static yes_t check(...);typedef iutest_type_traits::bool_constant<sizeof(check(&U::SetUp))==sizeof(yes_t)> type;};public: typedef typename impl<iutest_type_traits::is_base_of<Test,T>::value,T>::type type;};}template<typename T>class is_useful_testfixture<void(int(T))>:public is_useful_tf_helper::is_override_setup<T>::type{};inline bool IsDisableTestName(const ::std::string& name){if(detail::IsStringForwardMatching(name,"DISABLED_")|| detail::IsStringContains(name,"/DISABLED_")){return true;}return false;}}}template<typename DMY>::iutest::Test* ::iutest::Test::Observer<DMY>::s_current=0;namespace iutest{inline void Test::RecordPropertyString(const ::std::string& key,const ::std::string& value){TestProperty prop(key,value);TestRecordPropertyHelper::RecordProperty(prop);}inline void Test::RecordProperty(const ::std::string& key,const ::std::string& value){RecordPropertyString(key,value);}inline void Test::Run(detail::iuITestInfoMediator* test_info){m_test_info=test_info;test_info_=test_info->ptr();unsigned int seed=TestEnv::get_random_seed();if(seed==0){seed=detail::GetIndefiniteValue();}m_random_seed=seed;m_random.init(seed);SetUp();if(!HasFailure()&&!IsSkipped()){Body();}TearDown();test_info_=0;m_test_info=0;}}namespace iutest{class Test;namespace detail{class iuFactoryBase{IP_DIS_C_A_A(iuFactoryBase);public: iuFactoryBase() II_CXX_NEX_S{}virtual ~iuFactoryBase(){}public: virtual auto_ptr<Test> Create()=0;};template<class Tester>class iuFactory:public iuFactoryBase{public: virtual auto_ptr<Test> Create() II_CXX_O{auto_ptr<Test> p(new Tester());return p;}};template<typename ParamType>class iuParamTestFactoryBase:public iuFactoryBase{public: iuParamTestFactoryBase():m_param(){}explicit iuParamTestFactoryBase(ParamType param):m_param(param){}public: void SetParam(ParamType param){m_param=param;}const ParamType& GetParam()const{return m_param;}protected: ParamType m_param;};template<class Tester>class iuParamTestFactory:public iuParamTestFactoryBase<typename Tester::ParamType>{typedef typename Tester::ParamType ParamType;typedef iuParamTestFactoryBase<ParamType> _Mybase;public: iuParamTestFactory() II_CXX_DF_F explicit iuParamTestFactory(ParamType param):_Mybase(param){}public: virtual auto_ptr<Test> Create() II_CXX_O{Tester::SetParam(&this->m_param);auto_ptr<Test> p(new Tester());return p;}};}}namespace iutest{class TestInfo{public: TestInfo(detail::iuITestCaseMediator* testcase,const ::std::string& name,detail::iuFactoryBase* factory):m_testname(name),m_factory(factory),m_testcase(testcase),m_should_run(true),m_ran(false),m_disable(detail::IsDisableTestName(name)),m_skip(false),m_matches_filter(true){m_mediator.SetPointer(this);}public: const char* test_case_name()const{return m_testcase->test_case_name();}const char* name()const{return m_testname.c_str();}bool should_run()const II_CXX_NEX_S{return m_should_run;}bool is_ran()const II_CXX_NEX_S{return m_ran;}bool is_disabled_test()const II_CXX_NEX_S{return m_disable;}bool is_skipped()const II_CXX_NEX_S{return m_skip||m_test_result.Skipped();}bool is_reportable()const II_CXX_NEX_S{return m_matches_filter;}TimeInMillisec elapsed_time()const{return m_test_result.elapsed_time();}const TestResult* result()const II_CXX_NEX_S{return &m_test_result;}const char* value_param()const{return m_value_param.empty()?0:m_value_param.c_str();}const char* type_param()const{return m_testcase->type_param();}::std::string t_c_name_with_default_package_name()const{return TestEnv::AddDefaultPackageName(test_case_name());}public: bool HasFatalFailure()const{return m_test_result.HasFatalFailure();}bool HasNonfatalFailure()const{return m_test_result.HasNonfatalFailure();}bool HasFailure()const{return m_test_result.Failed();}bool HasWarning()const{return m_test_result.HasWarning();}bool Passed()const{if(is_skipped()){return false;}return m_test_result.Passed();}public: ::std::string test_full_name()const{::std::string fullname=test_case_name();fullname+=".";fullname+=name();return fullname;}::std::string test_name_with_where()const{::std::string str=m_testname;if(value_param()!=0){str+=", where GetParam() = ";str+=m_value_param;}return str;}public: static bool ValidateTestPropertyName(const ::std::string& name){const char* ban[]={"name","status","time","classname","type_param","value_param"};return TestProperty::ValidateName(name,ban);}public: void set_value_param(const char* str){m_value_param=str;}private: bool Run();private: void RunImpl();private: void clear();bool filter();void skip(){m_skip=true;}private: class Mediator II_CXX_F:public detail::iuITestInfoMediator{public: explicit Mediator(TestInfo* p=0) II_CXX_NEX_S:iuITestInfoMediator(p){}public: virtual bool HasFatalFailure()const II_CXX_O{return ptr()->HasFatalFailure();}virtual bool HasNonfatalFailure()const II_CXX_O{return ptr()->HasNonfatalFailure();}virtual bool HasFailure()const II_CXX_O{return ptr()->HasFailure();}virtual bool IsSkipped()const II_CXX_O{return ptr()->is_skipped();}public: void SetPointer(TestInfo* p){m_test_info=p;}};private: friend class UnitTestImpl;friend class UnitTest;friend class TestCase;::std::string m_testname;::std::string m_value_param;TestResult m_test_result;Mediator m_mediator;detail::iuFactoryBase* m_factory;detail::iuITestCaseMediator* m_testcase;bool m_should_run;bool m_ran;bool m_disable;bool m_skip;bool m_matches_filter;IP_DIS_C_A_A(TestInfo);};}namespace iutest{inline bool TestInfo::Run(){if(!should_run()){return true;}TestEnv::event_listeners().OnTestStart(*this);RunImpl();TestEnv::event_listeners().OnTestEnd(*this);return !HasFailure();}inline void TestInfo::RunImpl(){detail::iuStopWatch sw;TimeInMillisec elapsedmsec=0;m_ran=true;
#if IUTEST_HAS_EXCEPTIONS
if(TestFlag::IsEnableFlag(TestFlag::CATCH_EXCEPTION_EACH)){detail::auto_ptr<Test> p=m_factory->Create();try{sw.start();p->Run(&m_mediator);elapsedmsec=sw.stop();}catch(const ::std::exception& e){elapsedmsec=sw.stop();iutest::AssertionHelper(0,-1,detail::FormatCxxException(e.what()),TestPartResult::kFatalFailure).OnFixed(AssertionHelper::Fixed());if(TestFlag::IsEnableFlag(TestFlag::THROW_ON_FAILURE)){throw;}}catch(const TestPartResult::Type& eType){elapsedmsec=sw.stop();if(TestPartResult::type_is_failed(eType)&&TestFlag::IsEnableFlag(TestFlag::THROW_ON_FAILURE)){throw;}}catch(...){elapsedmsec=sw.stop();iutest::AssertionHelper(0,-1,detail::FormatCxxException(0),TestPartResult::kFatalFailure).OnFixed(AssertionHelper::Fixed());if(TestFlag::IsEnableFlag(TestFlag::THROW_ON_FAILURE)){throw;}}}else
#endif
{detail::auto_ptr<Test> p=m_factory->Create();sw.start();p->Run(&m_mediator);elapsedmsec=sw.stop();}m_test_result.set_elapsed_time(elapsedmsec);if(HasFailure()&&TestFlag::IsEnableFlag(TestFlag::THROW_ON_FAILURE)){
#if IUTEST_HAS_EXCEPTIONS
throw HasFatalFailure()?TestPartResult::kFatalFailure:TestPartResult::kNonFatalFailure;
#else
exit(1);
#endif
}}inline void TestInfo::clear(){m_ran=false;m_skip=false;m_test_result.Clear();}inline bool TestInfo::filter(){bool run=true;if(!TestFlag::IsEnableFlag(TestFlag::RUN_DISABLED_TESTS)&& is_disabled_test()){run=false;}bool match=true;if(TestFlag::IsEnableFlag(TestFlag::FILTERING_TESTS)){if(!detail::iuFilterRegex::match(TestEnv::test_filter(),test_full_name().c_str())){match=false;run=false;}}m_matches_filter=match;m_should_run=run;return m_should_run;}}namespace iutest{class TestCase{protected:typedef ::std::vector<TestInfo*> iuTestInfos;protected: TestCase(const ::std::string& t_c_name,TestTypeId id,SetUpMethod setup,TearDownMethod teardown):m_t_c_name(t_c_name),m_setup(setup),m_teardown(teardown),m_id(id),m_disable_num(0),m_should_run_num(0),m_elapsedmsec(0),m_start_timestamp(0),m_disable(detail::IsDisableTestName(t_c_name)){}public: virtual ~TestCase(){}public: const char* name()const{return m_t_c_name.c_str();}int total_test_count()const II_CXX_NEX_S{return static_cast<int>(m_testinfos.size());}int reportable_test_count()const;int test_to_run_count()const II_CXX_NEX_S{return m_should_run_num;}int failed_test_count()const;int disabled_test_count()const II_CXX_NEX_S{return m_disable_num;}int reportable_disabled_test_count()const;int successful_test_count()const;int skip_test_count()const;int reportable_skip_test_count()const;int test_run_skipped_count()const;int reportable_test_run_skipped_count()const;TimeInMillisec elapsed_time()const II_CXX_NEX_S{return m_elapsedmsec;}TimeInMillisec start_timestamp()const II_CXX_NEX_S{return m_start_timestamp;}const TestInfo* GetTestInfo(int index)const{return m_testinfos[index];}bool should_run()const II_CXX_NEX_S{return m_should_run_num!=0;}bool Passed()const{return failed_test_count()==0 && m_ad_hoc_testresult.Passed();}bool Failed()const{return !Passed();}virtual const char* type_param()const{return 0;}::std::string t_c_name_with_where()const{::std::string str=m_t_c_name;if(type_param()!=0){str+=", where TypeParam = ";str+=type_param();}return str;}::std::string t_c_name_with_default_package_name()const{return TestEnv::AddDefaultPackageName(name());}const TestResult* ad_hoc_testresult()const II_CXX_NEX_S{return ad_hoc_test_result();}const TestResult* ad_hoc_test_result()const II_CXX_NEX_S{return &m_ad_hoc_testresult;}public: static bool ValidateTestPropertyName(const ::std::string& name){const char* ban[]={"name","tests","failures","disabled","skip","errors","time"};return TestProperty::ValidateName(name,ban);}private: bool Run();bool RunImpl();private: bool CheckSetUpSkipped();public: struct FindOp{TestTypeId m_id;const char* m_name;bool operator()(const TestCase* p)const{if(p->get_typeid()==m_id&&detail::IsStringEqual(p->m_t_c_name,m_name)){return true;}return false;}};private: void clear();bool filter();private: friend bool operator==(const TestCase& lhs,const TestCase& rhs){return(lhs.m_id==rhs.m_id)&&(strcmp(lhs.name(),rhs.name())==0);}void push_back(TestInfo* p){m_testinfos.push_back(p);}private: iuTestInfos::const_iterator begin()const{return m_testinfos.begin();}iuTestInfos::const_iterator end()const{return m_testinfos.end();}TestTypeId get_typeid()const II_CXX_NEX_S{return m_id;}private: bool HasWarning()const{return m_ad_hoc_testresult.HasWarning()||detail::AnyOverList(m_testinfos,&TestInfo::HasWarning);}private: static bool IsSuccessfulTest(const TestInfo* p){return p->is_ran()&&p->Passed();}static bool IsFailedTest(const TestInfo* p){return p->should_run()&&p->HasFailure();}static bool IsSkipTest(const TestInfo* p){return !p->is_ran()||p->is_skipped();}static bool IsReportableSkipTest(const TestInfo* p){return p->is_reportable()&&IsSkipTest(p);}static bool IsRunSkippedTest(const TestInfo* p){return p->should_run()&&p->is_skipped();}static bool IsReportableRunSkippedTest(const TestInfo* p){return p->is_reportable()&&IsRunSkippedTest(p);}static bool IsReportableDisabledTest(const TestInfo* p){return p->is_reportable()&&p->is_disabled_test();}private: friend class UnitTestImpl;friend class UnitTest;::std::string m_t_c_name;iuTestInfos m_testinfos;SetUpMethod m_setup;TearDownMethod m_teardown;TestTypeId m_id;int m_disable_num;int m_should_run_num;TimeInMillisec m_elapsedmsec;TimeInMillisec m_start_timestamp;bool m_disable;TestResult m_ad_hoc_testresult;IP_DIS_C_A_A(TestCase);};template<typename T>class TypedTestCase:public TestCase{public: typedef T TypeParam;protected: TypedTestCase(const ::std::string& t_c_name,TestTypeId id,SetUpMethod setup,TearDownMethod teardown):TestCase(t_c_name,id,setup,teardown),m_type_param(detail::GetTypeNameProxy<TypeParam>::GetTypeName()){}public: virtual const char* type_param()const II_CXX_O{return m_type_param.empty()?0:m_type_param.c_str();}private: friend class UnitTestImpl;::std::string m_type_param;};namespace detail{class TestCaseMediator II_CXX_F:public detail::iuITestCaseMediator{public: explicit TestCaseMediator(TestCase* p) II_CXX_NEX_S:iuITestCaseMediator(p){}public: virtual const char* test_case_name()const II_CXX_O{return m_test_case->name();}virtual const char* type_param()const II_CXX_O{return m_test_case->type_param();}};}}namespace iutest{inline bool TestCase::Run(){if(!should_run()){return true;}if(TestFlag::IsEnableFlag(TestFlag::SHUFFLE_TESTS)){detail::RandomShuffle(m_testinfos,TestEnv::genrand());}bool result=false;m_start_timestamp=detail::GetTimeInMillis();TestEnv::event_listeners().OnTestCaseStart(*this);
#if IUTEST_HAS_EXCEPTIONS
if(TestFlag::IsEnableFlag(TestFlag::CATCH_EXCEPTION_EACH)){try{result=RunImpl();}catch(const TestPartResult::Type& eType){CheckSetUpSkipped();if(TestPartResult::type_is_failed(eType)&&TestFlag::IsEnableFlag(TestFlag::THROW_ON_FAILURE)){throw;}}catch(...){throw;}}else
#endif
{result=RunImpl();}TestEnv::event_listeners().OnTestCaseEnd(*this);return result;}inline bool TestCase::RunImpl(){bool result=true;m_elapsedmsec=0;m_setup();if(m_ad_hoc_testresult.HasFatalFailure()){return false;}if(CheckSetUpSkipped()){return true;}{detail::iuStopWatch sw;sw.start();for(iuTestInfos::iterator it=m_testinfos.begin(),end=m_testinfos.end();it!=end;++it){if(!(*it)->Run()){result=false;}}m_elapsedmsec=sw.stop();}m_teardown();if(m_ad_hoc_testresult.HasFatalFailure()){return false;}return result;}inline bool TestCase::CheckSetUpSkipped(){if(m_ad_hoc_testresult.Skipped()){for(iuTestInfos::iterator it=m_testinfos.begin(),end=m_testinfos.end();it!=end;++it){(*it)->skip();}return true;}return false;}inline void TestCase::clear(){m_ad_hoc_testresult.Clear();for(iuTestInfos::iterator it=m_testinfos.begin(),end=m_testinfos.end();it!=end;++it){(*it)->clear();}}inline bool TestCase::filter(){m_should_run_num=0;m_disable_num=0;for(iuTestInfos::iterator it=m_testinfos.begin(),end=m_testinfos.end();it!=end;++it){if(m_disable){(*it)->m_disable=true;}if((*it)->is_disabled_test()){++m_disable_num;}if((*it)->filter()){++m_should_run_num;}}return should_run();}inline int TestCase::reportable_test_count()const{return detail::CountIfOverList(m_testinfos,&TestInfo::is_reportable);}inline int TestCase::failed_test_count()const{if(!should_run()){return 0;}return detail::CountIf(m_testinfos,IsFailedTest);}inline int TestCase::successful_test_count()const{if(!should_run()){return 0;}return detail::CountIf(m_testinfos,IsSuccessfulTest);}inline int TestCase::skip_test_count()const{if(!should_run()){return total_test_count();}return detail::CountIf(m_testinfos,IsSkipTest);}inline int TestCase::reportable_skip_test_count()const{if(!should_run()){return reportable_test_count();}return detail::CountIf(m_testinfos,IsReportableSkipTest);}inline int TestCase::test_run_skipped_count()const{if(!should_run()){return 0;}return detail::CountIf(m_testinfos,IsRunSkippedTest);}inline int TestCase::reportable_test_run_skipped_count()const{if(!should_run()){return 0;}return detail::CountIf(m_testinfos,IsReportableRunSkippedTest);}inline int TestCase::reportable_disabled_test_count()const{return detail::CountIf(m_testinfos,IsReportableDisabledTest);}}namespace iutest{class UnitTestImpl{protected:typedef ::std::vector<TestCase*> iuTestCases;typedef ::std::vector<Environment*> iuEnvironmentList;protected: UnitTestImpl():m_total_test_num(0),m_disable_num(0),m_should_run_num(0),m_current_testcase(0),m_elapsedmsec(0){ptr()=this;}~UnitTestImpl(){TerminateImpl();}public: static TestResult* current_test_result();public: static bool ValidateTestPropertyName(const ::std::string& name){const char* ban[]={"name","tests","failures","disabled","skip","errors","time","timestamp","random_seed"};return TestProperty::ValidateName(name,ban);}public: template<typename T>TestCase* AddTestCase(const ::std::string& t_c_name,TestTypeId id,SetUpMethod setup,TearDownMethod teardown II_A_E_TT(T)){TestCase* p=FindTestCase(t_c_name,id);if(p==0){p=new T(t_c_name,id,setup,teardown);m_testcases.push_back(p);}return p;}void AddTestInfo(TestCase* pCase,TestInfo* pInfo);static bool SkipTest();protected: int Listup()const;int ListupWithWhere()const;bool PreRunner();void ClearNonAdHocTestResult();void ClearAdHocTestResult(){m_ad_hoc_testresult.Clear();}private: static void RecordProperty(const TestProperty& prop);TestCase* FindTestCase(const ::std::string& t_c_name,TestTypeId id);bool DoInfoOptions();private: void InitializeImpl();void TerminateImpl();private:private: static UnitTestImpl*& ptr() II_CXX_NEX_S{static UnitTestImpl* ptr=0;return ptr;}protected: friend class UnitTestSource;friend class Test::TestRecordPropertyHelper;int m_total_test_num;int m_disable_num;int m_should_run_num;TestCase* m_current_testcase;TimeInMillisec m_elapsedmsec;iuTestCases m_testcases;TestResult m_ad_hoc_testresult;};namespace detail{::std::string MakeIndexName(size_t index);::std::string MakeIndexTestName(const char* basename,size_t index);::std::string MakeParamTestName(const ::std::string& basename,const ::std::string& parame_name);template<typename T>::std::string MakeIndexTypedTestName(const char* basename,size_t index){
#if IUTEST_HAS_RTTI
::std::string name=MakeIndexTestName(basename,index);name+="/";name+=GetTypeNameProxy<T>::GetTypeNameProxy();return name;
#else
return MakeIndexTestName(basename,index);
#endif
}::std::string MakePrefixedIndexTestName(const char* prefix,const char* basename,size_t index);template<typename T>::std::string MakePrefixedIndexTypedTestName(const char* prefix,const char* basename,size_t index){
#if IUTEST_HAS_RTTI
::std::string name=prefix;if(!name.empty()){name+="/";}name+=MakeIndexTypedTestName<T>(basename,index);return name;
#else
return MakePrefixedIndexTestName(prefix,basename,index);
#endif
}}}namespace iutest{inline TestResult* UnitTestImpl::current_test_result(){if(Test::GetCurrentTestInfo()){return &(Test::GetCurrentTest()->m_test_info->ptr()->m_test_result);}UnitTestImpl* p=ptr();if(p==0){return 0;}if(p->m_current_testcase!=0){return &p->m_current_testcase->m_ad_hoc_testresult;}return &p->m_ad_hoc_testresult;}inline void UnitTestImpl::AddTestInfo(TestCase* pCase,TestInfo* pInfo){++m_total_test_num;pCase->push_back(pInfo);}inline bool UnitTestImpl::SkipTest(){if(current_test_result()->Failed()){return false;}const Test* test=Test::GetCurrentTest();if(test!=0&&test->m_test_info->ptr()!=0){test->m_test_info->ptr()->skip();}return true;}inline int UnitTestImpl::Listup()const{detail::iuConsole::output("%d tests from %" IUPRzu " testcase\n",m_total_test_num,m_testcases.size());for(iuTestCases::const_iterator it=m_testcases.begin(),end=m_testcases.end();it!=end;++it){detail::iuConsole::output("%s\n",(*it)->name());for(TestCase::iuTestInfos::const_iterator it2=(*it)->begin(),end2=(*it)->end();it2!=end2;++it2){detail::iuConsole::output("  %s\n",(*it2)->name());}}return 0;}inline int UnitTestImpl::ListupWithWhere()const{detail::iuConsole::output("%d tests from %" IUPRzu " testcase\n",m_total_test_num,m_testcases.size());for(iuTestCases::const_iterator it=m_testcases.begin(),end=m_testcases.end();it!=end;++it){detail::iuConsole::output("%s\n",(*it)->t_c_name_with_where().c_str());for(TestCase::iuTestInfos::const_iterator it2=(*it)->begin(),end2=(*it)->end();it2!=end2;++it2){detail::iuConsole::output("  %s\n",(*it2)->test_name_with_where().c_str());}}return 0;}inline bool UnitTestImpl::PreRunner(){InitializeImpl();if(DoInfoOptions()){TestFlag::SetFlag(0,~TestFlag::SHOW_MASK);return false;}return true;}inline void UnitTestImpl::ClearNonAdHocTestResult(){for(iuTestCases::iterator it=m_testcases.begin(),end=m_testcases.end();it!=end;++it){(*it)->clear();}}inline void UnitTestImpl::RecordProperty(const TestProperty& prop){UnitTestImpl* p=ptr();TestResult* tr=0;if(Test::GetCurrentTestInfo()){tr=&(Test::GetCurrentTest()->m_test_info->ptr()->m_test_result);if(!TestInfo::ValidateTestPropertyName(prop.key())){II_ADD_F()<<"Reserved key used in RecordProperty(): " <<prop.key();return;}}else if(p->m_current_testcase!=0){tr=&p->m_current_testcase->m_ad_hoc_testresult;if(!TestCase::ValidateTestPropertyName(prop.key())){II_ADD_F()<<"Reserved key used in RecordProperty(): " <<prop.key();return;}}else{tr =&p->m_ad_hoc_testresult;if(!ValidateTestPropertyName(prop.key())){II_ADD_F()<<"Reserved key used in RecordProperty(): " <<prop.key();return;}}tr->RecordProperty(prop);TestEnv::event_listeners().OnTestRecordProperty(prop);}inline TestCase* UnitTestImpl::FindTestCase(const ::std::string& t_c_name,TestTypeId id){TestCase::FindOp func ={id,t_c_name.c_str()};return detail::FindList(m_testcases,func);}inline bool UnitTestImpl::DoInfoOptions(){if(TestFlag::IsEnableFlag(TestFlag::SHOW_INFO_MASK)){if(TestFlag::IsEnableFlag(TestFlag::SHOW_HELP)){detail::iuOptionMessage::ShowHelp();}if(TestFlag::IsEnableFlag(TestFlag::SHOW_VERSION)){detail::iuOptionMessage::ShowVersion();}if(TestFlag::IsEnableFlag(TestFlag::SHOW_FEATURE)){detail::iuOptionMessage::ShowFeature();}if(TestFlag::IsEnableFlag(TestFlag::SHOW_SPEC)){detail::iuOptionMessage::ShowSpec();}return true;}if(TestFlag::IsEnableFlag(TestFlag::SHOW_TESTS_LIST_WITH_WHERE)){ListupWithWhere();return true;}if(TestFlag::IsEnableFlag(TestFlag::SHOW_TESTS_LIST)){Listup();return true;}return false;}inline void UnitTestImpl::InitializeImpl(){if(setlocale(LC_CTYPE,TestEnv::get_locale_ctype())==0){if(TestEnv::is_specific_locale_ctype()){IUTEST_LOG_(WARNING)<<"failed: setlocale LC_CTYPE to " <<TestEnv::get_locale_ctype();}}}inline void UnitTestImpl::TerminateImpl(){for(iuTestCases::iterator it=m_testcases.begin();it!=m_testcases.end();it=m_testcases.begin()){TestCase* p=(*it);m_testcases.erase(it);delete p;}}namespace detail{inline ::std::string MakeIndexName(size_t index){iu_global_format_stringstream strm;strm<<index;return strm.str();}inline ::std::string MakeIndexTestName(const char* basename,size_t index){::std::string name=basename;name+="/";name+=MakeIndexName(index);return name;}inline::std::string MakeParamTestName(const ::std::string& basename,const ::std::string& param_name){if(param_name.empty()){return basename;}::std::string name=basename;name+="/";name+=param_name;return name;}inline ::std::string MakePrefixedIndexTestName(const char* prefix,const char* basename,size_t index){::std::string name=prefix;if(!name.empty()){name+="/";}name+=MakeIndexTestName(basename,index);return name;}}inline void Test::TestRecordPropertyHelper::RecordProperty(const TestProperty& prop){iutest::UnitTestImpl::RecordProperty(prop);}}namespace iutest{namespace detail{class DefaultGlobalTestPartResultReporter:public TestPartResultReporterInterface{public: virtual ~DefaultGlobalTestPartResultReporter() II_CXX_O{}virtual void ReportTestPartResult(const TestPartResult& test_part_result) II_CXX_O{DefaultReportTestPartResult(test_part_result);}static void DefaultReportTestPartResult(const TestPartResult& test_part_result){TestResult* result=UnitTestImpl::current_test_result();if(result){result->AddTestPartResult(test_part_result);}else{iuConsole::output("%s",test_part_result.make_newline_message().c_str());}TestEnv::event_listeners().OnTestPartResult(test_part_result);}};class NoTestPartResultReporter:public TestPartResultReporterInterface{public: virtual ~NoTestPartResultReporter() II_CXX_O{}virtual void ReportTestPartResult(const TestPartResult& result) II_CXX_O{(void)(result);}};class NewTestPartResultCheckHelper{public: template<TestPartResult::Type Type>struct CondEq{bool operator()(const TestPartResult& result){return result.type()==Type;}};template<TestPartResult::Type Type>struct CondNe{bool operator()(const TestPartResult& result){return result.type()!=Type;}};template<TestPartResult::Type Type>struct CondGt{bool operator()(const TestPartResult& result){return result.type()> Type;}};public: class ReporterHolder{public: ReporterHolder():m_origin(0){}virtual ~ReporterHolder(){Detach();}void Attach(TestPartResultReporterInterface* p){m_origin=TestEnv::GetGlobalTestPartResultReporter();TestEnv::SetGlobalTestPartResultReporter(p);}void Detach(){TestEnv::SetGlobalTestPartResultReporter(m_origin);}public: void ReportTestPartResultOrigin(const TestPartResult& result){if(m_origin){m_origin->ReportTestPartResult(result);}}private: TestPartResultReporterInterface* m_origin;};public: template<typename COND,typename REPORTER=DefaultGlobalTestPartResultReporter>class Counter:public REPORTER{typedef REPORTER _Mybase;public: Counter():m_count(0){m_holder.Attach(this);}virtual void ReportTestPartResult(const TestPartResult& result) II_CXX_O{if(m_cond(result)){++m_count;}_Mybase::ReportTestPartResult(result);}public: int count()const II_CXX_NEX_S{return m_count;}private: ReporterHolder m_holder;COND m_cond;int m_count;IP_DIS_C_A_A(Counter);};template<typename REPORTER=DefaultGlobalTestPartResultReporter>class Collector:public REPORTER{typedef REPORTER _Mybase;typedef ::std::vector<TestPartResult> TestPartResults;public: Collector(){m_holder.Attach(this);}public: virtual void ReportTestPartResult(const TestPartResult& result) II_CXX_O{m_results.push_back(result);_Mybase::ReportTestPartResult(result);}public: size_t count()const II_CXX_NEX_S{return m_results.size();}const TestPartResult& GetTestPartResult(size_t index)const{return m_results[index];}void ReportTestPartResult(){for(TestPartResults::iterator it=m_results.begin();it!=m_results.end();++it){m_holder.ReportTestPartResultOrigin(*it);}}private: ReporterHolder m_holder;TestPartResults m_results;};};inline void DefaultReportTestPartResult(const TestPartResult& test_part_result){DefaultGlobalTestPartResultReporter::DefaultReportTestPartResult(test_part_result);}}}namespace iutest{namespace detail{template<typename Generator1,typename Generator2>class iuConcatParamHolder;template<typename T>class iuIParamGenerator{public: typedef T type;public: typedef iuIParamGenerator<T>*(*Generator)();public: virtual ~iuIParamGenerator(){}public: virtual void Begin()=0;virtual T GetCurrent()const=0;virtual void Next()=0;virtual bool IsEnd()const=0;};template<typename T>class iuParamGenerator:public iuIParamGenerator<T>{typedef iuIParamGenerator<T> _Interface;typedef iuParamGenerator<T> _Myt;public: typedef T type;public: iuParamGenerator(_Interface* pInterface=0):m_pInterface(pInterface){}public: operator iuIParamGenerator<T>*()const{return m_pInterface;}public:template<typename Other>iuConcatParamHolder<_Myt,Other> operator+(const Other& g)const{return iuConcatParamHolder<_Myt,Other>(*this,g);}public: virtual void Begin() II_CXX_O{m_pInterface->Begin();}virtual T GetCurrent()const II_CXX_O{return m_pInterface->GetCurrent();}virtual void Next() II_CXX_O{m_pInterface->Next();}virtual bool IsEnd()const II_CXX_O{return m_pInterface->IsEnd();}private: _Interface* m_pInterface;};template<typename T>class iuRangeParamsGenerator:public iuIParamGenerator<T>{T m_begin;T m_end;T m_step;T m_cur;public: iuRangeParamsGenerator(T begin,T end,T step):m_begin(begin),m_end(end),m_step(step),m_cur(begin){}public: virtual void Begin() II_CXX_O{m_cur=m_begin;}virtual T GetCurrent()const II_CXX_O{return m_cur;}virtual void Next() II_CXX_O{m_cur=static_cast<T>(m_cur+m_step);}virtual bool IsEnd()const II_CXX_O{return !(m_cur<m_end);}};class iuBoolParamsGenerator:public iuIParamGenerator<bool>{int m_n;bool m_cur;public: iuBoolParamsGenerator():m_n(0),m_cur(false){}public: virtual void Begin() II_CXX_O{m_cur=false;m_n=0;}virtual bool GetCurrent()const II_CXX_O{return m_cur;}virtual void Next() II_CXX_O{++m_n;m_cur=!m_cur;}virtual bool IsEnd()const II_CXX_O{return m_n>=2;}};template<typename T>class iuValuesInParamsGenerator:public iuIParamGenerator<T>{typedef ::std::vector<T> params_t;params_t m_values;typename params_t::const_iterator m_it;public: explicit iuValuesInParamsGenerator(const params_t& values):m_values(values){}template<typename Container>explicit iuValuesInParamsGenerator(const Container& values){m_values.insert(m_values.end(),values.begin(),values.end());}template<typename TT,size_t SIZE>explicit iuValuesInParamsGenerator(const TT(&values)[SIZE]){m_values.insert(m_values.end(),values,values+SIZE);}template<typename Ite>iuValuesInParamsGenerator(Ite begin,Ite end){m_values.insert(m_values.end(),begin,end);}
#if IUTEST_HAS_INITIALIZER_LIST
iuValuesInParamsGenerator(::std::initializer_list<T> l){m_values.insert(m_values.end(),l.begin(),l.end());}
#endif
public: virtual void Begin() II_CXX_O{m_it=m_values.begin();}virtual T GetCurrent()const II_CXX_O{return *m_it;}virtual void Next() II_CXX_O{++m_it;}virtual bool IsEnd()const II_CXX_O{return(m_it==m_values.end());}};template<typename G1,typename G2>class iuConcatParamHolder{typedef iuConcatParamHolder<G1,G2> _Myt;public: iuConcatParamHolder(const G1& g1,const G2& g2):m_g1(g1),m_g2(g2){}private: iuConcatParamHolder() II_CXX_DL_F;public: template<typename T>operator iuIParamGenerator<T>*(){params_t<T> params;params.append(m_g1);params.append(m_g2);return new iuValuesInParamsGenerator<T>(params.val);}template<typename Other>iuConcatParamHolder<_Myt,Other> operator+(const Other& g)const{return iuConcatParamHolder<_Myt,Other>(*this,g);}private: template<typename T>struct params_t{typedef iuIParamGenerator<T> IParamGenerater;::std::vector<T> val;void append(IParamGenerater* gen){detail::scoped_ptr<IParamGenerater> p(gen);for(p->Begin();!p->IsEnd();p->Next()){val.push_back(p->GetCurrent());}}template<typename U>void append(iuParamGenerator<U>& gen){for(gen.Begin();!gen.IsEnd();gen.Next()){val.push_back(static_cast<T>(gen.GetCurrent()));}}};private: G1 m_g1;G2 m_g2;};
#if IUTEST_HAS_VARIADIC_VALUES
template<typename... Args>class iuValueArray{typedef tuples::tuple<Args...> _MyTuple;typedef iuValueArray<Args...> _Myt;template<typename T>struct make_array{T val[sizeof...(Args)];template<typename U>void operator()(int index,const U& value){val[index]=value;}explicit make_array(const _MyTuple& t){tuples::tuple_foreach(t,*this);}};public: explicit iuValueArray(const Args&... args):v(args...){}
#if defined(__clang__)&&defined(II_LSTDCXX_V)&&II_LSTDCXX_V>=40900
#if IUTEST_HAS_RVALUE_REFS
iuValueArray(const iuValueArray& rhs):v(rhs.v){}iuValueArray(iuValueArray&& rhs):v(rhs.v){}
#endif
#endif
public: template<typename T>operator iuIParamGenerator<T>*()const{make_array<T> ar(v);return new iuValuesInParamsGenerator<T>(ar.val);}public:template<typename Other>iuConcatParamHolder<_Myt,Other> operator+(const Other& g)const{return iuConcatParamHolder<_Myt,Other>(*this,g);}private: _MyTuple v;};
#else
#define II_D_VA_CONSTRUCT_(i,p1,p2) IP_CAT(p1,i)(IP_CAT(p2,i))
#define II_D_VA_STATICCAST_(i,p1,p2) static_cast<p1>(IP_CAT(p2,i))
#define II_D_VA_VARIABLE_(i,p1,p2) IP_CAT(p1,i) IP_CAT(p2,i);
#define II_D_VA_CONCAT_() template<typename Other> iuConcatParamHolder<_Myt,Other> operator+(const Other& g)const{return iuConcatParamHolder<_Myt,Other>(*this,g);}
#define II_D_VA_(n) template<IP_ENM_P(n,typename A)> class IP_CAT(iuValueArray,n){typedef IP_CAT(iuValueArray,n)<IP_ENM_P(n,A)> _Myt;public: IP_CAT(iuValueArray,n)(IP_ENM_B_P(n,A,a)) : IP_ENM_B(n,II_D_VA_CONSTRUCT_,v,a){}template<typename T>operator iuIParamGenerator<T>*()const{const T val[]={IP_ENM_B(n,II_D_VA_STATICCAST_,T,v)};return new iuValuesInParamsGenerator<T>(val);}II_D_VA_CONCAT_() private: IUTEST_PP_REPEAT_BINARY(n,II_D_VA_VARIABLE_,A,v) }
II_D_VA_(1);II_D_VA_(2);II_D_VA_(3);II_D_VA_(4);II_D_VA_(5);II_D_VA_(6);II_D_VA_(7);II_D_VA_(8);II_D_VA_(9);II_D_VA_(10);II_D_VA_(11);II_D_VA_(12);II_D_VA_(13);II_D_VA_(14);II_D_VA_(15);II_D_VA_(16);II_D_VA_(17);II_D_VA_(18);II_D_VA_(19);II_D_VA_(20);II_D_VA_(21);II_D_VA_(22);II_D_VA_(23);II_D_VA_(24);II_D_VA_(25);II_D_VA_(26);II_D_VA_(27);II_D_VA_(28);II_D_VA_(29);II_D_VA_(30);II_D_VA_(31);II_D_VA_(32);II_D_VA_(33);II_D_VA_(34);II_D_VA_(35);II_D_VA_(36);II_D_VA_(37);II_D_VA_(38);II_D_VA_(39);II_D_VA_(40);II_D_VA_(41);II_D_VA_(42);II_D_VA_(43);II_D_VA_(44);II_D_VA_(45);II_D_VA_(46);II_D_VA_(47);II_D_VA_(48);II_D_VA_(49);II_D_VA_(50);
#undef II_D_VA_CONSTRUCT_
#undef II_D_VA_STATICCAST_
#undef II_D_VA_VARIABLE_
#undef II_D_VA_CONCAT_
#undef II_D_VA_
#endif
#if IUTEST_HAS_COMBINE
#if IUTEST_HAS_VARIADIC_COMBINE
template<typename... Args>class iuCartesianProductGenerator:public iuIParamGenerator<tuples::tuple<Args...> >{typedef tuples::tuple<iuParamGenerator<Args>... > _MyTuple;static const int kCount=sizeof...(Args);struct begin_func{template<typename T>void operator()(int,T& value)const{value.Begin();}};template<int index,int end,typename Tuple>bool is_end_foreach(Tuple& t,typename detail::enable_if<index!=end,void>::type*& = detail::enabler::value)const{const bool b=tuples::get<index>(t).IsEnd();return b&&is_end_foreach<index+1,end>(t);}template<int index,int end,typename Tuple>bool is_end_foreach(Tuple&,typename detail::enable_if<index==end,void>::type*& = detail::enabler::value)const{return true;}template<int index,int end,typename Tuple>void next_foreach(Tuple& t,typename detail::enable_if<index!=end,void>::type*& = detail::enabler::value){next_foreach<index+1,end>(t);if(is_end_foreach<index+1,end>(t)){tuples::get<index>(t).Next();if(!tuples::get<index>(t).IsEnd()){tuples::tuple_foreach<index+1>(t,begin_func());}}}template<int index,int end,typename Tuple>void next_foreach(Tuple&,typename detail::enable_if<index==end,void>::type*& = detail::enabler::value){}template<int index,int end,typename T1,typename ...TArgs>tuples::tuple<T1,TArgs...> current_foreach(typename detail::enable_if<index!=end-1,void>::type*& = detail::enabler::value)const{return ::std::tuple_cat(tuples::tuple<T1>(tuples::get<index>(v).GetCurrent()),current_foreach<index+1,end,TArgs...>());}template<int index,int end,typename T1,typename ...TArgs>tuples::tuple<T1> current_foreach(typename detail::enable_if<index==end-1,void>::type*& = detail::enabler::value)const{return tuples::tuple<T1>(tuples::get<index>(v).GetCurrent());}public: typedef tuples::tuple<Args...> ParamType;public: iuCartesianProductGenerator(){}public: virtual void Begin() II_CXX_O{tuples::tuple_foreach(v,begin_func());}virtual void Next() II_CXX_O{if(!IsEnd()){next_foreach<0,kCount>(v);}}virtual bool IsEnd()const II_CXX_O{return is_end_foreach<0,kCount>(v);}virtual ParamType GetCurrent()const II_CXX_O{return current_foreach<0,kCount,Args...>();}_MyTuple& generators(){return v;}private: _MyTuple v;};template<typename... Generator>class iuCartesianProductHolder{typedef iuCartesianProductHolder<Generator...> _Myt;typedef tuples::tuple<const Generator...> _MyTuple;public: explicit iuCartesianProductHolder(const Generator&... generators):v(generators...){}public: template<typename... Args>operator iuIParamGenerator<tuples::tuple<Args...> >*()const{iuCartesianProductGenerator<Args...>* p=new iuCartesianProductGenerator<Args...>();tuples::tuple_cast_copy(p->generators(),v);return p;}public:template<typename Other>iuConcatParamHolder<_Myt,Other> operator+(const Other& g)const{return iuConcatParamHolder<_Myt,Other>(*this,g);}private: _Myt& operator=(const _Myt&) II_CXX_DL_F;private: _MyTuple v;};
#else
template<typename Generator1,typename Generator2,typename ParamType>class iuICartesianProductGeneratorBase:public iuIParamGenerator<ParamType >{public: iuICartesianProductGeneratorBase(const Generator1& g1,const Generator2& g2):m_g1(g1),m_g2(g2){}public: virtual void Begin() II_CXX_O{m_g1.Begin();m_g2.Begin();}virtual void Next() II_CXX_O{if(m_g2.IsEnd()){return;}m_g2.Next();if(m_g2.IsEnd()){m_g1.Next();if(!m_g1.IsEnd()){m_g2.Begin();}}}virtual bool IsEnd()const II_CXX_O{return m_g1.IsEnd()&&m_g2.IsEnd();}protected: Generator1 m_g1;Generator2 m_g2;};template<typename T1,typename T2>class iuCartesianProductGenerator2: public iuICartesianProductGeneratorBase<iuParamGenerator<T1>,iuParamGenerator<T2>,tuples::tuple<T1,T2> >{typedef iuICartesianProductGeneratorBase<iuParamGenerator<T1>,iuParamGenerator<T2>,tuples::tuple<T1,T2> > _Mybase;typedef iuParamGenerator<T1> Generator1;typedef iuParamGenerator<T2> Generator2;public: typedef tuples::tuple<T1,T2> ParamType;public: iuCartesianProductGenerator2(const Generator1 &g1,const Generator2 &g2):_Mybase(g1,g2){}public: virtual ParamType GetCurrent()const II_CXX_O{return ParamType(this->m_g1.GetCurrent(),this->m_g2.GetCurrent());}};
#define II_D_C_P_GEN_TYPEDEF_(i,p1,p2) typedef iuParamGenerator<IP_CAT(p1,i)> IP_CAT(p2,i);
#define II_D_C_P_GEN_TUPLEGET_(i,param) tuples::get<i>(param)
#define II_D_C_P_GEN_BASE_(n) iuICartesianProductGeneratorBase<iuParamGenerator<T0> ,IP_CAT(iuCartesianProductGenerator,IP_DEC(n))< IP_ENM_S_P(IP_DEC(n),T)> ,tuples::tuple<IP_ENM_P(n,T)> >
#define II_D_C_P_GEN_(n) template<IP_ENM_P(n,typename T)> class IP_CAT(iuCartesianProductGenerator,n) : public II_D_C_P_GEN_BASE_(n){typedef II_D_C_P_GEN_BASE_(n) _Mybase;IUTEST_PP_REPEAT_BINARY(n,II_D_C_P_GEN_TYPEDEF_,T,Generator) public: typedef tuples::tuple<IP_ENM_P(n,T)> ParamType;IP_CAT(iuCartesianProductGenerator,n)(IP_ENM_B_P(n,const Generator,&g)) : _Mybase(g0,IP_CAT(iuCartesianProductGenerator,IP_DEC(n))< IP_ENM_S_P(IP_DEC(n),T)> (IP_ENM_S_P(IP_DEC(n),g))){}virtual ParamType GetCurrent()const II_CXX_O{tuples::tuple<IP_ENM_S_P(IP_DEC(n),T)> params(this->m_g2.GetCurrent());return ParamType(this->m_g1.GetCurrent(),IP_ENM(IP_DEC(n) ,II_D_C_P_GEN_TUPLEGET_,params));}}
II_D_C_P_GEN_(3);II_D_C_P_GEN_(4);II_D_C_P_GEN_(5);II_D_C_P_GEN_(6);II_D_C_P_GEN_(7);II_D_C_P_GEN_(8);II_D_C_P_GEN_(9);
#undef II_D_C_P_GEN_TYPEDEF_
#undef II_D_C_P_GEN_TUPLEGET_
#undef II_D_C_P_GEN_BASE_
#undef II_D_C_P_GEN_
#define II_D_C_P_HLR_CONSTRUCT_(i,p1,p2) IP_CAT(p1,i)(IP_CAT(p2,i))
#define II_D_C_P_HLR_STATICCAST_(i,p1,p2) static_cast<iuIParamGenerator<IP_CAT(p1,i)>* >(IP_CAT(p2,i))
#define II_D_C_P_HLR_VARIABLE_(i,p1,p2) IP_CAT(p1,i) IP_CAT(p2,i);
#define II_D_C_P_HLR_CONCAT_() template<typename Other> iuConcatParamHolder<_Myt,Other> operator+(const Other& g)const{return iuConcatParamHolder<_Myt,Other>(*this,g);}
#define II_D_C_P_HLR_(n) template<IP_ENM_P(n,typename Generator)> class IP_CAT(iuCartesianProductHolder,n){typedef IP_CAT(iuCartesianProductHolder,n)<IP_ENM_P(n,Generator)> _Myt;public: IP_CAT(iuCartesianProductHolder,n)(IP_ENM_B_P(n,const Generator,&g)) : IP_ENM_B(n,II_D_C_P_HLR_CONSTRUCT_,m_g,g){}template<IP_ENM_P(n,typename T)> operator iuIParamGenerator<tuples::tuple<IP_ENM_P(n,T)> >*()const{return new IP_CAT(iuCartesianProductGenerator,n)<IP_ENM_P(n,T)>(IP_ENM_B(n,II_D_C_P_HLR_STATICCAST_,T,m_g));}II_D_C_P_HLR_CONCAT_() private: _Myt& operator=(const _Myt&);IUTEST_PP_REPEAT_BINARY(n,II_D_C_P_HLR_VARIABLE_,const Generator,m_g) }
II_D_C_P_HLR_(2);II_D_C_P_HLR_(3);II_D_C_P_HLR_(4);II_D_C_P_HLR_(5);II_D_C_P_HLR_(6);II_D_C_P_HLR_(7);II_D_C_P_HLR_(8);II_D_C_P_HLR_(9);
#undef II_D_C_P_HLR_CONSTRUCT_
#undef II_D_C_P_HLR_STATICCAST_
#undef II_D_C_P_HLR_VARIABLE_
#undef II_D_C_P_HLR_CONCAT_
#undef II_D_C_P_HLR_
#endif
#endif
#if IUTEST_HAS_PAIRWISE
class iuPairwiseGeneratorBase{protected: template<int N>struct ParamIndexes{int index[N];ParamIndexes(){for(int i=0;i<N;++i) index[i]=-1;}};private: struct PairInfo{PairInfo(int r1,int r2,int i1,int i2):raw1(r1),raw2(r2),idx1(i1),idx2(i2){}int raw1,raw2;int idx1,idx2;};protected: template<typename T1>static void MakeParamVector(::std::vector<T1>& list,iuParamGenerator<T1>& g1){for(g1.Begin();!g1.IsEnd();g1.Next()){list.push_back(g1.GetCurrent());}}template<typename T1,typename T2>static void MakePairList(::std::vector< ::std::pair<T1,T2> >& list,iuParamGenerator<T1>& g1,iuParamGenerator<T2>& g2){for(g1.Begin();!g1.IsEnd();g1.Next()){T1 t1=g1.GetCurrent();for(g2.Begin();!g2.IsEnd();g2.Next()){
#if IUTEST_HAS_STD_EMPLACE
list.emplace_back(t1,g2.GetCurrent());
#else
list.push_back(::std::pair<T1,T2>(t1,g2.GetCurrent()));
#endif
}}}template<int N>static void MakeIndexList(::std::vector<ParamIndexes<N> >& list,int* count_list){typedef typename ::std::vector<ParamIndexes<N> >::iterator list_iterator;list.clear();::std::vector<PairInfo> pair_list;for(int i=0;i<N;++i){int l=count_list[i];for(int j=i+1;j<N;++j){int r=count_list[j];for(int li=0;li<l;++li){for(int ri=0;ri<r;++ri){
#if IUTEST_HAS_STD_EMPLACE
pair_list.emplace_back(i,j,li,ri);
#else
PairInfo info(i,j,li,ri);pair_list.push_back(info);
#endif
}}}}iuRandom random;unsigned int seed=TestEnv::get_random_seed();if(seed!=0){random.init(seed);}random.shuffle(pair_list.begin(),pair_list.end());for(::std::vector<PairInfo>::const_iterator it=pair_list.begin();it!=pair_list.end();++it){const PairInfo& pair_info=*it;list_iterator find=Find(list,pair_info,list.begin());if(find==list.end()){find=FindFree(list,pair_info,list.begin());if(find==list.end()){ParamIndexes<N> params;params.index[pair_info.raw1]=pair_info.idx1;params.index[pair_info.raw2]=pair_info.idx2;list.push_back(params);}else{ParamIndexes<N>& params=*find;params.index[pair_info.raw1]=pair_info.idx1;params.index[pair_info.raw2]=pair_info.idx2;}}}}template<int N,typename Fn>static int GetParamIndex(const ParamIndexes<N>& indexes,int raw,int count,Fn& func){return indexes.index[raw]==-1?func(count):indexes.index[raw];}template<int N,typename T>static T GetParam(const ::std::vector<T>& params,const ParamIndexes<N>& indexes,int raw){iuTypedRandom<int> rnd(TestEnv::genrand()());const int index=GetParamIndex(indexes,raw,static_cast<int>(params.size()),rnd);return params[index];}private: template<int N>static typename ::std::vector<ParamIndexes<N> >::iterator Find(::std::vector<ParamIndexes<N> >& list,const PairInfo& pair_info,typename ::std::vector<ParamIndexes<N> >::iterator start){typedef typename ::std::vector<ParamIndexes<N> >::iterator iterator;for(iterator it=start,end=list.end();it!=end;++it){ParamIndexes<N>& indexes=*it;if(indexes.index[pair_info.raw1]==pair_info.idx1&& indexes.index[pair_info.raw2]==pair_info.idx2){return it;}}return list.end();}template<int N>static typename ::std::vector<ParamIndexes<N> >::iterator FindFree(::std::vector<ParamIndexes<N> >& list,const PairInfo& pair_info,typename ::std::vector<ParamIndexes<N> >::iterator start){typedef typename ::std::vector<ParamIndexes<N> >::iterator iterator;iterator find=list.end();UInt32 max_overlap=static_cast<UInt32>(-1);for(iterator it=start,end=list.end();it!=end;++it){ParamIndexes<N>& indexes=*it;int free_raw=-1;int free_idx=-1;if(indexes.index[pair_info.raw1]==-1&&indexes.index[pair_info.raw2]==pair_info.idx2){free_raw=pair_info.raw1;free_idx=pair_info.idx1;}if(indexes.index[pair_info.raw2]==-1&&indexes.index[pair_info.raw1]==pair_info.idx1){free_raw=pair_info.raw2;free_idx=pair_info.idx2;}if(free_raw!=-1){UInt32 overlap=0;for(int i=0;i<N;++i){if(indexes.index[i]==-1||i==free_raw){continue;}PairInfo tmp(i,free_raw,indexes.index[i],free_idx);iterator it2=Find(list,tmp,list.begin());while(it2!=end){++overlap;++it2;it2=Find(list,tmp,it2);}}if(overlap==0){return it;}if(find==list.end()||(overlap<max_overlap)){find=it;max_overlap=overlap;}}}if(find!=list.end()){return find;}typedef typename ::std::vector<ParamIndexes<N> >::iterator iterator;for(iterator it=start,end=list.end();it!=end;++it){ParamIndexes<N>& indexes=*it;if(indexes.index[pair_info.raw1]==-1&&indexes.index[pair_info.raw2]==-1){return it;}}return list.end();}};
#if IUTEST_HAS_VARIADIC_PAIRWISE
template<typename... Args>class iuPairwiseGenerator:public iuPairwiseGeneratorBase{typedef tuples::tuple<Args... > ParamType;typedef tuples::tuple<iuParamGenerator<Args>... > GeneratorTuple;static const int kRAW_COUNT=sizeof...(Args);typedef ParamIndexes<kRAW_COUNT> _MyParamIndexes;typedef ::std::vector<_MyParamIndexes>ParamIndexesList;typedef tuples::tuple< ::std::vector<Args>... > ParamsTuple;public: static iuIParamGenerator<ParamType >* Create(GeneratorTuple& generators){ParamIndexesList list;ParamVecotrs param_vectors(generators);MakeIndexList(list,param_vectors.count_list);::std::vector<ParamType> params;for(typename ParamIndexesList::const_iterator it=list.begin(),end=list.end();it!=end;++it){const _MyParamIndexes& indexes=*it;params.push_back(MakeParam<0,Args...>(param_vectors.params_list,indexes));}return new iuValuesInParamsGenerator<ParamType >(params);}private: template<int N,typename T1,typename... TArgs>static tuples::tuple<T1,TArgs...> MakeParam(ParamsTuple& list,const _MyParamIndexes& indexes,typename detail::disable_if<N==kRAW_COUNT -1,void>::type*& = detail::enabler::value){return ::std::tuple_cat(tuples::tuple<T1>(GetParam(tuples::get<N>(list),indexes,N)),MakeParam<N+1,TArgs...>(list,indexes));}template<int N,typename T1,typename... TArgs>static tuples::tuple<T1> MakeParam(ParamsTuple& list,const _MyParamIndexes& indexes,typename detail::enable_if<N==kRAW_COUNT -1,void>::type*& = detail::enabler::value){return tuples::tuple<T1>(GetParam(tuples::get<N>(list),indexes,N));}struct ParamVecotrs{ParamsTuple params_list;int count_list[kRAW_COUNT];template<int N>void MakeParamVecotrs(GeneratorTuple& generators,typename detail::disable_if<N==kRAW_COUNT -1,void>::type*& = detail::enabler::value){MakeParamVector(tuples::get<N>(params_list),tuples::get<N>(generators));count_list[N]=static_cast<int>(tuples::get<N>(params_list).size());MakeParamVecotrs<N+1>(generators);}template<int N>void MakeParamVecotrs(GeneratorTuple& generators,typename detail::enable_if<N==kRAW_COUNT -1,void>::type*& = detail::enabler::value){MakeParamVector(tuples::get<N>(params_list),tuples::get<N>(generators));count_list[N]=static_cast<int>(tuples::get<N>(params_list).size());}explicit ParamVecotrs(GeneratorTuple& generators){MakeParamVecotrs<0>(generators);}};};template<typename... Generator>class iuPairwiseHolder{typedef iuPairwiseHolder<Generator...> _Myt;typedef tuples::tuple<const Generator...> _MyTuple;public: explicit iuPairwiseHolder(const Generator&... generators):v(generators...){}public: template<typename... Args>operator iuIParamGenerator<tuples::tuple<Args...> >*()const{tuples::tuple<iuParamGenerator<Args>... > generators;tuples::tuple_cast_copy(generators,v);return iuPairwiseGenerator<Args...>::Create(generators);}public:template<typename Other>iuConcatParamHolder<_Myt,Other> operator+(const Other& g)const{return iuConcatParamHolder<_Myt,Other>(*this,g);}private: _Myt& operator=(const _Myt&) II_CXX_DL_F;private: _MyTuple v;};
#else
template<typename T1,typename T2>class iuPairwiseGenerator2:public iuIParamGenerator<tuples::tuple<T1,T2> >{typedef iuParamGenerator<T1> Generator1;typedef iuParamGenerator<T2> Generator2;public: typedef tuples::tuple<T1,T2> ParamType;public: iuPairwiseGenerator2(const Generator1& g1,const Generator2& g2):m_g1(g1),m_g2(g2){}static iuIParamGenerator<ParamType >* Create(const Generator1& g1,const Generator2& g2){return new iuPairwiseGenerator2<T1,T2>(g1,g2);}public: virtual void Begin() II_CXX_O{m_g1.Begin();m_g2.Begin();}virtual void Next() II_CXX_O{if(m_g2.IsEnd()){return;}m_g2.Next();if(m_g2.IsEnd()){m_g1.Next();if(!m_g1.IsEnd()){m_g2.Begin();}}}virtual bool IsEnd()const II_CXX_O{return m_g1.IsEnd()&&m_g2.IsEnd();}virtual ParamType GetCurrent()const II_CXX_O{return ParamType(this->m_g1.GetCurrent(),this->m_g2.GetCurrent());}private: Generator1 m_g1;Generator2 m_g2;};
#define II_D_PW_GEN_TEMPLATE_T_(i,p1,p2) p1<IP_CAT(T,i)> IP_CAT(p2,i);
#define II_D_PW_GEN_MAKEPARAM_VECTOR_(i,p1,p2) MakeParamVector(IP_CAT(p1,i),IP_CAT(p2,i));
#define II_D_PW_GEN_PARAM_SIZE_(i,param) static_cast<int>(IP_CAT(param,i).size())
#define II_D_PW_GEN_GETPARAM_(i,param) GetParam(IP_CAT(param,i),indexes,i)
#define II_D_PW_GEN_(n) template<IP_ENM_P(n,typename T)> class IP_CAT(iuPairwiseGenerator,n):public iuPairwiseGeneratorBase{IUTEST_PP_REPEAT_BINARY(n,II_D_PW_GEN_TEMPLATE_T_,typedef iuParamGenerator,Generator) typedef ParamIndexes<n> _MyParamIndexes;typedef ::std::vector<_MyParamIndexes>ParamIndexesList;public: typedef tuples::tuple<IP_ENM_P(n,T)> ParamType;static iuIParamGenerator<ParamType >* Create(IP_ENM_B_P(n,Generator,g)){ParamIndexesList list;IUTEST_PP_REPEAT_BINARY(n,II_D_PW_GEN_TEMPLATE_T_,::std::vector,params) IUTEST_PP_REPEAT_BINARY(n,II_D_PW_GEN_MAKEPARAM_VECTOR_,params,g) int count_list[]={IP_ENM(n,II_D_PW_GEN_PARAM_SIZE_,params)};MakeIndexList(list,count_list);::std::vector<ParamType> params;for(typename ParamIndexesList::const_iterator it=list.begin(),end=list.end();it!=end;++it){const _MyParamIndexes& indexes=*it;params.push_back(ParamType(IP_ENM(n,II_D_PW_GEN_GETPARAM_,params)));}return new iuValuesInParamsGenerator<ParamType >(params);}}
II_D_PW_GEN_(3);II_D_PW_GEN_(4);II_D_PW_GEN_(5);II_D_PW_GEN_(6);II_D_PW_GEN_(7);II_D_PW_GEN_(8);II_D_PW_GEN_(9);
#undef II_D_PW_GEN_TEMPLATE_T_
#undef II_D_PW_GEN_MAKEPARAM_VECTOR_
#undef II_D_PW_GEN_PARAM_SIZE_
#undef II_D_PW_GEN_GETPARAM_
#undef II_D_PW_GEN_
#define II_D_PW_HLR_CONSTRUCT_(i,p1,p2) IP_CAT(p1,i)(IP_CAT(p2,i))
#define II_D_PW_HLR_STATICCAST_(i,p1,p2) static_cast<iuIParamGenerator<IP_CAT(p1,i)>* >(IP_CAT(p2,i))
#define II_D_PW_HLR_VARIABLE_(i,p1,p2) IP_CAT(p1,i) IP_CAT(p2,i);
#define II_D_PW_HLR_CONCAT_() template<typename Other> iuConcatParamHolder<_Myt,Other> operator+(const Other& g)const{return iuConcatParamHolder<_Myt,Other>(*this,g);}
#define II_D_PW_HLR_(n) template<IP_ENM_P(n,typename Generator)> class IP_CAT(iuPairwiseHolder,n){typedef IP_CAT(iuPairwiseHolder,n)<IP_ENM_P(n,Generator)> _Myt;public: IP_CAT(iuPairwiseHolder,n)(IP_ENM_B_P(n,const Generator,&g)) : IP_ENM_B(n,II_D_PW_HLR_CONSTRUCT_,m_g,g){}template<IP_ENM_P(n,typename T)> operator iuIParamGenerator<tuples::tuple<IP_ENM_P(n,T)> >*()const{return IP_CAT(iuPairwiseGenerator,n)<IP_ENM_P(n,T)>::Create(IP_ENM_B(n,II_D_PW_HLR_STATICCAST_,T,m_g));}II_D_PW_HLR_CONCAT_() private: _Myt& operator=(const _Myt&);IUTEST_PP_REPEAT_BINARY(n,II_D_PW_HLR_VARIABLE_,const Generator,m_g) }
II_D_PW_HLR_(2);II_D_PW_HLR_(3);II_D_PW_HLR_(4);II_D_PW_HLR_(5);II_D_PW_HLR_(6);II_D_PW_HLR_(7);II_D_PW_HLR_(8);II_D_PW_HLR_(9);
#undef II_D_PW_HLR_CONSTRUCT_
#undef II_D_PW_HLR_STATICCAST_
#undef II_D_PW_HLR_VARIABLE_
#undef II_D_PW_HLR_CONCAT_
#undef II_D_PW_HLR_
#endif
#endif
template<typename StdGenerator>class iuValuesParamsGeneratorHolder{typedef iuValuesParamsGeneratorHolder<StdGenerator> _Myt;public: iuValuesParamsGeneratorHolder(size_t num,const StdGenerator& g):m_num(num),m_g(g){}public: template<typename T>operator iuIParamGenerator<T>*()const{::std::vector<T> params(m_num);::std::generate(params.begin(),params.end(),m_g);return new iuValuesInParamsGenerator<T>(params);}public:template<typename Other>iuConcatParamHolder<_Myt,Other> operator+(const Other& g)const{return iuConcatParamHolder<_Myt,Other>(*this,g);}private: size_t m_num;StdGenerator m_g;};template<typename T,typename F>class iuRandomFilterParamGenerator{typedef T type;public: iuRandomFilterParamGenerator(const F& fn,unsigned int seed):m_fn(fn),m_rnd(seed){}type operator()(){type val=m_rnd.genrand();for(;!(m_fn)(val);val=m_rnd.genrand()){}return val;}private: F m_fn;iuTypedRandom<type> m_rnd;};class iuRandomParamsHolder{public: explicit iuRandomParamsHolder(size_t num,unsigned int seed=0) II_CXX_NEX_S: m_num(num),m_seed(seed){}public: template<typename T>operator iuIParamGenerator<T>*()const{unsigned int seed=m_seed;if(seed==0){seed=GetIndefiniteValue();}iuValuesParamsGeneratorHolder<iuTypedRandom<T> > gen(m_num,iuTypedRandom<T>(seed));return gen;}public:template<typename Other>iuConcatParamHolder<iuRandomParamsHolder,Other> operator+(const Other& g)const{return iuConcatParamHolder<iuRandomParamsHolder,Other>(*this,g);}private: size_t m_num;unsigned int m_seed;};}}namespace iutest{namespace detail{template<typename T>class iuCsvFileParamsGenerator:public iuValuesInParamsGenerator<T>{typedef ::std::vector<T> params_t;public: explicit iuCsvFileParamsGenerator(const ::std::string& path,char delimiter=','):iuValuesInParamsGenerator<T>(ReadParams(path,delimiter)){}private: void AppendParams(params_t& params,const ::std::string& data){if(StringIsBlank(data)){return;}T param;if(!StringToValue(data,param)){return;}params.push_back(param);}params_t ReadParams(const ::std::string& path,char delimiter=','){params_t params;IFile* fp=detail::IFileSystem::New();if((fp!=0)&&fp->Open(path.c_str(),IFile::OpenRead)){const ::std::string dataset=fp->ReadAll();::std::string::size_type prev=0;::std::string::size_type pos=0;while(static_cast<void>(pos=dataset.find(delimiter,prev)),pos!=::std::string::npos){const ::std::string data=dataset.substr(prev,pos-prev);AppendParams(params,data);++pos;prev=pos;}AppendParams(params,dataset.substr(prev));if(params.empty()){IUTEST_LOG_(WARNING)<<"Empty params file \"" <<path<<"\".";}}else{IUTEST_LOG_(WARNING)<<"Unable to open file \"" <<path<<"\".";}detail::IFileSystem::Free(fp);return params;}};class iuIObject{public: virtual ~iuIObject(){}};class iuPool{typedef ::std::vector<iuIObject*> pool;pool m_pool;public: typedef iuIObject *value_ptr;public: ~iuPool(){for(pool::iterator it=m_pool.begin();it!=m_pool.end();){value_ptr p=*it;it=m_pool.erase(it);delete p;}}public: void push(value_ptr ptr){m_pool.push_back(ptr);}public: static iuPool& GetInstance(){static iuPool inst;return inst;}};}}namespace iutest{namespace detail{class IParamTestInfoData{public: class EachTestBase:public iuIObject{};template<typename T>class ParamEachTestBase:public EachTestBase{public: virtual void SetParam(const T& param)=0;};public: explicit IParamTestInfoData(const char* name):m_name(name){}virtual ~IParamTestInfoData() II_CXX_DF_F virtual TestCase* MakeTestCase(const ::std::string&,TestTypeId,SetUpMethod,TearDownMethod)const=0;virtual EachTestBase* RegisterTest(TestCase*,const ::std::string&)const=0;const char* GetName()const{return m_name.c_str();}protected: ::std::string m_name;};class IParamTestCaseInfo{public: virtual ~IParamTestCaseInfo(){}protected: IParamTestCaseInfo(const ::std::string& base_name,const ::std::string& package_name):m_t_c_base_name(base_name),m_package_name(package_name){}IParamTestCaseInfo(const char* base_name,const char* package_name):m_t_c_base_name(base_name),m_package_name(package_name){}public: void AddTestPattern(IParamTestInfoData* testinfo){m_testinfos.push_back(testinfo);}public: void RegisterTests()const{for(TestInfoContainer::const_iterator it=m_testinfos.begin(),end=m_testinfos.end();it!=end;++it){OnRegisterTests(*it);}}::std::string GetTestCaseBaseName()const{return m_t_c_base_name;}::std::string GetPackageName()const{return m_package_name;}public: bool is_same(const ::std::string& base_name,const ::std::string& package_name){return m_t_c_base_name==base_name&&m_package_name==package_name;}bool is_same(const char* base_name,const char* package_name){return m_t_c_base_name==base_name&&m_package_name==package_name;}private: virtual void OnRegisterTests(IParamTestInfoData*)const=0;private: typedef ::std::vector<IParamTestInfoData*> TestInfoContainer;TestInfoContainer m_testinfos;protected: ::std::string m_t_c_base_name;::std::string m_package_name;};template<class T>class ParamTestCaseInfo:public IParamTestCaseInfo{typedef T Tester;typedef typename Tester::ParamType ParamType;typedef detail::iuIParamGenerator<ParamType> ParamGenerator;typedef typename ParamGenerator::Generator Generator;typedef IParamTestInfoData::ParamEachTestBase<ParamType> EachTest;typedef ::std::vector<IParamTestInfoData*> TestInfoContainer;typedef ParamGenerator*(*pfnCreateGeneratorFunc)();typedef ::std::string(*pfnParamNameGeneratorFunc)(const TestParamInfo<ParamType>&);class Functor{public: Functor():CreateGen(0),ParamNameGen(0){}Functor(pfnCreateGeneratorFunc c,pfnParamNameGeneratorFunc p):CreateGen(c),ParamNameGen(p){}pfnCreateGeneratorFunc CreateGen;pfnParamNameGeneratorFunc ParamNameGen;};public: ParamTestCaseInfo(const ::std::string& t_c_name,const ::std::string& package_name):IParamTestCaseInfo(t_c_name,package_name){}ParamTestCaseInfo(const char* t_c_name,const char* package_name):IParamTestCaseInfo(t_c_name,package_name){}virtual ~ParamTestCaseInfo(){}int AddTestCaseInstantiation(::std::string name,pfnCreateGeneratorFunc create_func,pfnParamNameGeneratorFunc paramname_func){
#if IUTEST_HAS_STD_EMPLACE
m_instantiation.emplace_back(name,Functor(create_func,paramname_func));
#else
m_instantiation.push_back(InstantiationPair(name,Functor(create_func,paramname_func)));
#endif
return 0;}virtual void OnRegisterTests(IParamTestInfoData* infodata)const II_CXX_O{for(typename InstantiationContainer::const_iterator gen_it=m_instantiation.begin(),gen_end=m_instantiation.end();gen_it!=gen_end;++gen_it){detail::scoped_ptr<ParamGenerator> p((gen_it->second.CreateGen)());const ::std::string t_c_name=CreateTestCaseName(gen_it->first);TestCase* testcase=infodata->MakeTestCase(t_c_name,internal::GetTypeId<Tester>(),Tester::SetUpTestCase,Tester::TearDownTestCase);if(p.get()!=0){size_t i=0;for(p->Begin();!p->IsEnd();p->Next()){const ::std::string name=MakeParamTestName(infodata->GetName(),gen_it->second.ParamNameGen(TestParamInfo<ParamType>(p->GetCurrent(),i)));if(!CheckTestName(testcase,name)){IUTEST_LOG_(WARNING)<<t_c_name<<"." <<name<<" is already exist.";}EachTest* test=static_cast<EachTest*>(infodata->RegisterTest(testcase,name));test->SetParam(p->GetCurrent());++i;}}}}static ::std::string DefaultParamNameFunc(const TestParamInfo<ParamType>& info){return Tester::MakeTestParamName(info);}template<typename ParamNameFunctor>static ParamNameFunctor GetParamNameGen(ParamNameFunctor func){return func;}static pfnParamNameGeneratorFunc GetParamNameGen(){return DefaultParamNameFunc;}private: ::std::string CreateTestCaseName(const ::std::string& gen_name)const{::std::string t_c_name=m_package_name;if(!gen_name.empty()){t_c_name+=gen_name;t_c_name+="/";}t_c_name+=m_t_c_base_name;return t_c_name;}private: static bool CheckTestName(const TestCase* testcase,const::std::string& name){const int count=testcase->total_test_count();for(int i=0;i<count;++i){if(detail::IsStringEqual(name.c_str(),testcase->GetTestInfo(i)->name())){return false;}}return true;}private: typedef ::std::pair< ::std::string,Functor>InstantiationPair;typedef ::std::vector<InstantiationPair> InstantiationContainer;InstantiationContainer m_instantiation;};class ParamTestCaseHolder{private: ~ParamTestCaseHolder(){for(TestCaseInfoContainer::const_iterator it=m_t_c_infos.begin(),end=m_t_c_infos.end();it!=end;++it){delete *it;}}public: template<typename T>ParamTestCaseInfo<T>* GetTestCasePatternHolder(const ::std::string& testcase,const ::std::string& package II_A_E_TT(T)){ParamTestCaseInfo<T>* p=static_cast<ParamTestCaseInfo<T>*>(FindTestCasePatternHolder(testcase,package));if(p==0){p=new ParamTestCaseInfo<T>(testcase,package);m_t_c_infos.push_back(p);}return p;}private: template<typename T>IParamTestCaseInfo* FindTestCasePatternHolder(const T& testcase,const T& package){for(TestCaseInfoContainer::iterator it=m_t_c_infos.begin(),end=m_t_c_infos.end();it!=end;++it){if((*it)->is_same(testcase,package)){return(*it);}}return 0;}public: size_t count()const{return m_t_c_infos.size();}private: struct RegisterTestsFunctor{inline void operator()(const IParamTestCaseInfo* p)const{p->RegisterTests();}};void RegisterTests(){::std::for_each(m_t_c_infos.begin(),m_t_c_infos.end(),RegisterTestsFunctor());}private: friend class ::iutest::UnitTest;typedef ::std::vector<IParamTestCaseInfo*> TestCaseInfoContainer;TestCaseInfoContainer m_t_c_infos;};}}namespace iutest{class UnitTest:public UnitTestImpl{public: static UnitTest& instance(){static UnitTest inst;return inst;}static UnitTest* GetInstance(){return &instance();}public: const TestCase* current_test_case()const{return m_current_testcase;}const TestInfo* current_test_info()const{return Test::GetCurrentTestInfo();}unsigned int random_seed()const{return TestEnv::current_random_seed();}int repeat_counter()const II_CXX_NEX_S{return m_repeat_counter;}int repeat_count()const II_CXX_NEX_S{return TestEnv::get_repeat_count();}public: int total_test_count()const II_CXX_NEX_S{return m_total_test_num;}int reportable_test_count()const;int test_to_run_count()const II_CXX_NEX_S{return m_should_run_num;}int failed_test_count()const;int disabled_test_count()const II_CXX_NEX_S{return m_disable_num;}int reportable_disabled_test_count()const;int successful_test_count()const;int skip_test_count()const;int reportable_skip_test_count()const;int test_run_skipped_count()const;int reportable_test_run_skipped_count()const;int total_test_case_count()const{return static_cast<int>(m_testcases.size());}int test_case_to_run_count()const;int successful_test_case_count()const;int failed_test_case_count()const;const TestResult* ad_hoc_testresult()const II_CXX_NEX_S{return ad_hoc_test_result();}const TestResult* ad_hoc_test_result()const II_CXX_NEX_S{return &m_ad_hoc_testresult;}TimeInMillisec elapsed_time()const II_CXX_NEX_S{return m_elapsedmsec;}TimeInMillisec start_timestamp()const II_CXX_NEX_S{return m_start_timestamp;}const TestCase* GetTestCase(int index)const{return m_testcases[index];}bool Passed()const;bool Failed()const{return !Passed();}TestEventListeners& listeners()const{return TestEnv::event_listeners();}protected: int Run();private:int RunImpl();bool RunOnce();private: void TestProgramStart();void SetUpTestIteration();void EnvironmentSetUp();void EnvironmentTearDown();void TestProgramEnd();private: static void OnExit(){instance().TestProgramEnd();}private: UnitTest():m_repeat_counter(0),m_init_iutest_count(0),m_test_started(false),m_start_timestamp(0){TestEnv::SetGlobalTestPartResultReporter(&m_default_test_part_result_reporter);TestEnv::LoadEnvironmentVariable();}~UnitTest(){TestEnv::ReleaseGlobalTestEnvironment();TestEnv::SetGlobalTestPartResultReporter(0);}private: void Initialize();public: detail::ParamTestCaseHolder& parameterized_test_registry() II_CXX_NEX_S{return m_param_t_c_holder;}private: detail::ParamTestCaseHolder m_param_t_c_holder;private: friend class UnitTestSource;int m_repeat_counter;int m_init_iutest_count;bool m_test_started;TimeInMillisec m_start_timestamp;detail::DefaultGlobalTestPartResultReporter m_default_test_part_result_reporter;IP_DIS_C_A_A(UnitTest);};namespace detail{template<class Tester>class TestInstance{public: TestInstance(const char* testcase,const char* name,TestTypeId id,SetUpMethod setup,TearDownMethod teardown):m_mediator(AddTestCase(testcase,id,setup,teardown)),m_info(&m_mediator,name,&m_factory){UnitTest::instance().AddTestInfo(m_mediator.ptr(),&m_info);}TestInstance(const ::std::string& testcase,const char* name,TestTypeId id,SetUpMethod setup,TearDownMethod teardown):m_mediator(AddTestCase(testcase,id,setup,teardown)),m_info(&m_mediator,name,&m_factory){UnitTest::instance().AddTestInfo(m_mediator.ptr(),&m_info);}TestInstance(const char* testcase,const char* name,const char* value_params,TestTypeId id,SetUpMethod setup,TearDownMethod teardown):m_mediator(AddTestCase(testcase,id,setup,teardown)),m_info(&m_mediator,name,&m_factory){m_info.set_value_param(value_params);UnitTest::instance().AddTestInfo(m_mediator.ptr(),&m_info);}TestInstance(const ::std::string& testcase,const char* name,const char* value_params,TestTypeId id,SetUpMethod setup,TearDownMethod teardown):m_mediator(AddTestCase(testcase,id,setup,teardown)),m_info(&m_mediator,name,&m_factory){m_info.set_value_param(value_params);UnitTest::instance().AddTestInfo(m_mediator.ptr(),&m_info);}private: TestCase* AddTestCase(const char* testcase,TestTypeId id,SetUpMethod setup,TearDownMethod teardown){return UnitTest::instance().AddTestCase<TestCase>(testcase,id,setup,teardown);}TestCase* AddTestCase(const ::std::string& testcase,TestTypeId id,SetUpMethod setup,TearDownMethod teardown){return UnitTest::instance().AddTestCase<TestCase>(testcase,id,setup,teardown);}private: TestCaseMediator m_mediator;TestInfo m_info;iuFactory<Tester> m_factory;};}}namespace iutest{inline int UnitTest::reportable_test_count()const{return detail::SumOverList(m_testcases,&TestCase::reportable_test_count);}inline int UnitTest::failed_test_count()const{return detail::SumOverList(m_testcases,&TestCase::failed_test_count);}inline int UnitTest::reportable_disabled_test_count()const{return detail::SumOverList(m_testcases,&TestCase::reportable_disabled_test_count);}inline int UnitTest::successful_test_count()const{return detail::SumOverList(m_testcases,&TestCase::successful_test_count);}inline int UnitTest::skip_test_count()const{return detail::SumOverList(m_testcases,&TestCase::skip_test_count);}inline int UnitTest::reportable_skip_test_count()const{return detail::SumOverList(m_testcases,&TestCase::reportable_skip_test_count);}inline int UnitTest::test_run_skipped_count()const{return detail::SumOverList(m_testcases,&TestCase::test_run_skipped_count);}inline int UnitTest::reportable_test_run_skipped_count()const{return detail::SumOverList(m_testcases,&TestCase::reportable_test_run_skipped_count);}inline int UnitTest::test_case_to_run_count()const{return detail::CountIfOverList(m_testcases,&TestCase::should_run);}inline int UnitTest::successful_test_case_count()const{return detail::CountIfOverList(m_testcases,&TestCase::Passed);}inline int UnitTest::failed_test_case_count()const{return detail::CountIfOverList(m_testcases,&TestCase::Failed);}inline bool UnitTest::Passed()const{if(m_ad_hoc_testresult.Failed()){return false;}for(iuTestCases::const_iterator it=m_testcases.begin(),end=m_testcases.end();it!=end;++it){if((*it)->Failed()){return false;}}return true;}inline int UnitTest::Run(){if(m_init_iutest_count==0){{detail::iuConsole::output("This test program did NOT call ::iutest::InitIrisUnitTest before calling IUTEST_RUN_ALL_TESTS().  Please fix it.\n");return 1;}}if(!PreRunner()){return Passed()?0:1;}
#if IUTEST_HAS_EXCEPTIONS
if(TestFlag::IsEnableFlag(TestFlag::CATCH_EXCEPTION_GLOBAL)){int ret=1;try{ret=RunImpl();}catch(...){}return ret;}
#endif
return RunImpl();}inline int UnitTest::RunImpl(){m_repeat_counter=0;int repeat=TestEnv::get_repeat_count();bool result=true;if(repeat!=0){m_start_timestamp=detail::GetTimeInMillis();TestProgramStart();while(repeat){SetUpTestIteration();listeners().OnTestIterationStart(*this,m_repeat_counter);if(!RunOnce()){result=false;}listeners().OnTestIterationEnd(*this,m_repeat_counter);++m_repeat_counter;if(repeat>0){--repeat;}}TestProgramEnd();}if(!result){return 1;}if(detail::IUTestLog::HasError()){return 1;}if(IUTEST_FLAG(warning_into_error)){if(detail::IUTestLog::HasWarning()){return 1;}}return 0;}inline bool UnitTest::RunOnce(){m_elapsedmsec=0;ClearNonAdHocTestResult();if(test_to_run_count()==0){return Passed();}if(TestFlag::IsEnableFlag(TestFlag::SHUFFLE_TESTS)){detail::RandomShuffle(m_testcases,TestEnv::genrand());}EnvironmentSetUp();if(m_ad_hoc_testresult.HasFatalFailure()){return false;}{detail::iuStopWatch sw;sw.start();for(iuTestCases::iterator it=m_testcases.begin(),end=m_testcases.end();it!=end;++it){m_current_testcase=*it;m_current_testcase->Run();m_current_testcase=0;}m_elapsedmsec=sw.stop();}EnvironmentTearDown();return Passed();}inline void UnitTest::TestProgramStart(){m_should_run_num=0;m_disable_num=0;for(iuTestCases::iterator it=m_testcases.begin(),end=m_testcases.end();it!=end;++it){TestCase* testcase=*it;testcase->filter();m_should_run_num+=testcase->test_to_run_count();m_disable_num+=testcase->disabled_test_count();}atexit(OnExit);
#if IUTEST_HAS_STD_QUICK_EXIT
::std::at_quick_exit(OnExit);
#endif
m_test_started=true;listeners().OnTestProgramStart(*this);}inline void UnitTest::SetUpTestIteration(){TestEnv::SetUp();}inline void UnitTest::EnvironmentSetUp(){listeners().OnEnvironmentsSetUpStart(*this);for(iuEnvironmentList::iterator it=TestEnv::environments().begin(),end=TestEnv::environments().end();it!=end;++it){(*it)->SetUp();}listeners().OnEnvironmentsSetUpEnd(*this);}inline void UnitTest::EnvironmentTearDown(){listeners().OnEnvironmentsTearDownStart(*this);for(iuEnvironmentList::reverse_iterator it=TestEnv::environments().rbegin(),end=TestEnv::environments().rend();it!=end;++it){(*it)->TearDown();}listeners().OnEnvironmentsTearDownEnd(*this);}inline void UnitTest::TestProgramEnd(){if(!m_test_started){return;}if(current_test_info()!=0){II_E_FAIL("program exit.");}listeners().OnTestProgramEnd(*this);m_test_started=false;}inline void UnitTest::Initialize(){m_init_iutest_count++;ClearAdHocTestResult();if(detail::IFileSystem::GetInstance()==0){
#ifdef IUTEST_FILE
static FileSystem<IUTEST_FILE> filesystem;filesystem.Initialize();
#elif 1
static FileSystem<StdioFile> filesystem;filesystem.Initialize();
#endif
}if(m_init_iutest_count!=1){return;}m_param_t_c_holder.RegisterTests();}}namespace iutest{class any{typedef internal::TypeId type_id;public: any():content(0){}template<typename T>any(const T& rhs):content(new holder<T>(rhs)){}any(const any& rhs):content(rhs.content==0?0:rhs.content->clone()){}any(const char rhs[]):content(new holder< ::std::string >(::std::string(rhs))){}~any(){delete content;}public: any& swap(any& rhs){::std::swap(content,rhs.content);return *this;}bool empty()const{return content==0;}void clear(){any().swap(*this);}type_id type()const{return content==0?internal::GetTypeId<void>():content->type();}template<typename T>bool type_equal()const{return type()==internal::GetTypeId<T>();}::std::string to_string()const{if(empty()){return "empty";}return content->to_string();}public: bool has_value()const{return !empty();}void reset(){clear();}public: template<typename T>any& operator=(const T& rhs){any(rhs).swap(*this);return *this;}any& operator=(const any& rhs){any(rhs).swap(*this);return *this;}template<typename T>friend T* any_cast(any*);template<typename T>friend T* unsafe_any_cast(any*);private: class placeholder{public: virtual ~placeholder(){}virtual type_id type()const=0;virtual placeholder* clone()const=0;virtual ::std::string to_string()const=0;};template<typename T>class holder:public placeholder{public: explicit holder(const T& v):held(v){}public: virtual type_id type()const II_CXX_O{return internal::GetTypeId<T>();}virtual placeholder* clone()const II_CXX_O{return new holder<T>(held);}virtual ::std::string to_string()const II_CXX_O{return PrintToString(held);}public: T held;private: holder& operator=(const holder&);};private: placeholder* content;};
#if IUTEST_HAS_EXCEPTIONS
class bad_any_cast:public ::std::bad_cast{};
#endif
inline void swap(any& lhs,any& rhs){lhs.swap(rhs);}template<typename T>T* any_cast(any* p){return p!=0&&p->type_equal<T>() ?&(static_cast<any::holder<T>* >(p->content)->held):0;}template<typename T>inline const T* any_cast(const any* p){return any_cast<T>(const_cast<any*>(p));}template<typename T>inline T any_cast(any& value){typedef typename type_traits::remove_reference<T>::type nonref_t;nonref_t* p=any_cast<nonref_t>(&value);
#if IUTEST_HAS_EXCEPTIONS
if(p==0){throw bad_any_cast();}
#endif
return static_cast<nonref_t&>(*p);}template<typename T>inline T any_cast(const any& value){return any_cast<T>(const_cast<any&>(value));}template<typename T>T* unsafe_any_cast(any* p){if(p==0){return 0;}if(!p->has_value()){return 0;}return &(static_cast<any::holder<T>* >(p->content)->held);}template<typename T>inline const T* unsafe_any_cast(const any* p){return unsafe_any_cast<T>(const_cast<any*>(p));}template<typename T>inline T unsafe_any_cast(any& value){typedef typename type_traits::remove_reference<T>::type nonref_t;nonref_t* p=unsafe_any_cast<nonref_t>(&value);return static_cast<nonref_t&>(*p);}template<typename T>inline T unsafe_any_cast(const any& value){return unsafe_any_cast<T>(const_cast<any&>(value));}template<typename Elem,typename Traits>inline ::std::basic_ostream<Elem,Traits>& operator<<(::std::basic_ostream<Elem,Traits>& os,const any& value){return os<<value.to_string();}}
#define IUTEST_INSTANTIATE_TEST_CASE_P(pfx_,tf_,gen_,...) II_INST_TC_P_(pfx_,tf_,gen_,__VA_ARGS__)
#define IUTEST_P(tf_,tn_) IUTEST_TEST_P_(tf_,tn_)
#define IUTEST_INSTANTIATE_TEST_CASE_AP(pfx_,t_c_,gen_) II_INST_TC_AP_(pfx_,t_c_,gen_)
#define IUTEST_AP(t_c_,tn_) IUTEST_TEST_AP_(t_c_,tn_)
#define II_GTCPH(T,t_c_,package_) ::iutest::UnitTest::GetInstance()->parameterized_test_registry().GetTestCasePatternHolder<T>(t_c_,package_)
#define II_T_P_FX_D_(t_c_)
#define II_T_P_B_FX(t_c_) ::iutest::detail::paramtest_select_base_testcase<void(int(II_TO_VN_(t_c_)))>::type
#define II_INST_TC_P_(pfx_,t_c_,gen_,...) II_INST_TC_P_I(pfx_,t_c_,gen_,GetParamNameGen(__VA_ARGS__))
#define II_INST_TC_P_I(pfx_,t_c_,gen_,pn_gen_) II_INST_TC_P_II(pfx_,IUTEST_PP_IF(IP_IS_B_PAR(t_c_) ,II_ALS_TN_F_,IP_EMPTY()) t_c_,gen_,pn_gen_)
#define II_INST_TC_P_II(pfx_,t_c_,gen_,pn_gen_) II_INST_TC_P_III(pfx_,t_c_,II_T_P_B_FX(t_c_) ,gen_,pn_gen_)
#define II_INST_TC_P_III(pfx_,t_c_,basefixture_,gen_,pn_gen_) II_T_P_FX_D_(t_c_) static ::iutest::detail::iuIParamGenerator<basefixture_::ParamType >* II_T_P_EGEN_N_(pfx_,t_c_)(){return gen_;}static ::std::string II_T_P_PGEN_N_(pfx_,t_c_)(const ::iutest::TestParamInfo<basefixture_::ParamType>&info){return ::iutest::detail::ParamTestCaseInfo<basefixture_ >::pn_gen_(info);}int II_T_P_INST_R_N_(pfx_,t_c_)(){::iutest::detail::ParamTestCaseInfo<basefixture_ >* p=II_GTCPH(basefixture_,II_TO_N_STR_(t_c_),II_GET_PKGN_());return p->AddTestCaseInstantiation(#pfx_ ,II_T_P_EGEN_N_(pfx_,t_c_) ,II_T_P_PGEN_N_(pfx_,t_c_));}II_T_P_INST_R_(pfx_,t_c_)
#define II_TEST_P_I_(classname_,t_c_,tcn_,tn_) II_T_P_FX_D_(t_c_) class classname_:public t_c_{public: classname_(){}protected: virtual void Body() II_CXX_O;private: static int AddRegister(){static ::iutest::detail::ParamTestInstance<classname_>testinfo(tn_);II_GTCPH(t_c_,tcn_ ,II_GET_PKGN_())->AddTestPattern(&testinfo);return 0;}static int dmy_;IP_DIS_C_A_A(classname_);};int classname_::dmy_ II_ATR_U=classname_::AddRegister();void classname_::Body()
#define II_TEST_P_(mcr,t_c_,tn_) mcr(II_T_CLS_N_(t_c_,tn_) ,II_T_P_B_FX(t_c_) ,II_TO_N_STR_(t_c_),II_TO_N_STR_(tn_))
#define II_TEST_P_A_(mcr,t_c_,tn_) II_TEST_P_(mcr,IUTEST_PP_IF(IP_IS_B_PAR(t_c_) ,II_ALS_TN_F_,IP_EMPTY()) t_c_,tn_)
#define IUTEST_TEST_P_(t_c_,tn_) II_TEST_P_A_(II_TEST_P_I_,t_c_,tn_)
#define II_T_AP_FIX_N_(t_c_) IP_CAT(iuTestWithAny,t_c_)
#define II_ALS_TN_AP_(t_c_) II_ALS_TN_F(t_c_,II_T_AP_FIX_N_(t_c_))
#define IUTEST_TEST_AP_(t_c_,tn_) typedef ::iutest::TestWithAny II_T_AP_FIX_N_(t_c_);IUTEST_TEST_P_(II_ALS_TN_AP_(t_c_),tn_)
#define II_INST_TC_AP_(pfx_,t_c_,gen_) II_INST_TC_P_(pfx_,II_ALS_TN_AP_(t_c_),gen_)
#define II_T_P_EGEN_N_(pfx_,t_c_) II_T_P_EGEN_N_I(pfx_,II_TO_VN_(t_c_))
#define II_T_P_EGEN_N_I(pfx_,t_c_) II_T_P_EGEN_N_I_(pfx_,t_c_)
#define II_T_P_EGEN_N_I_(pfx_,t_c_) s_##pfx_##_x_iutest_x_##t_c_##_EvalGenerator_
#define II_T_P_PGEN_N_(pfx_,t_c_) II_T_P_PGEN_N_I(pfx_,II_TO_VN_(t_c_))
#define II_T_P_PGEN_N_I(pfx_,t_c_) II_T_P_PGEN_N_I_(pfx_,t_c_)
#define II_T_P_PGEN_N_I_(pfx_,t_c_) s_##pfx_##_x_iutest_x_##t_c_##_ParamGenerator_
#define II_T_P_INST_R_N_(pfx_,t_c_) II_T_P_INST_R_N_I(pfx_,II_TO_VN_(t_c_))
#define II_T_P_INST_R_N_I(pfx_,t_c_) II_T_P_INST_R_N_I_(pfx_,t_c_)
#define II_T_P_INST_R_N_I_(pfx_,t_c_) pfx_##_x_iutest_x_##t_c_##_TestCaseInstantiationRegister
#define II_T_P_INST_R_(pfx_,t_c_) II_T_P_INST_R_I(pfx_,II_TO_VN_(t_c_),II_T_P_INST_R_N_(pfx_,t_c_))
#define II_T_P_INST_R_I(pfx_,t_c_,register_) II_T_P_INST_R_I_(pfx_,t_c_,register_)
#define II_T_P_INST_R_I_(pfx_,t_c_,register_) int s_##pfx_##_x_iutest_x_##t_c_##_dmy=register_()
namespace iutest{namespace detail{template<typename T>class ParamTestInstance:public IParamTestInfoData{typedef T Tester;typedef typename Tester::ParamType ParamType;typedef detail::iuParamTestFactory<T> Factory;class EachTest II_CXX_F:public IParamTestInfoData::ParamEachTestBase<ParamType>{public: EachTest(TestCase* testcase,const ::std::string& name):m_mediator(testcase),m_info(&m_mediator,name,&m_factory){UnitTest::instance().AddTestInfo(testcase,&m_info);}private: virtual void SetParam(const ParamType& param) II_CXX_O{m_factory.SetParam(param);m_info.set_value_param(PrintToString(param).c_str());}private: TestCaseMediator m_mediator;Factory m_factory;TestInfo m_info;};public: explicit ParamTestInstance(const char* t_c_name):IParamTestInfoData(t_c_name){}private: virtual TestCase* MakeTestCase(const ::std::string& t_c_name,TestTypeId id,SetUpMethod setup,TearDownMethod teardown)const II_CXX_O{return UnitTest::instance().AddTestCase<TestCase>(t_c_name,id,setup,teardown);}virtual IParamTestInfoData::EachTestBase* RegisterTest(TestCase* testcase,const ::std::string& name)const II_CXX_O{EachTest* test=new EachTest(testcase,name);detail::iuPool::GetInstance().push(test);return test;}};}class TestWithAny:public Test,public WithParamInterface<any>{public: static const ParamType& GetParam(){return WithParamInterface<any>::GetParam();}template<typename T>static T GetParam(){return unsafe_any_cast<T>(WithParamInterface<any>::GetParam());}};namespace detail{template<typename T>struct paramtest_select_base_testcase;template<>struct paramtest_select_base_testcase<void(int)>{typedef TestWithAny type;};template<typename T>struct paramtest_select_base_testcase<void(int(T))>{typedef T type;};}template<typename T>detail::iuParamGenerator<T> II_ATR_U Range(T begin,T end,T step=static_cast<T>(1)){return new detail::iuRangeParamsGenerator<T>(begin,end,step);}inline detail::iuParamGenerator<bool> II_ATR_U Bool(){return new detail::iuBoolParamsGenerator();}template<typename StdGenerator>inline detail::iuValuesParamsGeneratorHolder<StdGenerator> II_ATR_U ValuesGen(size_t num,const StdGenerator& generator){return detail::iuValuesParamsGeneratorHolder<StdGenerator>(num,generator);}template<typename T,typename Filter>inline detail::iuRandomFilterParamGenerator<T,Filter> II_ATR_U RandomGenerator(const Filter& filter,unsigned int seed=0){if(seed==0){seed=detail::GetIndefiniteValue();}return detail::iuRandomFilterParamGenerator<T,Filter>(filter,seed);}inline detail::iuRandomParamsHolder II_ATR_U RandomValues(size_t num,unsigned int seed=0){return detail::iuRandomParamsHolder(num,seed);}template<typename Container>inline detail::iuParamGenerator<typename Container::value_type>II_ATR_U ValuesIn(Container container){return new detail::iuValuesInParamsGenerator<typename Container::value_type >(container);}template<typename T,size_t SIZE>inline detail::iuParamGenerator<T> II_ATR_U ValuesIn(const T(&v)[SIZE]){return new detail::iuValuesInParamsGenerator<T>(v,v+SIZE);}template<typename Ite>inline detail::iuParamGenerator<typename detail::IteratorTraits<Ite>::type>II_ATR_U ValuesIn(Ite begin,Ite end){return new detail::iuValuesInParamsGenerator<typename detail::IteratorTraits<Ite>::type >(begin,end);}
#if IUTEST_HAS_INITIALIZER_LIST
template<typename T>inline detail::iuParamGenerator<T> II_ATR_U ValuesIn(::std::initializer_list<T> l){return new detail::iuValuesInParamsGenerator<T>(l);}
#endif
#if IUTEST_HAS_VARIADIC_VALUES
template<typename ...Args>inline detail::iuValueArray<Args...> II_ATR_U Values(Args... args){return detail::iuValueArray<Args...>(args...);}
#else
#define II_D_V_(n) template<IP_ENM_P(n,typename T)> inline detail::iuValueArray##n<IP_ENM_P(n,T)> II_ATR_U Values(IP_ENM_B_P(n,T,t)){return detail::iuValueArray##n<IP_ENM_P(n,T)>(IP_ENM_P(n,t));}
II_D_V_(1)II_D_V_(2)II_D_V_(3)II_D_V_(4)II_D_V_(5)II_D_V_(6)II_D_V_(7)II_D_V_(8)II_D_V_(9)II_D_V_(10)II_D_V_(11)II_D_V_(12)II_D_V_(13)II_D_V_(14)II_D_V_(15)II_D_V_(16)II_D_V_(17)II_D_V_(18)II_D_V_(19)II_D_V_(20)II_D_V_(21)II_D_V_(22)II_D_V_(23)II_D_V_(24)II_D_V_(25)II_D_V_(26)II_D_V_(27)II_D_V_(28)II_D_V_(29)II_D_V_(30)II_D_V_(31)II_D_V_(32)II_D_V_(33)II_D_V_(34)II_D_V_(35)II_D_V_(36)II_D_V_(37)II_D_V_(38)II_D_V_(39)II_D_V_(40)II_D_V_(41)II_D_V_(42)II_D_V_(43)II_D_V_(44)II_D_V_(45)II_D_V_(46)II_D_V_(47)II_D_V_(48)II_D_V_(49)II_D_V_(50)
#undef II_D_V_
#endif
template<typename Generator1,typename Generator2>detail::iuConcatParamHolder<Generator1,Generator2> Concat(const Generator1& g1,const Generator2& g2){return detail::iuConcatParamHolder<Generator1,Generator2>(g1,g2);}
#if IUTEST_HAS_COMBINE
#if IUTEST_HAS_VARIADIC_COMBINE
template<typename ...Generator>detail::iuCartesianProductHolder<Generator...> Combine(const Generator&... generators){return detail::iuCartesianProductHolder<Generator...>(generators...);}
#else
#define II_D_C_(n) template<IP_ENM_P(n,typename T)> inline IP_CAT(detail::iuCartesianProductHolder,n)<IP_ENM_P(n,T)> Combine(IP_ENM_B_P(n,const T,&t)){return IP_CAT(detail::iuCartesianProductHolder,n) <IP_ENM_P(n,T)>(IP_ENM_P(n,t));}
II_D_C_(2)II_D_C_(3)II_D_C_(4)II_D_C_(5)II_D_C_(6)II_D_C_(7)II_D_C_(8)II_D_C_(9)
#undef II_D_C_
#endif
#endif
#if IUTEST_HAS_PAIRWISE
#if IUTEST_HAS_VARIADIC_PAIRWISE
template<typename ...Generator>detail::iuPairwiseHolder<Generator...> Pairwise(const Generator&... generators){return detail::iuPairwiseHolder<Generator...>(generators...);}
#else
#define II_D_PW_(n) template<IP_ENM_P(n,typename T)> inline IP_CAT(detail::iuPairwiseHolder,n)<IP_ENM_P(n,T)> Pairwise(IP_ENM_B_P(n,const T,&t)){return IP_CAT(detail::iuPairwiseHolder,n) <IP_ENM_P(n,T)>(IP_ENM_P(n,t));}
II_D_PW_(2)II_D_PW_(3)II_D_PW_(4)II_D_PW_(5)II_D_PW_(6)II_D_PW_(7)II_D_PW_(8)II_D_PW_(9)
#undef II_D_PW__
#endif
#endif
template<typename T>detail::iuParamGenerator<T> II_ATR_U CSV(const char* path,char delimiter=','){return new detail::iuCsvFileParamsGenerator<T>(path,delimiter);}template<typename T>detail::iuParamGenerator<T> II_ATR_U CSV(const char* relative_path,const char* test_file,char delimiter=','){const char* sep=detail::FindLastPathSeparator(test_file,strlen(test_file));::std::string path;if(sep!=0){const size_t length=::std::distance(test_file,sep);path+=::std::string(test_file,length);path+=detail::GetPathSeparator();}path+=relative_path;return new detail::iuCsvFileParamsGenerator<T>(path,delimiter);}}typedef ::iutest::TestWithAny iuTestWithAny;namespace iutest{namespace detail{template<typename TypeList,size_t N>class typelist_get{template<typename T,size_t I>struct impl{typedef typename impl<typename T::Tail,I-1>::type type;};template<typename T>struct impl<T,0>{typedef typename T::Head type;};public: typedef typename impl<TypeList,N>::type type;};struct TypeList0{};template<typename T1>struct TypeList1{typedef T1 Head;typedef TypeList0 Tail;};
#if IUTEST_HAS_VARIADIC_TEMPLATES
template<typename T,typename ...Args>struct VariadicTypeList{typedef T Head;typedef VariadicTypeList<Args...> Tail;};template<typename T>struct VariadicTypeList<T>{typedef T Head;typedef TypeList0 Tail;};
#else
#define II_D_TL_(n) II_D_TL_I(n,IP_DEC(n))
#define II_D_TL_I(n,m) template<typename T0,IP_ENM_S_P(m,typename T)> struct IP_CAT(TypeList,n){typedef T0 Head;typedef IP_CAT(TypeList,m)<IP_ENM_S_P(m,T)> Tail;}
II_D_TL_(2);II_D_TL_(3);II_D_TL_(4);II_D_TL_(5);II_D_TL_(6);II_D_TL_(7);II_D_TL_(8);II_D_TL_(9);II_D_TL_(10);II_D_TL_(11);II_D_TL_(12);II_D_TL_(13);II_D_TL_(14);II_D_TL_(15);II_D_TL_(16);II_D_TL_(17);II_D_TL_(18);II_D_TL_(19);II_D_TL_(20);II_D_TL_(21);II_D_TL_(22);II_D_TL_(23);II_D_TL_(24);II_D_TL_(25);II_D_TL_(26);II_D_TL_(27);II_D_TL_(28);II_D_TL_(29);II_D_TL_(30);II_D_TL_(31);II_D_TL_(32);II_D_TL_(33);II_D_TL_(34);II_D_TL_(35);II_D_TL_(36);II_D_TL_(37);II_D_TL_(38);II_D_TL_(39);II_D_TL_(40);II_D_TL_(41);II_D_TL_(42);II_D_TL_(43);II_D_TL_(44);II_D_TL_(45);II_D_TL_(46);II_D_TL_(47);II_D_TL_(48);II_D_TL_(49);II_D_TL_(50);
#undef II_D_TL_
#endif
#define II_TEMPLATE_TPARAM1 template<typename XXX> class
template<II_TEMPLATE_TPARAM1 U>struct TemplateTypeSel{template<typename T>struct bind{typedef U<T> type;};};struct TemplateTypeList0{};
#if IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES
template<II_TEMPLATE_TPARAM1 T1,II_TEMPLATE_TPARAM1 ...Types>struct VariadicTemplateTypeList{typedef TemplateTypeSel<T1> Head;typedef VariadicTemplateTypeList<Types...> Tail;};template<II_TEMPLATE_TPARAM1 T1>struct VariadicTemplateTypeList<T1>{typedef TemplateTypeSel<T1> Head;typedef TemplateTypeList0 Tail;};
#else
template<II_TEMPLATE_TPARAM1 T1>struct TemplateTypeList1{typedef TemplateTypeSel<T1> Head;typedef TemplateTypeList0 Tail;};
#define II_D_TTL_(n) II_D_TTL_I(n,IP_DEC(n))
#define II_D_TTL_I(n,m) template<II_TEMPLATE_TPARAM1 T0,IP_ENM_S_P(m,II_TEMPLATE_TPARAM1 T)> struct IP_CAT(TemplateTypeList,n){typedef TemplateTypeSel<T0> Head;typedef IP_CAT(TemplateTypeList,m)<IP_ENM_S_P(m,T)> Tail;}
II_D_TTL_(2);II_D_TTL_(3);II_D_TTL_(4);II_D_TTL_(5);II_D_TTL_(6);II_D_TTL_(7);II_D_TTL_(8);II_D_TTL_(9);II_D_TTL_(10);II_D_TTL_(11);II_D_TTL_(12);II_D_TTL_(13);II_D_TTL_(14);II_D_TTL_(15);II_D_TTL_(16);II_D_TTL_(17);II_D_TTL_(18);II_D_TTL_(19);II_D_TTL_(20);II_D_TTL_(21);II_D_TTL_(22);II_D_TTL_(23);II_D_TTL_(24);II_D_TTL_(25);II_D_TTL_(26);II_D_TTL_(27);II_D_TTL_(28);II_D_TTL_(29);II_D_TTL_(30);II_D_TTL_(31);II_D_TTL_(32);II_D_TTL_(33);II_D_TTL_(34);II_D_TTL_(35);II_D_TTL_(36);II_D_TTL_(37);II_D_TTL_(38);II_D_TTL_(39);II_D_TTL_(40);II_D_TTL_(41);II_D_TTL_(42);II_D_TTL_(43);II_D_TTL_(44);II_D_TTL_(45);II_D_TTL_(46);II_D_TTL_(47);II_D_TTL_(48);II_D_TTL_(49);II_D_TTL_(50);
#undef II_D_TTL_
#endif
}}namespace iutest{
#if IUTEST_HAS_VARIADIC_TEMPLATES
template<typename ...Args>struct Types{typedef detail::VariadicTypeList<Args...> type;template<size_t N>struct get:public detail::typelist_get<type,N>{};};
#else
#define II_D_DEF_A_(i,param) IP_CAT(param,i)=detail::None
template<IP_ENM(50,II_D_DEF_A_,typename T)>struct Types{typedef detail::TypeList50<IP_ENM_P(50,T)> type;template<size_t N>struct get:public detail::typelist_get<type,N>{};};
#undef II_D_DEF_A_
#define II_D_T_CONCATTYPENAME_(i,param) GetTypeNameProxy<IP_CAT(param,i)>::GetTypeName()+", " +
#define II_D_T_GETTYPENAME_I_(n,m) template<IP_ENM_P(n,typename T)>struct GetTypeNameProxy<Types<IP_ENM_P(n,T) ,IP_ENM(m,II_D_S_NN_,detail::None)> >{static ::std::string GetTypeName(){::std::string name="iutest::Types<";name+=IUTEST_PP_REPEAT(IP_DEC(n),II_D_T_CONCATTYPENAME_,T) GetTypeNameProxy<IP_CAT(T,IP_DEC(n))>::GetTypeName()+">";return name;}}
#define II_D_T_GETTYPENAME_(n,m) namespace detail{II_D_T_GETTYPENAME_I_(n,m);}
#define II_D_S_NN_(i,param) param
#define II_D_T_(n,m) II_D_T_GETTYPENAME_(n,m) template<IP_ENM_P(n,typename T)> struct Types<IP_ENM_P(n,T) ,IP_ENM(m,II_D_S_NN_,detail::None)>{typedef IP_CAT(detail::TypeList,n)< IP_ENM_P(n,T)> type;template<size_t N>struct get:public detail::typelist_get<type,N>{};}
template<>struct Types<IP_ENM(50,II_D_S_NN_,detail::None)>{typedef detail::TypeList0 type;};II_D_T_(1,49);II_D_T_(2,48);II_D_T_(3,47);II_D_T_(4,46);II_D_T_(5,45);II_D_T_(6,44);II_D_T_(7,43);II_D_T_(8,42);II_D_T_(9,41);II_D_T_(10,40);II_D_T_(11,39);II_D_T_(12,38);II_D_T_(13,37);II_D_T_(14,36);II_D_T_(15,35);II_D_T_(16,34);II_D_T_(17,33);II_D_T_(18,32);II_D_T_(19,31);II_D_T_(20,30);II_D_T_(21,29);II_D_T_(22,28);II_D_T_(23,27);II_D_T_(24,26);II_D_T_(25,25);II_D_T_(26,24);II_D_T_(27,23);II_D_T_(28,22);II_D_T_(29,21);II_D_T_(30,20);II_D_T_(31,19);II_D_T_(32,18);II_D_T_(33,17);II_D_T_(34,16);II_D_T_(35,15);II_D_T_(36,14);II_D_T_(37,13);II_D_T_(38,12);II_D_T_(39,11);II_D_T_(40,10);II_D_T_(41,9);II_D_T_(42,8);II_D_T_(43,7);II_D_T_(44,6);II_D_T_(45,5);II_D_T_(46,4);II_D_T_(47,3);II_D_T_(48,2);II_D_T_(49,1);
#undef II_D_T_CONCATTYPENAME_
#undef II_D_T_GETTYPENAME_I_
#undef II_D_T_GETTYPENAME_
#undef II_D_S_NN_
#undef II_D_T_
#endif
namespace detail{
#if IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES
template<II_TEMPLATE_TPARAM1 ...Types>struct Templates{typedef VariadicTemplateTypeList<Types...> type;};
#else
#define II_D_DEF_A_(i,param) IP_CAT(param,i)=detail::NoneT1
template<IP_ENM(50,II_D_DEF_A_,II_TEMPLATE_TPARAM1 T)>struct Templates{typedef detail::TemplateTypeList50<IP_ENM_P(50,T)> type;};
#undef II_D_DEF_A_
#define II_D_S_NN_(i,param) param
#define II_D_TPL_(n,m) template<IP_ENM_P(n,II_TEMPLATE_TPARAM1 T)> struct Templates<IP_ENM_P(n,T) ,IP_ENM(m,II_D_S_NN_,detail::NoneT1)>{typedef IP_CAT(detail::TemplateTypeList,n)< IP_ENM_P(n,T)> type;}
template<>struct Templates<IP_ENM(50,II_D_S_NN_,detail::NoneT1)>{typedef detail::TemplateTypeList0 type;};II_D_TPL_(1,49);II_D_TPL_(2,48);II_D_TPL_(3,47);II_D_TPL_(4,46);II_D_TPL_(5,45);II_D_TPL_(6,44);II_D_TPL_(7,43);II_D_TPL_(8,42);II_D_TPL_(9,41);II_D_TPL_(10,40);II_D_TPL_(11,39);II_D_TPL_(12,38);II_D_TPL_(13,37);II_D_TPL_(14,36);II_D_TPL_(15,35);II_D_TPL_(16,34);II_D_TPL_(17,33);II_D_TPL_(18,32);II_D_TPL_(19,31);II_D_TPL_(20,30);II_D_TPL_(21,29);II_D_TPL_(22,28);II_D_TPL_(23,27);II_D_TPL_(24,26);II_D_TPL_(25,25);II_D_TPL_(26,24);II_D_TPL_(27,23);II_D_TPL_(28,22);II_D_TPL_(29,21);II_D_TPL_(30,20);II_D_TPL_(31,19);II_D_TPL_(32,18);II_D_TPL_(33,17);II_D_TPL_(34,16);II_D_TPL_(35,15);II_D_TPL_(36,14);II_D_TPL_(37,13);II_D_TPL_(38,12);II_D_TPL_(39,11);II_D_TPL_(40,10);II_D_TPL_(41,9);II_D_TPL_(42,8);II_D_TPL_(43,7);II_D_TPL_(44,6);II_D_TPL_(45,5);II_D_TPL_(46,4);II_D_TPL_(47,3);II_D_TPL_(48,2);II_D_TPL_(49,1);
#undef II_D_S_NN_
#undef II_D_TPL_
#endif
template<typename T>struct TypeList{typedef detail::TypeList1<T> type;};
#if IUTEST_HAS_VARIADIC_TEMPLATES
template<typename ...Args>struct TypeList<Types<Args...> >{typedef typename Types<Args...>::type type;};
#else
template<IP_ENM_P(50,typename T)>struct TypeList<Types<IP_ENM_P(50,T)> >{typedef typename Types<IP_ENM_P(50,T)>::type type;};
#endif
}}
#define IUTEST_TYPED_TEST_CASE(t_c_,...) II_T_TC_(t_c_,__VA_ARGS__)
#define IUTEST_TYPED_TEST(t_c_,tn_) IUTEST_TYPED_TEST_(t_c_,tn_)
#define IUTEST_T(t_c_,tn_) IUTEST_TYPED_TEST_(t_c_,tn_)
#define II_T_T_PRMS_(t_c_) II_T_T_PRMS_I_(IUTEST_PP_IF(IP_IS_B_PAR(t_c_) ,II_ALS_TN_F_,IP_EMPTY()) t_c_)
#define II_T_T_PRMS_I_(t_c_) II_T_T_PRMS_II_(II_TO_VN_(t_c_))
#define II_T_T_PRMS_II_(t_c_) II_T_T_PRMS_III_(t_c_)
#define II_T_T_PRMS_III_(t_c_) iutest_types_params_##t_c_
#define II_T_TC_(t_c_,...) typedef ::iutest::detail::TypeList<__VA_ARGS__ >::type II_T_T_PRMS_(t_c_)
#define II_T_T_I(classname_,t_c_,tcn_,tn_) template<typename iutest_TypeParam> class classname_:public t_c_<iutest_TypeParam>{typedef t_c_<iutest_TypeParam> TestFixture;typedef iutest_TypeParam TypeParam;protected: virtual void Body() II_CXX_O;};::iutest::detail::TypeParamTestInstance<classname_,II_T_T_PRMS_(t_c_)> II_T_INST_N_(t_c_,tn_)(II_CC_PKG_(tcn_),II_TO_N_STR_(tn_));template<typename iutest_TypeParam> void classname_<iutest_TypeParam>::Body()
#define II_T_T_(mcr,t_c_,tn_) mcr(II_T_CLS_N_(t_c_,tn_) ,II_TO_VN_(t_c_),II_TO_N_(t_c_) ,tn_)
#define II_T_T_A_(mcr,t_c_,tn_) II_T_T_(mcr,IUTEST_PP_IF(IP_IS_B_PAR(t_c_) ,II_ALS_TN_F_,IP_EMPTY()) t_c_,tn_)
#define IUTEST_TYPED_TEST_(t_c_,tn_) II_T_T_A_(II_T_T_I,t_c_,tn_)
#define IUTEST_TYPED_TEST_CASE_P(t_c_) II_T_TC_P_(t_c_)
#define IUTEST_TYPED_TEST_P(t_c_,tn_) II_T_T_P_(t_c_,tn_)
#define IUTEST_TP(t_c_,tn_) II_T_T_P_(t_c_,tn_)
#define IUTEST_REGISTER_TYPED_TEST_CASE_P(t_c_,...) II_R_T_TC_P_(t_c_,__VA_ARGS__)
#define IUTEST_INSTANTIATE_TYPED_TEST_CASE_P(pfx_,t_c_,...) II_INST_T_TC_P_(pfx_,t_c_,__VA_ARGS__)
#define II_T_TC_PS_N_(t_c_) s_iutest_typed_test_case_p_state_##t_c_##_
#define II_T_T_P_NS_(t_c_) iutest_typed_test_case_p_name_##t_c_##_
#define II_T_T_P_ADD_TN(t_c_,tn_) static const int s_iutest_##tn_##_defined_dmy_ II_ATR_U=II_T_TC_PS_N_(t_c_).AddTestName(__FILE__,__LINE__,#t_c_,#tn_)
#define II_T_TC_P_(t_c_) static ::iutest::detail::TypedTestCasePState II_T_TC_PS_N_(t_c_)
#define II_T_T_P_(t_c_,tn_) IUTEST_STATIC_ASSERT_MSG(sizeof(IUTEST_PP_TOSTRING(t_c_))> 1,"t_c_ must not be empty");IUTEST_STATIC_ASSERT_MSG(sizeof(IUTEST_PP_TOSTRING(tn_))> 1,"tn_ must not be empty");namespace II_T_T_P_NS_(t_c_){template<typename iutest_TypeParam> class tn_:public t_c_<iutest_TypeParam>{typedef t_c_<iutest_TypeParam> TestFixture;typedef iutest_TypeParam TypeParam;protected: virtual void Body() II_CXX_O;};II_T_T_P_ADD_TN(t_c_,tn_);}template<typename iutest_TypeParam> void II_T_T_P_NS_(t_c_)::tn_<iutest_TypeParam>::Body()
#define II_R_T_TC_P_(t_c_,...) namespace II_T_T_P_NS_(t_c_){typedef ::iutest::detail::Templates<__VA_ARGS__ >::type iutest_AllTests_;}static const bool s_iutest_##t_c_##_register_dmy_ II_ATR_U=II_T_TC_PS_N_(t_c_).VerifyTestNames(__FILE__,__LINE__,#__VA_ARGS__)
#define II_INST_T_TC_P_(pfx_,t_c_,...) const bool iutest_##pfx_##_##t_c_ II_ATR_U=::iutest::detail::TypeParameterizedTestCase<t_c_ ,II_T_T_P_NS_(t_c_)::iutest_AllTests_ ,::iutest::detail::TypeList<__VA_ARGS__ >::type >::Register(#pfx_,II_TO_N_STR_(t_c_),II_GET_PKGN_() ,II_T_TC_PS_N_(t_c_).names())
namespace iutest{namespace detail{template<template<typename T> class Tester,typename TypeParams>class TypeParamTestInstance{template<typename TT,typename DMY>class EachTest{typedef typename TT::Head TypeParam;typedef Tester<TypeParam> TestBody;typedef TypedTestCase<TypeParam> _MyTestCase;public: EachTest(const char* testcase,const char* name,size_t index):m_mediator(AddTestCase(testcase,index)),m_info(&m_mediator,name,&m_factory),m_next(testcase,name,index+1){}EachTest(const ::std::string& testcase,const char* name,size_t index):m_mediator(AddTestCase(testcase,index)),m_info(&m_mediator,name,&m_factory),m_next(testcase,name,index+1){}private: static TestCase* AddTestCase(const char* testcase,size_t index){return UnitTest::instance().AddTestCase<_MyTestCase>(
#if IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME
detail::MakeIndexTypedTestName<TypeParam>(testcase,index)
#else
detail::MakeIndexTestName(testcase,index)
#endif
,internal::GetTypeId<detail::None>(),TestBody::SetUpTestCase,TestBody::TearDownTestCase);}static TestCase* AddTestCase(const ::std::string& testcase,size_t index){return AddTestCase(testcase.c_str(),index);}public: void AddTest(){UnitTest::instance().AddTestInfo(m_mediator.ptr(),&m_info);m_next.AddTest();}private: TestCaseMediator m_mediator;TestInfo m_info;detail::iuFactory<TestBody> m_factory;EachTest<typename TT::Tail,void> m_next;};template<typename DMY>class EachTest<detail::TypeList0,DMY>{public: EachTest(const char*,const char*,size_t){}EachTest(const ::std::string&,const char*,size_t){}void AddTest(){}};public: TypeParamTestInstance(const char* testcase,const char* name):m_tests(testcase,name,0){m_tests.AddTest();}TypeParamTestInstance(const std::string& testcase,const char* name):m_tests(testcase,name,0){m_tests.AddTest();}private: EachTest<TypeParams,void> m_tests;IP_DIS_C_A_A(TypeParamTestInstance);};class TypedTestCasePState{typedef ::std::set<const char*> nameset_t;public: TypedTestCasePState():m_names(0){}public: const char* names()const{return m_names;}public: bool AddTestName(const char* file,int line,const char* t_c_name,const char* test_name){if(m_names!=0){IUTEST_LOG_(WARNING)<<detail::FormatCompilerIndependentFileLocation(file,line)<< ": Test \"" <<test_name<<"\" must be defined before IUTEST_REGISTER_TYPED_TEST_CASE_P("<<t_c_name<<", ...).\n";}m_list.insert(test_name);return true;}bool VerifyTestNames(const char* file,int line,const char* test_names){m_names=test_names;bool ret=true;for(nameset_t::iterator it=m_list.begin(),end=m_list.end();it!=end;++it){const char* test_name=*it;const char* p=strstr(test_names,test_name);if(p!=0){const size_t len=strlen(test_name);if(p[len]=='\0' || p[len]==',' || detail::IsSpace(p[len])){continue;}IUTEST_LOG_(FATAL)<<detail::FormatCompilerIndependentFileLocation(file,line)<< ": Test \"" <<test_name<<"\" is find in \"" <<test_names<< "\". expected whitespace or comma : " <<p[len]<<"(" <<static_cast<int>(p[len])<<")\n";}IUTEST_LOG_(WARNING)<<detail::FormatCompilerIndependentFileLocation(file,line)<< ": Test \"" <<test_name<<"\" has not been registered.\n" << "    TestNames: " <<test_names;ret=false;}return ret;}private: const char* m_names;nameset_t m_list;IP_DIS_C_A_A(TypedTestCasePState);};template<template<typename T> class Fixture,typename Tests,typename Types>class TypeParameterizedTestCase{template<typename TypeParam,typename TestsList>class EachTest:public iuIObject{typedef typename TestsList::Head TypeSel;typedef typename TypeSel::template bind<TypeParam>::type TestBody;typedef detail::iuFactory<TestBody> Factory;typedef EachTest<TypeParam,TestsList> _Myt;EachTest(TestCase* testcase,const ::std::string& name):m_mediator(testcase),m_info(&m_mediator,name,&m_factory){UnitTest::instance().AddTestInfo(testcase,&m_info);}public: static void Register(TestCase* testcase,const char* test_names){IUTEST_CHECK_(test_names!=0);const char* str=detail::SkipSpace(test_names);const char* comma=strchr(str,',');::std::string test_name;if(comma==0){test_name=str;}else{test_name=::std::string(str,static_cast<size_t>(comma-str));++comma;}_Myt* test=new EachTest(testcase,StripTrailingSpace(test_name));detail::iuPool::GetInstance().push(test);EachTest<TypeParam,typename TestsList::Tail>::Register(testcase,detail::SkipSpace(comma));}private: TestCaseMediator m_mediator;Factory m_factory;TestInfo m_info;};template<typename TypeParam>class EachTest<TypeParam,detail::TemplateTypeList0>{public: static void Register(TestCase*,const char*){}};public: static bool Register(const char* prefix,const char* t_c_name,const ::std::string& package_name,const char* names,size_t index=0){
#if IUTEST_HAS_EXCEPTIONS
try{return Register_(prefix,t_c_name,package_name,names,index);}catch(const ::std::exception& e){IUTEST_LOG_(FATAL)<<"IUTEST_INSTANTIATE_TYPED_TEST_CASE_P register tests failed...\n"<<e.what();}catch(...){IUTEST_LOG_(FATAL)<<"IUTEST_INSTANTIATE_TYPED_TEST_CASE_P register tests failed...\n";}return false;
#else
return Register_(prefix,t_c_name,package_name,names,index);
#endif
}private: static bool Register_(const char* prefix,const char* t_c_name,const ::std::string& package_name,const char* names,size_t index){typedef typename Types::Head TypeParam;typedef typename Tests::Head Head;typedef Fixture<Head> FixtureClass;typedef TypedTestCase<TypeParam> _MyTestCase;::std::string full_t_c_name=package_name;full_t_c_name+=
#if IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME
detail::MakePrefixedIndexTypedTestName<TypeParam>(prefix,t_c_name,index);
#else
detail::MakePrefixedIndexTestName(prefix,t_c_name,index);
#endif
TestCase* testcase =UnitTest::instance().AddTestCase<_MyTestCase>(full_t_c_name,internal::GetTypeId<FixtureClass>(),FixtureClass::SetUpTestCase,FixtureClass::TearDownTestCase);EachTest<TypeParam,Tests>::Register(testcase,names);return TypeParameterizedTestCase<Fixture,Tests,typename Types::Tail>::Register(prefix,t_c_name,package_name,names,index+1);}};template<template<typename T> class Fixture,typename Tests>class TypeParameterizedTestCase<Fixture,Tests,detail::TypeList0>{public: static bool Register(const char*,const char*,const ::std::string&,const char*,size_t index=0){(void)(index);return true;}};}}
#define IUTEST_FRIEND_TEST(tcn_,tn_) friend class II_T_CLS_N_(tcn_,tn_)
#define IUTEST_FRIEND_TYPED_TEST(tcn_,tn_) template<typename T>IUTEST_FRIEND_TEST(tcn_,tn_)
#define IUTEST_FRIEND_TYPED_TEST_P_DECLARATION(tcn_,tn_) namespace II_T_T_P_NS_(tcn_){template<typename T>class tn_;}
#define IUTEST_FRIEND_TYPED_TEST_P(tcn_,tn_) template<typename T>friend class II_T_T_P_NS_(tcn_)::tn_
#define IUTEST_MAKE_PEEP(member_type,class_name,member_name) IUTEST_MAKE_PEEP_TAG_(member_type,class_name,member_name)
#define IUTEST_PEEP_GET(v,class_name,member_name) (v.*::iutest::detail::peep_tag<II_PE_T_N_(class_name,member_name)<class_name> >::value)
#define IUTEST_PEEP_STATIC_GET(class_name,member_name) (*::iutest::detail::peep_tag<II_PE_T_N_(class_name,member_name)<class_name> >::value)
#if IUTEST_HAS_PEEP_CLASS
#define IUTEST_PEEP(class_name,member_name) ::iutest::detail::peep::Peep<class_name,II_PE_T_N_(class_name,member_name)<class_name> >::type
#endif
#define IUTEST_MAKE_PEEP_TAG_(member_type,class_name,member_name) template<typename T>struct II_PE_T_N_(class_name,member_name);template<>struct II_PE_T_N_(class_name,member_name)<class_name>{typedef ::iutest_type_traits::identity<member_type>::type type;};template<typename T,typename Tag,typename Tag::type X> struct II_PE_S_N_(class_name,member_name){II_PE_S_N_(class_name,member_name)(){::iutest::detail::peep_tag<Tag>::value=X;}static II_PE_S_N_(class_name,member_name) instance;};template<typename T,typename Tag,typename Tag::type X> II_PE_S_N_(class_name,member_name)<T,Tag,X> II_PE_S_N_(class_name,member_name)<T,Tag,X>::instance;template struct II_PE_S_N_(class_name,member_name)<class_name ,II_PE_T_N_(class_name,member_name)<class_name>,&class_name::member_name>
#define II_PE_T_N_(class_name,member_name) iu_peep_tag_##member_name
#define II_PE_S_N_(class_name,member_name) IP_CAT(IP_CAT(iu_peep_set_,member_name),__LINE__)
namespace iutest{namespace detail{template<typename Tag>struct peep_tag{static typename Tag::type value;};template<typename Tag>typename Tag::type peep_tag<Tag>::value;
#if IUTEST_HAS_PEEP_CLASS
namespace peep{template<typename T,typename Tag>class Peep{private: typedef Tag peep_tag;typedef typename Tag::type peep_type;private: template<typename U,typename Type>class peep_member_function_impl{private: typedef typename type_traits::function_return_type<Type>::type return_type;private: U* m_ptr;public: explicit peep_member_function_impl(U* ptr):m_ptr(ptr){}
#if IUTEST_HAS_VARIADIC_TEMPLATES
public: template<typename ...Args>return_type operator()(Args... args){return((*m_ptr).*detail::peep_tag<peep_tag>::value)(::std::forward<Args>(args)...);}
#else
#define II_D_PE_M_F_(n) template<IP_ENM_P(n,typename T)>return_type operator()(IP_ENM_B_P(n,T,t)){return((*m_ptr).*detail::peep_tag<peep_tag>::value)(IP_ENM_P(n,t));}
return_type operator()(){return((*m_ptr).*detail::peep_tag<peep_tag>::value)();}II_D_PE_M_F_(1)II_D_PE_M_F_(2)II_D_PE_M_F_(3)II_D_PE_M_F_(4)II_D_PE_M_F_(5)II_D_PE_M_F_(6)II_D_PE_M_F_(7)II_D_PE_M_F_(8)II_D_PE_M_F_(9)II_D_PE_M_F_(10)II_D_PE_M_F_(11)II_D_PE_M_F_(12)II_D_PE_M_F_(13)II_D_PE_M_F_(14)II_D_PE_M_F_(15)II_D_PE_M_F_(16)II_D_PE_M_F_(17)II_D_PE_M_F_(18)II_D_PE_M_F_(19)II_D_PE_M_F_(20)
#undef II_D_PE_M_F_
#endif
};template<typename U,typename Type,bool is_const>class peep_member_object_impl{typedef Type value_type;private: U* m_ptr;public: explicit peep_member_object_impl(U* ptr):m_ptr(ptr){}private: peep_member_object_impl(const peep_member_object_impl&);public: operator value_type()const{return(*m_ptr).*detail::peep_tag<peep_tag>::value;}peep_member_object_impl& operator=(const value_type& value) II_CXX_DL_F;};template<typename U,typename Type>class peep_member_object_impl<U,Type,false>{typedef Type value_type;private: U* m_ptr;public: explicit peep_member_object_impl(U* ptr):m_ptr(ptr){}private: peep_member_object_impl(const peep_member_object_impl&);public: operator value_type()const{return(*m_ptr).*detail::peep_tag<peep_tag>::value;}operator value_type&(){return(*m_ptr).*detail::peep_tag<peep_tag>::value;}peep_member_object_impl& operator=(const value_type& value){(*m_ptr).*detail::peep_tag<peep_tag>::value=value;return *this;}};template<typename U,typename Type,bool Func>struct peep_member_impl{typedef peep_member_function_impl<U,Type> type;};template<typename U,typename Type>struct peep_member_impl<U,Type U::*,false>{typedef peep_member_object_impl<U,Type,type_traits::is_const<Type>::value> type;};private: template<typename U,typename Type,bool Func>class peep_static_impl{typedef typename type_traits::remove_pointer<Type>::type value_type;public: peep_static_impl(){}peep_static_impl(const value_type& value){*detail::peep_tag<peep_tag>::value=value;}peep_static_impl(const peep_static_impl&){}public: operator value_type()const{return *detail::peep_tag<peep_tag>::value;}operator value_type&(){return *detail::peep_tag<peep_tag>::value;}peep_static_impl& operator=(const value_type& value){*detail::peep_tag<peep_tag>::value=value;return *this;}};template<typename U,typename Type>class peep_static_impl<U,Type,true>{public: operator Type(){return *detail::peep_tag<peep_tag>::value;}};private: template<typename U,typename Type,bool is_member_ptr>struct peep_impl{typedef peep_static_impl<U,Type,type_traits::is_function_pointer<Type>::value>type;};template<typename U,typename Type>struct peep_impl<U,Type,true>{typedef typename peep_member_impl<U,Type,type_traits::is_member_function_pointer<Type>::value >::type type;};public: typedef typename peep_impl<T,peep_type,type_traits::is_member_pointer<peep_type>::value >::type type;};}
#endif
}}
#define IUTEST_OPERAND(op) op II_EXPR_DEC()
#define IUTEST_EXPRESSION(expr) (II_EXPR_DEC() expr).GetResult()
#define II_EXPR_DEC() ::iutest::detail::ExpressionDecomposer()->*
#define II_T_EXPR_UNPAREN_(...) __VA_ARGS__
#define II_T_EXPR_E_E(expr) II_T_EXPR_E_E_(UNPAREN_ expr)
#define II_T_EXPR_E_E_(expr) II_T_EXPR_##expr
#define II_T_EXPR_(expr,expected,on_f) IUTEST_TEST_TRUE((II_EXPR_DEC() expr).GetResult(expected),#expr,on_f)
#define IUTEST_TEST_EXPRESSION_(expr,expected,on_f) II_T_EXPR_(II_T_EXPR_E_E(expr),expected,on_f)
#define II_D_EP_R_OP(op) template<typename RHS>ExpressionResult operator op(const RHS& rhs)const{const bool b=result() op rhs?true:false;return ExpressionResult(AssertionResult(b) <<m_result.message()<<" " #op " " <<rhs);}ExpressionResult operator op(const ExpressionResult& rhs)const{const bool b=result() op rhs.result()?true:false;return ExpressionResult(AssertionResult(b) <<m_result.message()<<" " #op " " <<rhs.message());}ExpressionResult operator op(const AssertionResult& rhs)const{const bool b=result() op rhs.passed()?true:false;return ExpressionResult(AssertionResult(b) <<m_result.message()<<" " #op " " <<rhs.message());}
#define II_D_EP_OP(op) template<typename RHS>ExpressionResult operator op(const RHS& rhs)const{const bool b=(m_lhs op rhs)?true:false;return ExpressionResult(AssertionResult(b)<<m_message<<" " #op " " <<rhs);}
#if IUTEST_HAS_DECLTYPE&&IUTEST_HAS_STD_DECLVAL
#define II_D_EP_OP_LHS(op) template<typename RHS>auto operator op(const RHS& rhs)const -> ExpressionLHS<decltype(expression_op_helper::operand_result((::std::declval<T>() op rhs)))>{return OperandResult(m_lhs op rhs)<<" " #op " " <<rhs;}
#else
#define II_D_EP_OP_LHS(op) template<typename RHS>ExpressionLHS<RHS> operator op(const RHS& rhs)const{return OperandResult(m_lhs op rhs)<<" " #op " " <<rhs;}
#endif
namespace iutest{namespace detail{class ExpressionResult{public: explicit ExpressionResult(const AssertionResult& ar):m_result(ar){}public: II_D_EP_R_OP(||)II_D_EP_R_OP(&&)public: AssertionResult GetResult(bool expected)const{return AssertionResult(result()==expected)<<"expansion: " <<m_result.message();}AssertionResult GetResult()const{return AssertionResult(result())<<m_result.message();}private: bool result()const{return m_result.passed();}const char* message()const{return m_result.message();}private: AssertionResult m_result;};namespace expression_op_helper{template<typename T>T operand_result(const T&);}template<typename T>class ExpressionLHS{typedef ExpressionLHS<T> _Myt;public:
#if IUTEST_HAS_RVALUE_REFS
explicit ExpressionLHS(T&& lhs):m_lhs(::std::forward<T>(lhs)){AppendMessage(m_lhs);}
#else
explicit ExpressionLHS(T lhs):m_lhs(lhs){AppendMessage(lhs);}
#endif
ExpressionLHS(T lhs,const ::std::string& msg):m_lhs(lhs),m_message(msg){}public: II_D_EP_OP(==)II_D_EP_OP(!=)II_D_EP_OP(<)II_D_EP_OP(<=)II_D_EP_OP(>)II_D_EP_OP(>=)II_D_EP_OP(&&)II_D_EP_OP(||)II_D_EP_OP_LHS(+)II_D_EP_OP_LHS(-)II_D_EP_OP_LHS(*)II_D_EP_OP_LHS(/)II_D_EP_OP_LHS(%)
#if IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE
II_D_EP_OP_LHS(&)II_D_EP_OP_LHS(|)II_D_EP_OP_LHS(^)II_D_EP_OP_LHS(<<)II_D_EP_OP_LHS(>>)
#endif
private: template<typename U>ExpressionLHS<U> OperandResult(const U& lhs)const{return ExpressionLHS<U>(lhs,m_message);}public: template<typename U>_Myt& operator<<(const U& value){AppendMessage(value);return *this;}public: AssertionResult GetResult(bool expected)const{const bool b=m_lhs?true:false;return AssertionResult(b==expected)<<"expansion: " <<m_message;}AssertionResult GetResult()const{const bool b=m_lhs?true:false;return AssertionResult(b)<<m_message;}private: template<typename U>void AppendMessage(const U& value){Message msg;msg<<value;m_message+=msg.GetString();}private: ExpressionLHS& operator=(const ExpressionLHS&) II_CXX_DL_F;private: T m_lhs;::std::string m_message;};
#undef II_D_EP_R_OP
#undef II_D_EP_OP
#ifdef II_D_EP_OP_LHS
#undef II_D_EP_OP_LHS
#endif
class ExpressionDecomposer{public:
#if IUTEST_HAS_RVALUE_REFS
template<typename T>ExpressionLHS<T> operator ->*(T&& expr){return ExpressionLHS<T>(::std::forward<T>(expr));}
#else
template<typename T>ExpressionLHS<const T&> operator ->*(const T& expr){return ExpressionLHS<const T&>(expr);}
#endif
};}}
#define IUTEST_TEST_THAT(actual,matcher,on_f) II_AMB_E_B if(::iutest::AssertionResult iutest_ar=matcher(actual)){}else on_f(::iutest::detail::MatcherAssertionFailureMessage(::iutest::PrintToString(actual).c_str(),#matcher,iutest_ar))
namespace iutest{namespace detail{inline ::std::string MatcherAssertionFailureMessage(const char* actual,const char* matcher_str,const AssertionResult& ar){iu_global_format_stringstream strm;strm<<"error: Expected: " <<matcher_str<< "\n  Actual: " <<actual<< "\nWhich is: " <<ar.message();return strm.str();}II_PGM_A_O_CN_G_W_D_B()class IMatcher{IMatcher& operator=(const IMatcher&);public: template<typename T>struct is_matcher:public iutest_type_traits::is_base_of<IMatcher,T>{};public: IMatcher(){}IMatcher(const IMatcher&){}virtual ~IMatcher(){}virtual ::std::string WhichIs()const=0;};template<typename T>inline typename detail::enable_if_t<IMatcher::is_matcher<T>,iu_ostream>::type& operator<<(iu_ostream& os,const T& m){return os<<m.WhichIs();}
#define II_D_COMP_M(name,op) template<typename T>class IP_CAT(name,Matcher):public IMatcher{public: explicit IP_CAT(name,Matcher)(const T& v):m_expected(v){}::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<#name ": " <<m_expected;return strm.str();}template<typename U>AssertionResult operator()(const U& actual)const{if(actual op m_expected) return AssertionSuccess();return AssertionFailure()<<WhichIs();}private: const T& m_expected;}
#define II_D_COMP_M2(name,op) class IP_CAT(Twofold,IP_CAT(name,Matcher)):public IMatcher{public: ::std::string WhichIs()const II_CXX_O{return #name;}template<typename T,typename U>AssertionResult operator() (const T& actual,const U& expected)const{if(actual op expected) return AssertionSuccess();return AssertionFailure()<<WhichIs()<<": " <<actual<<" vs " <<expected;}}
II_PGM_W_PU()II_PGM_W_D_S_C()II_D_COMP_M(Ne,!=);II_D_COMP_M(Le,<=);II_D_COMP_M(Lt,<);II_D_COMP_M(Ge,>=);II_D_COMP_M(Gt,>);II_D_COMP_M2(Eq,==);II_D_COMP_M2(Ne,!=);II_D_COMP_M2(Le,<=);II_D_COMP_M2(Lt,<);II_D_COMP_M2(Ge,>=);II_D_COMP_M2(Gt,>);II_PGM_W_PP()
#undef II_D_COMP_M
#undef II_D_COMP_M2
#define II_D_S_COMP_M(name) template<typename T>class IP_CAT(name,Matcher):public IMatcher{public: IP_CAT(name,Matcher)(const T& value):m_expected(value){}template<typename U>AssertionResult operator()(const U& actual)const{if(internal::IP_CAT(name,Helper)::Compare(actual,m_expected)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<#name ": " <<m_expected;return strm.str();}private: const T& m_expected;}
II_D_S_COMP_M(StrEq);II_D_S_COMP_M(StrNe);II_D_S_COMP_M(StrCaseEq);II_D_S_COMP_M(StrCaseNe);
#undef II_D_COMP_M
class IsNullMatcher:public IMatcher{public: template<typename U>AssertionResult operator()(const U* actual)const{if(actual==0){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}::std::string WhichIs()const II_CXX_O{return "Is Null";}};class NotNullMatcher:public IMatcher{public: template<typename U>AssertionResult operator()(const U* actual)const{if(actual!=0){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}::std::string WhichIs()const II_CXX_O{return "Not Null";}};template<typename T>class FloatingPointEqMatcher:public IMatcher{public: explicit FloatingPointEqMatcher(const T& value):m_expected(value){}public: template<typename U>AssertionResult operator()(const U& actual)const{floating_point<T> f2(actual);if(m_expected.AlmostEquals(f2)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Eq: " <<PrintToString(m_expected);return strm.str();}private: floating_point<T> m_expected;};template<typename T>class NanSensitiveFloatingPointEqMatcher:public IMatcher{public: explicit NanSensitiveFloatingPointEqMatcher(const T& value):m_expected(value){}public: template<typename U>AssertionResult operator()(const U& actual)const{floating_point<T> f2(actual);if(m_expected.NanSensitiveAlmostEquals(f2)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"NanSensitive Eq: " <<PrintToString(m_expected);return strm.str();}private: floating_point<T> m_expected;};template<typename T>class FloatingPointNearMatcher:public IMatcher{public: explicit FloatingPointNearMatcher(const T& value,const T& abs_error):m_expected(value),m_max_abs_error(abs_error){}public: template<typename U>AssertionResult operator()(const U& actual)const{floating_point<T> a(actual);if(m_expected.AlmostNear(a,m_max_abs_error)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Near: " <<PrintToString(m_expected)<<"(abs error <= " <<m_max_abs_error<<")";return strm.str();}private: floating_point<T> m_expected;T m_max_abs_error;};template<typename T>class NanSensitiveFloatingPointNearMatcher:public IMatcher{public: explicit NanSensitiveFloatingPointNearMatcher(const T& value,const T& abs_error):m_expected(value),m_max_abs_error(abs_error){}public: template<typename U>AssertionResult operator()(const U& actual)const{floating_point<T> a(actual);if(m_expected.NanSensitiveAlmostNear(a,m_max_abs_error)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"NanSensitive Near: " <<PrintToString(m_expected)<<"(abs error <= " <<m_max_abs_error<<")";return strm.str();}private: floating_point<T> m_expected;T m_max_abs_error;};template<typename T>class StartsWithMatcher:public IMatcher{public: explicit StartsWithMatcher(T str):m_expected(str){}public: template<typename U>AssertionResult operator()(const U& actual)const{if(StartsWith(actual,m_expected)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"StartsWith: " <<m_expected;return strm.str();}private: static bool StartsWith(const char* actual,const char* start){return strstr(actual,start)==actual;}static bool StartsWith(const ::std::string& actual,const char* start){const char* p=actual.c_str();return StartsWith(p,start);}static bool StartsWith(const char* actual,const ::std::string& start){const char* p=start.c_str();return StartsWith(actual,p);}static bool StartsWith(const ::std::string& actual,const ::std::string& start){const char* p=start.c_str();return StartsWith(actual,p);}private: T m_expected;};template<typename T>class HasSubstrMatcher:public IMatcher{public: explicit HasSubstrMatcher(T expected):m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual)const{if(HasSubstr(actual,m_expected)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"HasSubstr: " <<m_expected;return strm.str();}private: static bool HasSubstr(const char* actual,const char* expected){return strstr(actual,expected)!=0;}static bool HasSubstr(const ::std::string& actual,const char* expected){const char* p=actual.c_str();return HasSubstr(p,expected);}static bool HasSubstr(const char* actual,const ::std::string& expected){const char* p=expected.c_str();return HasSubstr(actual,p);}static bool HasSubstr(const ::std::string& actual,const ::std::string& expected){const char* p=expected.c_str();return HasSubstr(actual,p);}private: T m_expected;};template<typename T>class EndsWithMatcher:public IMatcher{public: explicit EndsWithMatcher(T str):m_expected(str){}public: template<typename U>AssertionResult operator()(const U& actual)const{if(EndsWith(actual,m_expected)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"EndsWith: " <<m_expected;return strm.str();}private: static bool EndsWith(const char* actual,const char* end){const size_t len=strlen(end);const size_t actual_len=strlen(actual);if(len>actual_len){return false;}const char* p=actual+actual_len-1;const char* q=end+len-1;for(size_t i=0;i<len;++i,--p,--q){if(*p!=*q){return false;}}return true;}static bool EndsWith(const ::std::string& actual,const char* end){const char* p=actual.c_str();return EndsWith(p,end);}static bool EndsWith(const char* actual,const ::std::string& end){const char* p=end.c_str();return EndsWith(actual,p);}static bool EndsWith(const ::std::string& actual,const ::std::string& end){const char* p=end.c_str();return EndsWith(actual,p);}private: T m_expected;};template<typename T>class EqMatcher:public IMatcher{public: explicit EqMatcher(const T& expected):m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual)const{if(Equals(actual,m_expected)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Eq: " <<m_expected;return strm.str();}private: template<typename A,typename B>static bool Equals(const A& actual,const B& expected){II_PGM_W_PU()II_PGM_W_D_S_C()return actual==expected;II_PGM_W_PP()}static bool Equals(const char* actual,const char* expected){return strcmp(actual,expected)==0;}static bool Equals(const ::std::string& actual,const char* expected){const char* p=actual.c_str();return Equals(p,expected);}static bool Equals(const ::std::string& actual,const ::std::string& expected){const char* p=expected.c_str();return Equals(actual,p);}private: const T& m_expected;};template<typename T>class TypedEqMatcher:public EqMatcher<T>{public: explicit TypedEqMatcher(T expected):EqMatcher<T>(m_expected),m_expected(expected){}public: AssertionResult operator()(const T& actual){return EqMatcher<T>::operator()(actual);}template<typename U>AssertionResult operator()(const U&)const;private: T m_expected;};template<typename T>T& CastToMatcher(T& matcher,typename detail::enable_if_t<IMatcher::is_matcher<T> >::type*& = detail::enabler::value){return matcher;}template<typename T>EqMatcher<T> CastToMatcher(const T& value,typename detail::disable_if_t<IMatcher::is_matcher<T> >::type*& = detail::enabler::value){return EqMatcher<T>(value);}template<typename T>class ContainsMatcher:public IMatcher{public: explicit ContainsMatcher(const T& expected):m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){IUTEST_USING_BEGIN_END();if(Contains(begin(actual),end(actual))){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Contains: " <<m_expected;return strm.str();}private: template<typename Ite>bool Contains(Ite begin,Ite end){for(Ite it=begin;it!=end;++it){if(CastToMatcher(m_expected)(*it)){return true;}}return false;}private: T m_expected;};template<typename T>class EachMatcher:public IMatcher{public: explicit EachMatcher(const T& expected):m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){IUTEST_USING_BEGIN_END();if(Each(begin(actual),end(actual))){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Each: " <<m_expected;return strm.str();}private: template<typename Ite>bool Each(Ite begin,Ite end){for(Ite it=begin;it!=end;++it){if(!CastToMatcher(m_expected)(*it)){return false;}}return true;}private: T m_expected;};template<typename T>class ContainerEqMatcher:public IMatcher{public: explicit ContainerEqMatcher(const T& expected):m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){IUTEST_USING_BEGIN_END();if(Check(begin(m_expected),end(m_expected),begin(actual),end(actual))){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"ContainerEq: " <<PrintToString(m_expected);strm<<" (" <<m_whichIs<<")";return strm.str();}private: template<typename Ite1,typename Ite2>bool Check(Ite1 b1,Ite1 e1,Ite2 b2,Ite2 e2){size_t elem=0;bool result=true;Message ar;for(elem=0;b1!=e1&&b2!=e2;++b1,++b2,++elem){if(!internal::bkw::EqHelper<false>::Compare("","",*b1,*b2)){result=false;ar<<"\nMismatch in a position " <<elem<<": "<< ::iutest::internal::FormatForComparisonFailureMessage(*b1,*b2)<< " vs " << ::iutest::internal::FormatForComparisonFailureMessage(*b2,*b1);}}if(b1!=e1||b2!=e2){const size_t elem1=elem+::std::distance(b1,e1);const size_t elem2=elem+::std::distance(b2,e2);result=false;ar<<"\nMismatch element : " <<elem1<<" vs " <<elem2;}m_whichIs=ar.GetString();return result;}private: const T& m_expected;::std::string m_whichIs;};template<typename M,typename T>class PointwiseMatcher:public IMatcher{public: PointwiseMatcher(const M& matcher,const T& expected):m_matcher(matcher),m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){IUTEST_USING_BEGIN_END();if(Check(begin(m_expected),end(m_expected),begin(actual),end(actual))){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Pointwise: " <<m_matcher<<": " <<PrintToString(m_expected);strm<<" (" <<m_whichIs<<")";return strm.str();}private: template<typename Ite1,typename Ite2>bool Check(Ite1 b1,Ite1 e1,Ite2 b2,Ite2 e2){size_t elem=0;bool result=true;Message ar;for(elem=0;b1!=e1&&b2!=e2;++b1,++b2,++elem){const AssertionResult r=m_matcher(*b2,*b1);if(r.failed()){result=false;ar<<"\nMismatch in a position " <<elem<<": " <<r.message();}}if(b1!=e1||b2!=e2){const size_t elem1=elem+::std::distance(b1,e1);const size_t elem2=elem+::std::distance(b2,e2);result=false;ar<<"\nMismatch element : " <<elem1<<" vs " <<elem2;}m_whichIs=ar.GetString();return result;}private: M m_matcher;const T& m_expected;::std::string m_whichIs;};class IsEmptyMatcher:public IMatcher{public: template<typename U>AssertionResult operator()(const U& actual){if((actual).empty()){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{return "Is Empty";}};template<typename T>class SizeIsMatcher:public IMatcher{public: explicit SizeIsMatcher(const T& expected):m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){if(Check(actual)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Size is: " <<m_expected;return strm.str();}private: template<typename Container>bool Check(const Container& actual){return static_cast<bool>(CastToMatcher(m_expected)(actual.size()));}template<typename U,size_t SIZE>bool Check(const U(&)[SIZE]){return static_cast<bool>(CastToMatcher(m_expected)(SIZE));}private: T m_expected;};template<typename T>class AtMatcher:public IMatcher{public: AtMatcher(size_t index,const T& expected):m_index(index),m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){if(CastToMatcher(m_expected)(actual[m_index])){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"At " <<m_index<<": " <<m_expected;return strm.str();}private: size_t m_index;T m_expected;};template<typename T>class ElementsAreArrayMatcher:public IMatcher{public: template<typename It>ElementsAreArrayMatcher(It begin,It end,bool expected_elem_count=true):m_expected_elem_count(expected_elem_count){m_expected.insert(m_expected.end(),begin,end);}public: template<typename U>AssertionResult operator()(const U& actual){IUTEST_USING_BEGIN_END();return Check(begin(actual),end(actual));}public: ::std::string WhichIs()const II_CXX_O{return WhichIs(PrintToString(m_expected));}::std::string WhichIs(const ::std::string& msg)const{iu_global_format_stringstream strm;if(m_expected_elem_count){strm<<"ElementsAreArray: ";}else{strm<<"ElementsAreArrayForward: ";}strm<<msg;return strm.str();}private: template<typename Ite>AssertionResult Check(Ite actual_begin,Ite actual_end){const size_t actual_cnt=::std::distance(actual_begin,actual_end);const size_t expected_cnt=m_expected.size();if(actual_cnt<expected_cnt){iu_global_format_stringstream stream;stream<<"actual argument[" <<actual_cnt<<"] is less than " <<expected_cnt;return AssertionFailure()<<WhichIs(stream.str());}if(m_expected_elem_count&&actual_cnt>expected_cnt){iu_global_format_stringstream stream;stream<<"actual argument[" <<actual_cnt<<"] is greater than " <<expected_cnt;return AssertionFailure()<<WhichIs(stream.str());}Ite it_a=actual_begin;typename ::std::vector<T>::iterator it_e=m_expected.begin();for(int i=0;it_a!=actual_end&&it_e!=m_expected.end();++it_e,++it_a,++i){(void)i;if(*it_a!=*it_e){return AssertionFailure()<<WhichIs();}}return AssertionSuccess();}private: ::std::vector<T> m_expected;bool m_expected_elem_count;};
#if IUTEST_HAS_MATCHER_ELEMENTSARE
class ElementsAreMatcherBase:public IMatcher{protected: template<typename T,typename U>static AssertionResult Check(T& matchers,const U& actual){IUTEST_USING_BEGIN_END();return Check<0,tuples::tuple_size<T>::value-1>(begin(actual),end(actual),matchers);}template<int N,typename T>static ::std::string WhichIs(const T& matchers){::std::string str="ElementsAre: {";str+=WhichIs_<T,N,tuples::tuple_size<T>::value-1>(matchers);str+="}";return str;}private: template<int N,int LAST,typename Ite,typename M>static AssertionResult Check(Ite it,Ite end,M& matchers){const size_t cnt=::std::distance(it,end);if(cnt<LAST+1){return AssertionFailure()<<"ElementsAre: argument[" <<cnt<<"] is less than " <<LAST+1;}return CheckElem<N,LAST>(it,end,matchers);}template<int N,int LAST,typename Ite,typename M>static AssertionResult CheckElem(Ite it,Ite end,M& matchers,typename detail::enable_if<N==LAST,void>::type*& = detail::enabler::value){for(int index=N;it!=end;++it,++index){AssertionResult ar=CastToMatcher(tuples::get<N>(matchers))(*it);if(!ar){return AssertionFailure()<<WhichIsElem<N>(matchers,index);}}return AssertionSuccess();}template<int N,int LAST,typename Ite,typename M>static AssertionResult CheckElem(Ite it,Ite end,M& matchers,typename detail::disable_if<N==LAST,void>::type*& = detail::enabler::value){AssertionResult ar=CastToMatcher(tuples::get<N>(matchers))(*it);if(ar){return CheckElem<N+1,LAST>(++it,end,matchers);}return AssertionFailure()<<WhichIsElem<N>(matchers,N);}template<int N,typename T>static ::std::string WhichIsElem(const T& matchers,int index){iu_global_format_stringstream strm;strm<<"ElementsAre(" <<index<<"): " <<tuples::get<N>(matchers);return strm.str();}template<typename T,int N,int LAST>static ::std::string WhichIs_(const T& matchers,typename detail::enable_if<N==LAST,void>::type*& = detail::enabler::value){return StreamableToString(tuples::get<N>(matchers));}template<typename T,int N,int LAST>static ::std::string WhichIs_(const T& matchers,typename detail::disable_if<N==LAST,void>::type*& = detail::enabler::value){return StreamableToString(tuples::get<N>(matchers))+", " + WhichIs_<T,N+1,LAST>(matchers);}};
#if IUTEST_HAS_MATCHER_VARIADIC
template<typename ...T>class ElementsAreMatcher:public ElementsAreMatcherBase{public: explicit ElementsAreMatcher(T... t):m_matchers(t...){}public: template<typename U>AssertionResult operator()(const U& actual){return Check(m_matchers,actual);}::std::string WhichIs()const II_CXX_O{return ElementsAreMatcherBase::WhichIs<0>(m_matchers);}private: tuples::tuple<T...> m_matchers;};
#else
#define II_D_EA_MATCHER(n) template<IP_ENM_P(n,typename T)> class IP_CAT(ElementsAreMatcher,n):public ElementsAreMatcherBase{public: IP_CAT(ElementsAreMatcher,n)(IP_ENM_B_P(n,T,m)) : m_matchers(IP_ENM_P(n,m)){}template<typename U>AssertionResult operator()(const U& actual){return Check(m_matchers,actual);}::std::string WhichIs()const II_CXX_O{return ElementsAreMatcherBase::WhichIs<0>(m_matchers);}private: tuples::tuple<IP_ENM_P(n,T)> m_matchers;}
II_D_EA_MATCHER(1);II_D_EA_MATCHER(2);II_D_EA_MATCHER(3);II_D_EA_MATCHER(4);II_D_EA_MATCHER(5);II_D_EA_MATCHER(6);II_D_EA_MATCHER(7);II_D_EA_MATCHER(8);II_D_EA_MATCHER(9);II_D_EA_MATCHER(10);
#undef II_D_EA_MATCHER
#endif
#endif
template<typename F,typename T>class FieldMatcher:public IMatcher{public: FieldMatcher(const F& field,const T& expected):m_field(field),m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){if(Check(actual)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Field: " <<m_expected;return strm.str();}private:template<typename U>bool Check(const U& actual,typename detail::disable_if_t<detail::is_pointer<U> >::type*& = detail::enabler::value){return static_cast<bool>(CastToMatcher(m_expected)(actual.*m_field));}template<typename U>bool Check(const U& actual,typename detail::enable_if_t<detail::is_pointer<U> >::type*& = detail::enabler::value){return static_cast<bool>(CastToMatcher(m_expected)(actual->*m_field));}private: const F& m_field;T m_expected;};template<typename F,typename T>class PropertyMatcher:public IMatcher{public: PropertyMatcher(const F& prop,const T& expected):m_property(prop),m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){if(Check(actual)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Property: " <<m_expected;return strm.str();}private:template<typename U>bool Check(const U& actual,typename detail::disable_if_t<detail::is_pointer<U> >::type*& = detail::enabler::value){return static_cast<bool>(CastToMatcher(m_expected)((actual.*m_property)()));}template<typename U>bool Check(const U& actual,typename detail::enable_if_t<detail::is_pointer<U> >::type*& = detail::enabler::value){return static_cast<bool>(CastToMatcher(m_expected)((actual->*m_property)()));}private: const F& m_property;T m_expected;};template<typename T>class KeyMatcher:public IMatcher{public: explicit KeyMatcher(const T& expected):m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual)const{if(CastToMatcher(m_expected)(actual.first)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Key: " <<m_expected;return strm.str();}private: const T& m_expected;};template<typename T1,typename T2>class PairMatcher:public IMatcher{public: PairMatcher(const T1& m1,const T2& m2):m_m1(m1),m_m2(m2){}public: template<typename U>AssertionResult operator()(const U& actual){if(!CheckElem(actual.first,m_m1)){return AssertionFailure()<<WhichIs();}if(!CheckElem(actual.second,m_m2)){return AssertionFailure()<<WhichIs();}return AssertionSuccess();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Pair: (" <<m_m1<<", " <<m_m2<<")";return strm.str();}private: template<typename T,typename U>bool CheckElem(const T& actual,U& matcher){return static_cast<bool>(CastToMatcher(matcher)(actual));}private: T1 m_m1;T2 m_m2;};template<typename F,typename T>class ResultOfMatcher:public IMatcher{public: ResultOfMatcher(F& func,const T& expected):m_func(func),m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){if(Check(actual)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Result of: " <<m_expected;return strm.str();}private: template<typename U>bool Check(const U& actual){return static_cast<bool>(CastToMatcher(m_expected)((*m_func)(actual)));}private: F& m_func;T m_expected;};template<typename T>class PointeeMatcher:public IMatcher{public: explicit PointeeMatcher(const T& expected):m_expected(expected){}public: template<typename U>AssertionResult operator()(const U& actual){if(Check(actual)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Points To: " <<m_expected;return strm.str();}private: template<typename U>bool Check(const U& actual){return static_cast<bool>(CastToMatcher(m_expected)(*actual));}private: T m_expected;};template<typename T>class NotMatcher:public IMatcher{public: explicit NotMatcher(const T& unexpected):m_unexpected(unexpected){}public: template<typename U>AssertionResult operator()(const U& actual){if(!CastToMatcher(m_unexpected)(actual)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"Not: (" <<m_unexpected<<")";return strm.str();}private: T m_unexpected;};template<typename T>class AnyMatcher:public IMatcher{public: AssertionResult operator()(const T&)const{return AssertionSuccess();}template<typename U>AssertionResult operator()(const U&)const;public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;strm<<"A: " <<detail::GetTypeNameProxy<T>::GetTypeName();return strm.str();}};class AnythingMatcher:public IMatcher{public: AnythingMatcher(){}public: template<typename U>AssertionResult operator()(const U&)const{return AssertionSuccess();}public: ::std::string WhichIs()const II_CXX_O{return "_";}};
#if IUTEST_HAS_MATCHER_REGEX
class RegexMatcher:public IMatcher{public: RegexMatcher(const detail::iuRegex& expected,bool full_match):m_expected(expected),m_full_match(full_match){}public: template<typename U>AssertionResult operator()(const U& actual)const{if(Regex(actual)){return AssertionSuccess();}return AssertionFailure()<<WhichIs();}public: ::std::string WhichIs()const II_CXX_O{iu_global_format_stringstream strm;if(m_full_match){strm<<"MatchesRegex: " <<m_expected.pattern();}else{strm<<"ContainsRegex: " <<m_expected.pattern();}return strm.str();}private: bool Regex(const char* actual)const{return m_full_match?m_expected.FullMatch(actual):m_expected.PartialMatch(actual);}bool Regex(const ::std::string& actual)const{return m_full_match?m_expected.FullMatch(actual.c_str()):m_expected.PartialMatch(actual.c_str());}private: detail::iuRegex m_expected;bool m_full_match;};
#endif
#if IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF
class AllOfMatcherBase:public IMatcher{protected: template<typename T,typename U>static AssertionResult Check(T& matchers,const U& actual){return Check_<T,U,0,tuples::tuple_size<T>::value-1>(matchers,actual);}template<int N,typename T>static ::std::string WhichIs(const T& matchers){return WhichIs_<T,N,tuples::tuple_size<T>::value-1>(matchers);}private: template<typename T,typename U,int N,int LAST>static AssertionResult Check_(T& matchers,const U& actual,typename detail::enable_if<N==LAST,void>::type*& = detail::enabler::value){AssertionResult ar=tuples::get<N>(matchers)(actual);if(ar){return ar;}return AssertionFailure()<<WhichIs_<T,0,N>(matchers);}template<typename T,typename U,int N,int LAST>static AssertionResult Check_(T& matchers,const U& actual,typename detail::disable_if<N==LAST,void>::type*& = detail::enabler::value){AssertionResult ar=tuples::get<N>(matchers)(actual);if(ar){return Check_<T,U,N+1,LAST>(matchers,actual);}return AssertionFailure()<<WhichIs_<T,0,N>(matchers);}template<typename T,int N,int LAST>static ::std::string WhichIs_(const T& matchers,typename detail::enable_if<N==LAST,void>::type*& = detail::enabler::value){return tuples::get<N>(matchers).WhichIs();}template<typename T,int N,int LAST>static ::std::string WhichIs_(const T& matchers,typename detail::disable_if<N==LAST,void>::type*& = detail::enabler::value){return tuples::get<N>(matchers).WhichIs()+" and " + WhichIs_<T,N+1,LAST>(matchers);}};
#if IUTEST_HAS_MATCHER_VARIADIC
template<typename ...T>class AllOfMatcher:public AllOfMatcherBase{public: explicit AllOfMatcher(T... t):m_matchers(t...){}public: template<typename U>AssertionResult operator()(const U& actual){return Check(m_matchers,actual);}::std::string WhichIs()const II_CXX_O{return AllOfMatcherBase::WhichIs<0>(m_matchers);}private: tuples::tuple<T...> m_matchers;};
#else
#define II_D_ALL_M(n) template<IP_ENM_P(n,typename T)> class IP_CAT(AllOfMatcher,n):public AllOfMatcherBase{public: IP_CAT(AllOfMatcher,n)(IP_ENM_B_P(n,T,m)) : m_matchers(IP_ENM_P(n,m)){}template<typename U>AssertionResult operator()(const U& actual){return Check(m_matchers,actual);}::std::string WhichIs()const II_CXX_O{return AllOfMatcherBase::WhichIs<0>(m_matchers);}private: tuples::tuple<IP_ENM_P(n,T)> m_matchers;}
II_D_ALL_M(2);II_D_ALL_M(3);II_D_ALL_M(4);II_D_ALL_M(5);II_D_ALL_M(6);II_D_ALL_M(7);II_D_ALL_M(8);II_D_ALL_M(9);II_D_ALL_M(10);
#undef II_D_ALL_M
#endif
class AnyOfMatcherBase:public IMatcher{protected: template<typename T,typename U>static AssertionResult Check(T& matchers,const U& actual){return Check_<T,U,0,tuples::tuple_size<T>::value-1>(matchers,actual);}template<int N,typename T>static ::std::string WhichIs(const T& matchers){return WhichIs_<T,N,tuples::tuple_size<T>::value-1>(matchers);}private: template<typename T,typename U,int N,int LAST>static AssertionResult Check_(T& matchers,const U& actual,typename detail::enable_if<N==LAST,void>::type*& = detail::enabler::value){AssertionResult ar=tuples::get<N>(matchers)(actual);if(ar){return ar;}return AssertionFailure()<<WhichIs_<T,0,N>(matchers);}template<typename T,typename U,int N,int LAST>static AssertionResult Check_(T& matchers,const U& actual,typename detail::disable_if<N==LAST,void>::type*& = detail::enabler::value){AssertionResult ar=tuples::get<N>(matchers)(actual);if(ar){return ar;}return Check_<T,U,N+1,LAST>(matchers,actual);}template<typename T,int N,int LAST>static ::std::string WhichIs_(const T& matchers,typename detail::enable_if<N==LAST,void>::type*& = detail::enabler::value){return tuples::get<N>(matchers).WhichIs();}template<typename T,int N,int LAST>static ::std::string WhichIs_(const T& matchers,typename detail::disable_if<N==LAST,void>::type*& = detail::enabler::value){return tuples::get<N>(matchers).WhichIs()+" or " + WhichIs_<T,N+1,LAST>(matchers);}};
#if IUTEST_HAS_MATCHER_VARIADIC
template<typename ...T>class AnyOfMatcher:public AnyOfMatcherBase{public: explicit AnyOfMatcher(T... t):m_matchers(t...){}public: template<typename U>AssertionResult operator()(const U& actual){return Check(m_matchers,actual);}::std::string WhichIs()const II_CXX_O{return AnyOfMatcherBase::WhichIs<0>(m_matchers);}private: tuples::tuple<T...> m_matchers;};
#else
#define II_D_ANY_M(n) template<IP_ENM_P(n,typename T)> class IP_CAT(AnyOfMatcher,n):public AnyOfMatcherBase{public: IP_CAT(AnyOfMatcher,n)(IP_ENM_B_P(n,T,m)) : m_matchers(IP_ENM_P(n,m)){}template<typename U>AssertionResult operator()(const U& actual){return Check(m_matchers,actual);}::std::string WhichIs()const II_CXX_O{return AnyOfMatcherBase::WhichIs<0>(m_matchers);}private: tuples::tuple<IP_ENM_P(n,T)> m_matchers;}
II_D_ANY_M(2);II_D_ANY_M(3);II_D_ANY_M(4);II_D_ANY_M(5);II_D_ANY_M(6);II_D_ANY_M(7);II_D_ANY_M(8);II_D_ANY_M(9);II_D_ANY_M(10);
#undef II_D_ANY_M
#endif
#endif
II_PGM_A_O_CN_G_W_D_E()}namespace matchers{template<typename T>detail::EqMatcher<T> Equals(const T& expected){return detail::EqMatcher<T>(expected);}template<typename T>detail::EqMatcher<T> Eq(const T& expected){return detail::EqMatcher<T>(expected);}template<typename T>detail::NeMatcher<T> Ne(const T& expected){return detail::NeMatcher<T>(expected);}template<typename T>detail::LeMatcher<T> Le(const T& expected){return detail::LeMatcher<T>(expected);}template<typename T>detail::LtMatcher<T> Lt(const T& expected){return detail::LtMatcher<T>(expected);}template<typename T>detail::GeMatcher<T> Ge(const T& expected){return detail::GeMatcher<T>(expected);}template<typename T>detail::GtMatcher<T> Gt(const T& expected){return detail::GtMatcher<T>(expected);}inline detail::TwofoldEqMatcher Eq(){return detail::TwofoldEqMatcher();}inline detail::TwofoldNeMatcher Ne(){return detail::TwofoldNeMatcher();}inline detail::TwofoldLeMatcher Le(){return detail::TwofoldLeMatcher();}inline detail::TwofoldLtMatcher Lt(){return detail::TwofoldLtMatcher();}inline detail::TwofoldGeMatcher Ge(){return detail::TwofoldGeMatcher();}inline detail::TwofoldGtMatcher Gt(){return detail::TwofoldGtMatcher();}inline detail::IsNullMatcher IsNull(){return detail::IsNullMatcher();}inline detail::NotNullMatcher NotNull(){return detail::NotNullMatcher();}template<typename T,typename U>detail::TypedEqMatcher<T> TypedEq(const U& expected){return detail::TypedEqMatcher<T>(static_cast<T>(expected));}template<typename T>inline detail::FloatingPointEqMatcher<T> FloatingPointEq(T expected){return detail::FloatingPointEqMatcher<T>(expected);}inline detail::FloatingPointEqMatcher<float> FloatEq(float expected){return detail::FloatingPointEqMatcher<float>(expected);}inline detail::FloatingPointEqMatcher<double> DoubleEq(double expected){return detail::FloatingPointEqMatcher<double>(expected);}
#if IUTEST_HAS_LONG_DOUBLE
inline detail::FloatingPointEqMatcher<long double> LongDoubleEq(long double expected){return detail::FloatingPointEqMatcher<long double>(expected);}
#endif
template<typename T>inline detail::NanSensitiveFloatingPointEqMatcher<T> NanSensitiveFloatingPointEq(T expected){return detail::NanSensitiveFloatingPointEqMatcher<T>(expected);}inline detail::NanSensitiveFloatingPointEqMatcher<float> NanSensitiveFloatEq(float expected){return detail::NanSensitiveFloatingPointEqMatcher<float>(expected);}inline detail::NanSensitiveFloatingPointEqMatcher<double> NanSensitiveDoubleEq(double expected){return detail::NanSensitiveFloatingPointEqMatcher<double>(expected);}
#if IUTEST_HAS_LONG_DOUBLE
inline detail::NanSensitiveFloatingPointEqMatcher<long double> NanSensitiveLongDoubleEq(long double expected){return detail::NanSensitiveFloatingPointEqMatcher<long double>(expected);}
#endif
template<typename T>inline detail::FloatingPointNearMatcher<T> FloatingPointNear(T expected,T max_abs_error){return detail::FloatingPointNearMatcher<T>(expected,max_abs_error);}inline detail::FloatingPointNearMatcher<float> FloatNear(float expected,float max_abs_error){return detail::FloatingPointNearMatcher<float>(expected,max_abs_error);}inline detail::FloatingPointNearMatcher<double> DoubleNear(double expected,double max_abs_error){return detail::FloatingPointNearMatcher<double>(expected,max_abs_error);}
#if IUTEST_HAS_LONG_DOUBLE
inline detail::FloatingPointNearMatcher<long double> LongDoubleNear(long double expected,long double max_abs_error){return detail::FloatingPointNearMatcher<long double>(expected,max_abs_error);}
#endif
template<typename T>inline detail::NanSensitiveFloatingPointNearMatcher<T> NanSensitiveFloatingPointNear(T expected,T max_abs_error){return detail::NanSensitiveFloatingPointNearMatcher<T>(expected,max_abs_error);}inline detail::NanSensitiveFloatingPointNearMatcher<float> NanSensitiveFloatNear(float expected,float max_abs_error){return detail::NanSensitiveFloatingPointNearMatcher<float>(expected,max_abs_error);}inline detail::NanSensitiveFloatingPointNearMatcher<double> NanSensitiveDoubleNear(double expected,double max_abs_error){return detail::NanSensitiveFloatingPointNearMatcher<double>(expected,max_abs_error);}
#if IUTEST_HAS_LONG_DOUBLE
inline detail::NanSensitiveFloatingPointNearMatcher<long double> NanSensitiveLongDoubleNear(long double expected,long double max_abs_error){return detail::NanSensitiveFloatingPointNearMatcher<long double>(expected,max_abs_error);}
#endif
template<typename T>detail::StrEqMatcher<T> StrEq(const T& expected){return detail::StrEqMatcher<T>(expected);}template<typename T>detail::StrNeMatcher<T> StrNe(const T& expected){return detail::StrNeMatcher<T>(expected);}template<typename T>detail::StrCaseEqMatcher<T> StrCaseEq(const T& expected){return detail::StrCaseEqMatcher<T>(expected);}template<typename T>detail::StrCaseNeMatcher<T> StrCaseNe(const T& expected){return detail::StrCaseNeMatcher<T>(expected);}template<typename T>detail::StartsWithMatcher<const T&> StartsWith(const T& str){return detail::StartsWithMatcher<const T&>(str);}template<typename T>detail::HasSubstrMatcher<const T&> HasSubstr(const T& str){return detail::HasSubstrMatcher<const T&>(str);}template<typename T>detail::EndsWithMatcher<const T&> EndsWith(const T& str){return detail::EndsWithMatcher<const T&>(str);}template<typename T>detail::ContainsMatcher<T> Contains(const T& expected){return detail::ContainsMatcher<T>(expected);}template<typename T>detail::EachMatcher<T> Each(const T& expected){return detail::EachMatcher<T>(expected);}template<typename T>detail::ContainerEqMatcher<T> ContainerEq(const T& expected){return detail::ContainerEqMatcher<T>(expected);}template<typename M,typename T>detail::PointwiseMatcher<M,T> Pointwise(const M& matcher,const T& expected){return detail::PointwiseMatcher<M,T>(matcher,expected);}inline detail::IsEmptyMatcher IsEmpty(){return detail::IsEmptyMatcher();}template<typename T>detail::SizeIsMatcher<T> SizeIs(const T& expected){return detail::SizeIsMatcher<T>(expected);}template<typename T>detail::AtMatcher<T> At(size_t index,const T& expected){return detail::AtMatcher<T>(index,expected);}template<typename Container>detail::ElementsAreArrayMatcher<typename Container::value_type>ElementsAreArray(const Container& container){IUTEST_USING_BEGIN_END();return detail::ElementsAreArrayMatcher<typename Container::value_type>(container.begin(),container.end());}template<typename T,size_t SIZE>detail::ElementsAreArrayMatcher<T> ElementsAreArray(const T(&v)[SIZE]){return detail::ElementsAreArrayMatcher<T>(v,v+SIZE);}template<typename Ite>detail::ElementsAreArrayMatcher<typename detail::IteratorTraits<Ite>::type>ElementsAreArray(Ite begin,Ite end){return detail::ElementsAreArrayMatcher<typename detail::IteratorTraits<Ite>::type >(begin,end);}
#if IUTEST_HAS_INITIALIZER_LIST
template<typename T>detail::ElementsAreArrayMatcher<T> ElementsAreArray(::std::initializer_list<T> l){return detail::ElementsAreArrayMatcher<T>(l.begin(),l.end());}
#endif
template<typename T>detail::ElementsAreArrayMatcher<T> ElementsAreArray(const T* a,int count){return detail::ElementsAreArrayMatcher<T>(a,a+count);}
#if IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD
template<typename Container>detail::ElementsAreArrayMatcher<typename Container::value_type>ElementsAreArrayForward(const Container& container){return detail::ElementsAreArrayMatcher<typename Container::value_type>(container.begin(),container.end(),false);}template<typename T,size_t SIZE>detail::ElementsAreArrayMatcher<T> ElementsAreArrayForward(const T(&v)[SIZE]){return detail::ElementsAreArrayMatcher<T>(v,v+SIZE,false);}template<typename Ite>detail::ElementsAreArrayMatcher<typename detail::IteratorTraits<Ite>::type>ElementsAreArrayForward(Ite begin,Ite end){return detail::ElementsAreArrayMatcher<typename detail::IteratorTraits<Ite>::type >(begin,end,false);}
#if IUTEST_HAS_INITIALIZER_LIST
template<typename T>detail::ElementsAreArrayMatcher<T> ElementsAreArrayForward(::std::initializer_list<T> l){return detail::ElementsAreArrayMatcher<T>(l.begin(),l.end(),false);}
#endif
template<typename T>detail::ElementsAreArrayMatcher<T> ElementsAreArrayForward(const T* a,int count){return detail::ElementsAreArrayMatcher<T>(a,a+count,false);}
#endif
#if IUTEST_HAS_MATCHER_ELEMENTSARE
#if IUTEST_HAS_MATCHER_VARIADIC
template<typename ...T>detail::ElementsAreMatcher<T...> ElementsAre(const T&... m){return detail::ElementsAreMatcher<T...>(m...);}
#else
#define II_EA_M_N(n) IP_CAT(ElementsAreMatcher,n)
#define II_D_EA(n) template<IP_ENM_P(n,typename T)> detail:: II_EA_M_N(n)<IP_ENM_P(n,T)> ElementsAre(IP_ENM_B_P(n,const T,&m)){return detail:: II_EA_M_N(n)<IP_ENM_P(n,T)> (IP_ENM_P(n,m));}
II_D_EA(1)II_D_EA(2)II_D_EA(3)II_D_EA(4)II_D_EA(5)II_D_EA(6)II_D_EA(7)II_D_EA(8)II_D_EA(9)II_D_EA(10)
#undef II_EA_M_N
#undef II_D_EA
#endif
#endif
template<typename T>detail::KeyMatcher<T> Key(const T& expected){return detail::KeyMatcher<T>(expected);}template<typename T1,typename T2>detail::PairMatcher<T1,T2> Pair(const T1& m1,const T2& m2){return detail::PairMatcher<T1,T2>(m1,m2);}template<typename F,typename T>detail::FieldMatcher<F,T> Field(const F& field,const T& expected){return detail::FieldMatcher<F,T>(field,expected);}template<typename P,typename T>detail::PropertyMatcher<P,T> Property(const P& prop,const T& expected){return detail::PropertyMatcher<P,T>(prop,expected);}template<typename F,typename T>detail::ResultOfMatcher<F,T> ResultOf(const F& func,const T& expected){return detail::ResultOfMatcher<F,T>(func,expected);}template<typename T>detail::PointeeMatcher<T> Pointee(const T& expected){return detail::PointeeMatcher<T>(expected);}template<typename T>detail::NotMatcher<T> Not(const T& unexpected){return detail::NotMatcher<T>(unexpected);}template<typename T>detail::AnyMatcher<T> A(){return detail::AnyMatcher<T>();}const detail::AnythingMatcher _;
#if IUTEST_HAS_MATCHER_REGEX
inline detail::RegexMatcher MatchesRegex(const ::std::string& str){return detail::RegexMatcher(detail::iuRegex(str),true);}inline detail::RegexMatcher ContainsRegex(const ::std::string& str){return detail::RegexMatcher(detail::iuRegex(str),false);}
#endif
#if IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF
#if IUTEST_HAS_MATCHER_VARIADIC
template<typename ...T>detail::AllOfMatcher<T...> AllOf(const T&... m){return detail::AllOfMatcher<T...>(m...);}template<typename ...T>detail::AnyOfMatcher<T...> AnyOf(const T&... m){return detail::AnyOfMatcher<T...>(m...);}
#else
#define II_AAA_M_N(name,n) IP_CAT(IP_CAT(name,Matcher),n)
#define II_D_AAA(name,n) template<IP_ENM_P(n,typename T)> detail:: II_AAA_M_N(name,n)<IP_ENM_P(n,T)> name(IP_ENM_B_P(n,const T,&m)){return detail:: II_AAA_M_N(name,n)<IP_ENM_P(n,T)> (IP_ENM_P(n,m));}
II_D_AAA(AllOf,2)II_D_AAA(AllOf,3)II_D_AAA(AllOf,4)II_D_AAA(AllOf,5)II_D_AAA(AllOf,6)II_D_AAA(AllOf,7)II_D_AAA(AllOf,8)II_D_AAA(AllOf,9)II_D_AAA(AllOf,10)II_D_AAA(AnyOf,2)II_D_AAA(AnyOf,3)II_D_AAA(AnyOf,4)II_D_AAA(AnyOf,5)II_D_AAA(AnyOf,6)II_D_AAA(AnyOf,7)II_D_AAA(AnyOf,8)II_D_AAA(AnyOf,9)II_D_AAA(AnyOf,10)
#undef II_AAA_M_N
#undef II_D_AAA
#endif
#endif
template<typename T,typename M>bool Value(const T& value,const M& expected){return static_cast<bool>(detail::CastToMatcher(expected)(value));}}using namespace matchers;}
#define StaticAssertTypeEq detail::StaticAssertTypeEqHelper
#if IUTEST_HAS_STATIC_ASSERT
#if (__GNUC__<4||(__GNUC__==4&&__GNUC_MINOR__<8))
#define IUTEST_STATIC_ASSERT_MSG(B,Msg) static_assert(B,"static_assert: " Msg)
#else
#define IUTEST_STATIC_ASSERT_MSG(B,Msg) static_assert(B,Msg)
#endif
#else
#define II_STATIC_ASSERT_SIZECHECK(B) sizeof(::iutest::detail::static_assert_failure<(bool)(B)>)
#define IUTEST_STATIC_ASSERT_MSG(B,Msg) typedef ::iutest::detail::StaticAssertionTest<II_STATIC_ASSERT_SIZECHECK(B)> IP_CAT(iutest_static_assert_typedef_,IUTEST_PP_COUNTER) II_ATR_U
#endif
#ifdef IUTEST_STATIC_ASSERT_MSG
#define IUTEST_STATIC_ASSERT(...) IUTEST_STATIC_ASSERT_MSG((__VA_ARGS__),#__VA_ARGS__)
#endif
namespace iutest{namespace detail{template<typename T1,typename T2>struct StaticAssertTypeEqHelper;namespace helper{template<bool b>struct static_assert_typeeq;template<>struct static_assert_typeeq<true>{operator bool()const{return true;}};}template<typename T1,typename T2>struct StaticAssertTypeEqHelper: public helper::static_assert_typeeq<iutest_type_traits::is_same<T1,T2>::value >{};template<bool b>struct static_assert_failure;template<> struct static_assert_failure<true>{enum{value=1};};template<int x>struct StaticAssertionTest{};}}namespace iutest{class DefaultResultPrintListener:public TestEventListener{public: DefaultResultPrintListener(){}virtual ~DefaultResultPrintListener(){TestEnv::event_listeners().set_default_result_printer(0);}public: virtual void OnTestProgramStart(const UnitTest& test) II_CXX_O;virtual void OnTestIterationStart(const UnitTest& test,int iteration) II_CXX_O;virtual void OnEnvironmentsSetUpStart(const UnitTest& test) II_CXX_O;virtual void OnEnvironmentsSetUpEnd(const UnitTest& test) II_CXX_O;virtual void OnTestCaseStart(const TestCase& test_case) II_CXX_O;virtual void OnTestStart(const TestInfo& test_info) II_CXX_O;virtual void OnTestPartResult(const TestPartResult& test_part_result) II_CXX_O;virtual void OnTestRecordProperty(const TestProperty& test_property) II_CXX_O;virtual void OnTestEnd(const TestInfo& test_info) II_CXX_O;virtual void OnTestCaseEnd(const TestCase& test_case) II_CXX_O;virtual void OnEnvironmentsTearDownStart(const UnitTest& test) II_CXX_O;virtual void OnEnvironmentsTearDownEnd(const UnitTest& test) II_CXX_O;virtual void OnTestIterationEnd(const UnitTest& test,int iteration) II_CXX_O;virtual void OnTestProgramEnd(const UnitTest& test) II_CXX_O;private: void PrintTestResult(const TestInfo& test_info)const;};}namespace iutest{inline void DefaultResultPrintListener::OnTestProgramStart(const UnitTest& test){(void)(test);if(TestFlag::IsEnableFlag(TestFlag::FILTERING_TESTS)){detail::iuConsole::color_output(detail::iuConsole::yellow,"Note: iutest filter = %s\n",TestEnv::test_filter());}}inline void DefaultResultPrintListener::OnTestIterationStart(const UnitTest& test,int iteration){if(test.repeat_count()!=1){detail::iuConsole::output("\nRepeating all tests (iteration %d) . . .\n\n",iteration+1);}if(TestFlag::IsEnableFlag(TestFlag::SHUFFLE_TESTS)){detail::iuConsole::color_output(detail::iuConsole::yellow,"Note: Randomizing tests' orders with a seed of %u\n",test.random_seed());}detail::iuConsole::color_output(detail::iuConsole::green,"[==========] ");detail::iuConsole::output("Running %d tests from %d test cases.\n",test.test_to_run_count(),test.test_case_to_run_count());}inline void DefaultResultPrintListener::OnEnvironmentsSetUpStart(const UnitTest& test){(void)(test);detail::iuConsole::color_output(detail::iuConsole::green,"[----------] ");detail::iuConsole::output("Global test environment set-up.\n");}inline void DefaultResultPrintListener::OnEnvironmentsSetUpEnd(const UnitTest& test){(void)(test);}inline void DefaultResultPrintListener::OnTestCaseStart(const TestCase& test_case){detail::iuConsole::color_output(detail::iuConsole::green,"[----------] ");detail::iuConsole::output("%d tests from %s\n",test_case.test_to_run_count(),test_case.t_c_name_with_where().c_str());}inline void DefaultResultPrintListener::OnTestStart(const TestInfo& test_info){detail::iuConsole::color_output(detail::iuConsole::green,"[ RUN      ] ");detail::iuConsole::output("%s.%s\n",test_info.test_case_name(),test_info.name());}inline void DefaultResultPrintListener::OnTestPartResult(const TestPartResult& test_part_result){const std::string msg=test_part_result.make_newline_message();;detail::iuConsole::output("%s",msg.c_str());}inline void DefaultResultPrintListener::OnTestRecordProperty(const TestProperty& test_property){detail::iuConsole::output("iutest record property:\n  %s=%s\n",test_property.key(),test_property.value());}inline void DefaultResultPrintListener::PrintTestResult(const TestInfo& test_info)const{if(test_info.HasFailure()){detail::iuConsole::color_output(detail::iuConsole::red,"[  FAILED  ] ");detail::iuConsole::output("%s.%s",test_info.test_case_name(),test_info.test_name_with_where().c_str());return;}if(test_info.is_skipped()){detail::iuConsole::color_output(detail::iuConsole::yellow,"[  SKIPPED ] ");detail::iuConsole::output("%s.%s",test_info.test_case_name(),test_info.name());return;}detail::iuConsole::color_output(detail::iuConsole::green,"[       OK ] ");detail::iuConsole::output("%s.%s",test_info.test_case_name(),test_info.name());}inline void DefaultResultPrintListener::OnTestEnd(const TestInfo& test_info){PrintTestResult(test_info);if(TestFlag::IsEnableFlag(TestFlag::PRINT_TIME)){detail::iuConsole::output(" (%sms)",detail::FormatTimeInMillisec(test_info.elapsed_time()).c_str());}detail::iuConsole::output("\n");}inline void DefaultResultPrintListener::OnTestCaseEnd(const TestCase& test_case){detail::iuConsole::color_output(detail::iuConsole::green,"[----------] ");detail::iuConsole::output("%d tests from %s",test_case.test_to_run_count(),test_case.name());if(TestFlag::IsEnableFlag(TestFlag::PRINT_TIME)){detail::iuConsole::output("(%sms total)",detail::FormatTimeInMillisec(test_case.elapsed_time()).c_str());}detail::iuConsole::output("\n\n");}inline void DefaultResultPrintListener::OnEnvironmentsTearDownStart(const UnitTest& test){(void)(test);detail::iuConsole::color_output(detail::iuConsole::green,"[----------] ");detail::iuConsole::output("Global test environment tear-down.\n");}inline void DefaultResultPrintListener::OnEnvironmentsTearDownEnd(const UnitTest& test){(void)(test);}inline void DefaultResultPrintListener::OnTestIterationEnd(const UnitTest& test,int iteration){(void)(iteration);detail::iuConsole::color_output(detail::iuConsole::green,"[==========] ");detail::iuConsole::output("%d tests from %d testcase ran.",test.test_to_run_count(),test.test_case_to_run_count());if(TestFlag::IsEnableFlag(TestFlag::PRINT_TIME)){detail::iuConsole::output(" (%sms total)",detail::FormatTimeInMillisec(test.elapsed_time()).c_str());}detail::iuConsole::output("\n");{{detail::iuConsole::color_output(detail::iuConsole::green,"[  PASSED  ] ");detail::iuConsole::output("%d tests.\n",test.successful_test_count());}{const int count=test.reportable_disabled_test_count();if(!TestFlag::IsEnableFlag(TestFlag::RUN_DISABLED_TESTS)&&count>0){detail::iuConsole::color_output(detail::iuConsole::yellow,"[ DISABLED ] ");detail::iuConsole::output("%d tests.\n",count);if(TestFlag::IsEnableFlag(TestFlag::VERBOSE)){for(int i=0,case_count=test.total_test_case_count();i<case_count;++i){const TestCase* testcase=test.GetTestCase(i);for(int j=0,info_count=testcase->total_test_count();j<info_count;++j){const TestInfo* testinfo=testcase->GetTestInfo(j);if(testinfo->is_disabled_test()){detail::iuConsole::color_output(detail::iuConsole::yellow,"[ DISABLED ] ");detail::iuConsole::output("%s.%s\n",testinfo->test_case_name(),testinfo->name());}}}}}}{const int count=test.reportable_test_run_skipped_count();if(count>0){detail::iuConsole::color_output(detail::iuConsole::yellow,"[  SKIPPED ] ");detail::iuConsole::output("%d tests.\n",count);if(TestFlag::IsEnableFlag(TestFlag::VERBOSE)){for(int i=0,case_count=test.total_test_case_count();i<case_count;++i){const TestCase* testcase=test.GetTestCase(i);for(int j=0,info_count=testcase->total_test_count();j<info_count;++j){const TestInfo* testinfo=testcase->GetTestInfo(j);if(testinfo->is_skipped()){detail::iuConsole::color_output(detail::iuConsole::yellow,"[  SKIPPED ] ");detail::iuConsole::output("%s.%s\n",testinfo->test_case_name(),testinfo->name());}}}}}}if(!test.Passed()){const int failed_num=test.failed_test_count();detail::iuConsole::color_output(detail::iuConsole::red,"[  FAILED  ] ");detail::iuConsole::output("%d %s, listed below:\n",failed_num,failed_num==1 ? "test" : "tests");for(int i=0,count=test.total_test_case_count();i<count;++i){const TestCase* testcase=test.GetTestCase(i);for(int j=0,info_count=testcase->total_test_count();j<info_count;++j){const TestInfo* testinfo=testcase->GetTestInfo(j);if(testinfo->HasFailure()){detail::iuConsole::color_output(detail::iuConsole::red,"[  FAILED  ] ");detail::iuConsole::output("%s.%s\n",testinfo->test_case_name(),testinfo->name());}}if(testcase->ad_hoc_test_result()->Failed()){detail::iuConsole::color_output(detail::iuConsole::red,"[  FAILED  ] ");detail::iuConsole::output("%s at SetUpTestCase/TearDownTestCase\n",testcase->name());}}if(test.ad_hoc_test_result()->Failed()){detail::iuConsole::color_output(detail::iuConsole::red,"[  FAILED  ] ");detail::iuConsole::output("other than\n");}detail::iuConsole::output("\n%d FAILED %s.\n",failed_num,failed_num==1 ? "TEST" : "TESTS");}}}inline void DefaultResultPrintListener::OnTestProgramEnd(const UnitTest& test){(void)(test);}}namespace iutest{class DefaultXmlGeneratorListener:public EmptyTestEventListener{::std::string m_output_path_format;::std::string m_output_path;protected: IFile* m_fp;public: explicit DefaultXmlGeneratorListener(const ::std::string& path):m_fp(0){SetFilePath(path);}virtual ~DefaultXmlGeneratorListener(){FileClose();TestEnv::event_listeners().set_default_xml_generator(0);}public: const ::std::string& GetFilePath()const{return m_output_path;}private: void SetFilePath(const ::std::string& path){if(path.empty()){m_output_path_format.clear();m_output_path=detail::kStrings::DefaultXmlReportFileName;}else{m_output_path_format=path;const ::std::string::size_type pos=path.find('.');if(pos==::std::string::npos|| pos==path.length()-1){m_output_path_format+=detail::GetPathSeparator();m_output_path_format+=detail::kStrings::DefaultXmlReportFileName;}m_output_path=m_output_path_format;}}public: virtual void OnTestIterationStart(const UnitTest& test,int iteration) II_CXX_O;virtual void OnTestProgramEnd(const UnitTest& test) II_CXX_O;private: virtual bool IsReportable(const UnitTest& test){(void)(test);return true;}virtual void OnReportTest(IFile* file,const UnitTest& test);private: static void OnReportTestCase(IFile* file,const TestCase& test_case);static void OnReportTestInfo(IFile* file,const TestInfo& test_info);static void OnReportTestProperty(IFile* file,const TestResult& test_result,bool(*pfnValidate)(const ::std::string&));static void OnReportTestSkipped(IFile* file,const TestInfo& test_info);private: virtual bool FileOpen(const char* path);virtual void FileClose();protected: static void OutputXmlCDataSection(IFile* file,const char* data);static void OutputXmlAttribute(IFile* file,const char* name,const char* value);protected: static ::std::string EscapeXmlAttribute(const char* str){return EscapeXml(str,true);}static ::std::string EscapeXmlAttribute(const ::std::string str){return EscapeXml(str.c_str(),true);}static ::std::string EscapeXmlText(const char* str){return EscapeXml(str,false);}static ::std::string EscapeXml(const char* str,bool is_attribute);static II_CXX_CE bool IsWhitespace(char c){return c==9||c==0xA||c==0xD;}static II_CXX_CE bool IsValidXmlCharacter(char c){return IsWhitespace(c)||c>=0x20;}public: static bool SetUp(){::std::string xmlpath=TestEnv::get_report_xml_filepath();if(!xmlpath.empty()){TestEnv::event_listeners().set_default_xml_generator(new DefaultXmlGeneratorListener(xmlpath));return true;}return false;}};}namespace iutest{inline void DefaultXmlGeneratorListener::OnTestIterationStart(const UnitTest& test,int iteration){if(!IsReportable(test)){return;}if(!m_output_path_format.empty()){m_output_path=m_output_path_format;::std::string strIte=detail::iu_to_string(iteration);detail::StringReplace(m_output_path,"%d",2,strIte.c_str());detail::StringReplace(m_output_path,"{I}",3,strIte.c_str());if(m_output_path==m_output_path_format){m_output_path_format.clear();}if(m_fp!=0){OnReportTest(m_fp,test);FileClose();}}if(m_fp==0){FileOpen(m_output_path.c_str());}}inline void DefaultXmlGeneratorListener::OnTestProgramEnd(const UnitTest& test){if(!IsReportable(test)){return;}if(m_fp==0){FileOpen(m_output_path.c_str());if(m_fp==0){return;}}OnReportTest(m_fp,test);FileClose();}inline void DefaultXmlGeneratorListener::OnReportTest(IFile* file,const UnitTest& test){file->Printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");file->Printf("<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" ",test.reportable_test_count(),test.failed_test_count(),test.reportable_disabled_test_count());file->Printf("skip=\"%d\" ",test.reportable_skip_test_count());file->Printf("errors=\"0\" time=\"%s\" timestamp=\"%s\" ",detail::FormatTimeInMillisecAsSecond(test.elapsed_time()).c_str(),detail::FormatTimeInMillisecAsIso8601(test.start_timestamp()).c_str());if(TestFlag::IsEnableFlag(TestFlag::SHUFFLE_TESTS)){file->Printf("random_seed=\"%d\" ",test.random_seed());}file->Printf("name=\"AllTests\"");OnReportTestProperty(file,*test.ad_hoc_test_result(),UnitTest::ValidateTestPropertyName);file->Printf(">\n");for(int i=0,count=test.total_test_case_count();i<count;++i){OnReportTestCase(file,*test.GetTestCase(i));}file->Printf("</testsuites>\n");}inline void DefaultXmlGeneratorListener::OnReportTestCase(IFile* file,const TestCase& test_case){if(test_case.reportable_test_count()<=0){return;}file->Printf("  <testsuite ");OutputXmlAttribute(file,"name",EscapeXmlAttribute(test_case.t_c_name_with_default_package_name()).c_str());file->Printf("tests=\"%d\" failures=\"%d\" disabled=\"%d\" ",test_case.reportable_test_count(),test_case.failed_test_count(),test_case.reportable_disabled_test_count());file->Printf("skip=\"%d\" ",test_case.reportable_skip_test_count());file->Printf("errors=\"0\" time=\"%s\" timestamp=\"%s\"",detail::FormatTimeInMillisecAsSecond(test_case.elapsed_time()).c_str(),detail::FormatTimeInMillisecAsIso8601(test_case.start_timestamp()).c_str());OnReportTestProperty(file,*test_case.ad_hoc_test_result(),TestCase::ValidateTestPropertyName);file->Printf(">\n");for(int i=0,count=test_case.total_test_count();i<count;++i){OnReportTestInfo(file,*test_case.GetTestInfo(i));}file->Printf("  </testsuite>\n");}inline void DefaultXmlGeneratorListener::OnReportTestInfo(IFile* file,const TestInfo& test_info){if(!test_info.is_reportable()){return;}file->Printf("    <testcase ");OutputXmlAttribute(file,"name",EscapeXmlAttribute(test_info.name()).c_str());{const char* type_param=test_info.type_param();if(type_param!=0){OutputXmlAttribute(file,"type_param",EscapeXmlAttribute(type_param).c_str());}}{const char* value_param=test_info.value_param();if(value_param!=0){OutputXmlAttribute(file,"value_param",EscapeXmlAttribute(value_param).c_str());}}if(test_info.is_ran()){file->Printf("status=\"run\" ");}else{file->Printf("status=\"notrun\" ");}file->Printf("time=\"%s\" ",detail::FormatTimeInMillisecAsSecond(test_info.elapsed_time()).c_str());OutputXmlAttribute(file,"classname",EscapeXmlAttribute(test_info.t_c_name_with_default_package_name()).c_str());OnReportTestProperty(file,*test_info.result(),TestInfo::ValidateTestPropertyName);const bool notrun=test_info.should_run()&&!test_info.is_ran();if(test_info.HasFailure()||notrun){file->Printf(">\n");for(int i=0,count=test_info.result()->total_part_count();i<count;++i){const TestPartResult& part=test_info.result()->GetTestPartResult(i);if(part.passed()){continue;}file->Printf("      <failure ");OutputXmlAttribute(file,"message",EscapeXmlAttribute(part.summary()).c_str());file->Printf("type=\"\">");::std::string message=detail::FormatCompilerIndependentFileLocation(part.file_name(),part.line_number());message+="\n";message+=detail::MultiByteStringToUTF8(part.summary());OutputXmlCDataSection(file,message.c_str());file->Printf("\n      </failure>\n");}if(notrun){file->Printf("      <failure message=\"Not Run\" type=\"\">");OutputXmlCDataSection(file,"Not Run");file->Printf("\n      </failure>\n");}file->Printf("    </testcase>\n");}else{const bool skipped=test_info.is_skipped()||!test_info.should_run();if(skipped){file->Printf(">\n");OnReportTestSkipped(file,test_info);file->Printf("    </testcase>\n");}else{file->Printf(" />\n");}}}inline void DefaultXmlGeneratorListener::OnReportTestSkipped(IFile* file,const TestInfo& test_info){file->Printf("      <skipped type=\"iutest.skip\" ");const TestResult* tr=test_info.result();const int count=tr->total_part_count();for(int i=0;i<count;++i){const TestPartResult& part=tr->GetTestPartResult(i);if(part.skipped()){::std::string message=detail::FormatCompilerIndependentFileLocation(part.file_name(),part.line_number());message+=": ";message+=detail::MultiByteStringToUTF8(part.summary());OutputXmlAttribute(file,"message",EscapeXmlAttribute(message.c_str()).c_str());file->Printf(" />\n");return;}}if(test_info.is_disabled_test()){OutputXmlAttribute(file,"message","disabled test.");}file->Printf("/>\n");}inline void DefaultXmlGeneratorListener::OnReportTestProperty(IFile* file,const TestResult& test_result,bool(*pfnValidate)(const ::std::string&)){for(int i=0,count=test_result.test_property_count();i<count;++i){const TestProperty& prop=test_result.GetTestProperty(i);if((*pfnValidate)(prop.key())){file->Printf(" %s=\"%s\"",EscapeXmlAttribute(prop.key()).c_str(),EscapeXmlAttribute(prop.value()).c_str());}}}inline bool DefaultXmlGeneratorListener::FileOpen(const char* path){m_fp=detail::IFileSystem::New();if(m_fp==0){return false;}if(!m_fp->Open(path,IFile::OpenWrite)){fprintf(stderr,"Unable to open file \"%s\".\n",m_output_path.c_str());fflush(stderr);detail::IFileSystem::Free(m_fp);m_fp=0;return false;}return true;}inline void DefaultXmlGeneratorListener::FileClose(){if(m_fp==0){return;}m_fp->Close();detail::IFileSystem::Free(m_fp);m_fp=0;}inline void DefaultXmlGeneratorListener::OutputXmlCDataSection(IFile* file,const char* data){file->Printf("<![CDATA[");file->Write(data,strlen(data),1);file->Printf("]]>");}inline void DefaultXmlGeneratorListener::OutputXmlAttribute(IFile* file,const char* name,const char* value){file->Printf("%s=\"",name);file->Write(value,strlen(value),1);file->Printf("\" ");}inline ::std::string DefaultXmlGeneratorListener::EscapeXml(const char* str,bool is_attribute){::std::string msg;if(str!=0){for(const char* src=str;*src;++src){const char s=*src;switch(s){case '<': msg+="&lt;";break;case '>': msg+="&gt;";break;case '&': msg+="&amp;";break;case '\'': msg+=is_attribute?"&apos;" : "\'";break;case '\"': msg+=is_attribute?"&quot;" : "\"";break;default: {wchar_t wc=0;const int len=detail::iu_mbtowc(&wc,src,MB_CUR_MAX);if(len>1){msg+=detail::AnyStringToUTF8(&wc,1);src+=len-1;}else if(IsValidXmlCharacter(s)){if(is_attribute&&IsWhitespace(s)){char tmp[8];detail::iu_snprintf(tmp,sizeof(tmp),"&#x%02X;",s);msg+=tmp;}else{msg+=s;}}}break;}}}return msg;}}namespace iutest{class JunitXmlGeneratorListener:public DefaultXmlGeneratorListener{public: explicit JunitXmlGeneratorListener(const ::std::string& path):DefaultXmlGeneratorListener(path){}virtual ~JunitXmlGeneratorListener(){}public: virtual bool IsReportable(const UnitTest& test) II_CXX_O;virtual void OnReportTest(IFile* file,const UnitTest& test) II_CXX_O;private: static void OnReportTestCase(IFile* file,const TestCase& test_case);static void OnReportTestInfo(IFile* file,const TestInfo& test_info);static void OnReportProperty(IFile* file,const char* name,const char* value);static void OnReportTestProperty(IFile* file,const TestResult& test_result);static void OnReportTestSkipped(IFile* file,const TestInfo& test_info);public: static bool SetUp(){::std::string xmlpath=TestEnv::get_report_junit_xml_filepath();if(!xmlpath.empty()){TestEnv::event_listeners().set_default_xml_generator(new JunitXmlGeneratorListener(xmlpath));return true;}return false;}};inline bool JunitXmlGeneratorListener::IsReportable(const UnitTest& test){const int reportable_test_count=test.reportable_test_count();if(reportable_test_count<=0){return false;}return true;}inline void JunitXmlGeneratorListener::OnReportTest(IFile* file,const UnitTest& test){file->Printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");const int reportable_test_count=test.reportable_test_count();file->Printf("<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" ",reportable_test_count,test.failed_test_count(),test.reportable_disabled_test_count());file->Printf("errors=\"0\" time=\"%s\" timestamp=\"%s\" ",detail::FormatTimeInMillisecAsSecond(test.elapsed_time()).c_str(),detail::FormatTimeInMillisecAsIso8601(test.start_timestamp()).c_str());file->Printf("name=\"AllTests\">\n");for(int i=0,count=test.total_test_case_count();i<count;++i){OnReportTestCase(file,*test.GetTestCase(i));}file->Printf("</testsuites>\n");}inline void JunitXmlGeneratorListener::OnReportTestCase(IFile* file,const TestCase& test_case){const int reportable_test_count=test_case.reportable_test_count();if(reportable_test_count<=0){return;}file->Printf("  <testsuite ");OutputXmlAttribute(file,"name",EscapeXmlAttribute(test_case.t_c_name_with_default_package_name()).c_str());file->Printf("tests=\"%d\" failures=\"%d\" disabled=\"%d\" ",reportable_test_count,test_case.failed_test_count(),test_case.reportable_disabled_test_count());file->Printf("skipped=\"%d\" ",test_case.reportable_skip_test_count());file->Printf("errors=\"0\" time=\"%s\" timestamp=\"%s\">\n",detail::FormatTimeInMillisecAsSecond(test_case.elapsed_time()).c_str(),detail::FormatTimeInMillisecAsIso8601(test_case.start_timestamp()).c_str());file->Printf("    <properties>\n");{const char* type_param=test_case.type_param();if(type_param!=0){OnReportProperty(file,"type_param",EscapeXmlAttribute(type_param).c_str());}}{for(int i=0,count=test_case.total_test_count();i<count;++i){const TestInfo& test_info=*test_case.GetTestInfo(i);const char* value_param=test_info.value_param();if(value_param!=0){OnReportProperty(file,test_info.name(),EscapeXmlAttribute(value_param).c_str());}}}OnReportTestProperty(file,*test_case.ad_hoc_test_result());file->Printf("    </properties>\n");{for(int i=0,count=test_case.total_test_count();i<count;++i){OnReportTestInfo(file,*test_case.GetTestInfo(i));}}file->Printf("    <system-out />\n");file->Printf("    <system-err />\n");file->Printf("  </testsuite>\n");}inline void JunitXmlGeneratorListener::OnReportTestInfo(IFile* file,const TestInfo& test_info){if(!test_info.is_reportable()){return;}file->Printf("    <testcase ");OutputXmlAttribute(file,"name",EscapeXmlAttribute(test_info.name()).c_str());if(test_info.is_ran()){file->Printf("status=\"run\" ");}else{file->Printf("status=\"notrun\" ");}file->Printf("time=\"%s\" ",detail::FormatTimeInMillisecAsSecond(test_info.elapsed_time()).c_str());OutputXmlAttribute(file,"classname",EscapeXmlAttribute(test_info.t_c_name_with_default_package_name()).c_str());file->Printf(">\n");const bool notrun=test_info.should_run()&&!test_info.is_ran();if(test_info.HasFailure()||notrun){for(int i=0,count=test_info.result()->total_part_count();i<count;++i){const TestPartResult& part=test_info.result()->GetTestPartResult(i);if(part.passed()){continue;}file->Printf("      <failure ");OutputXmlAttribute(file,"message",EscapeXmlAttribute(part.summary()).c_str());file->Printf("type=\"\">");::std::string message=detail::FormatCompilerIndependentFileLocation(part.file_name(),part.line_number());message+="\n";message+=detail::MultiByteStringToUTF8(part.summary());OutputXmlCDataSection(file,message.c_str());file->Printf("\n      </failure>\n");}if(notrun){file->Printf("      <failure message=\"Not Run\" type=\"\">");OutputXmlCDataSection(file,"Not Run");file->Printf("\n      </failure>\n");}}else{const bool skipped=test_info.is_skipped()||!test_info.should_run();if(skipped){OnReportTestSkipped(file,test_info);}}file->Printf("    </testcase>\n");}inline void JunitXmlGeneratorListener::OnReportProperty(IFile* file,const char* name,const char* value){file->Printf("      <property name=\"%s\" value=\"%s\" />\n",name,value);}inline void JunitXmlGeneratorListener::OnReportTestProperty(IFile* file,const TestResult& test_result){for(int i=0,count=test_result.test_property_count();i<count;++i){const TestProperty& prop=test_result.GetTestProperty(i);OnReportProperty(file,EscapeXmlAttribute(prop.key()).c_str(),EscapeXmlAttribute(prop.value()).c_str());}}inline void JunitXmlGeneratorListener::OnReportTestSkipped(IFile* file,const TestInfo& test_info){file->Printf("      <skipped type=\"iutest.skip\" ");const TestResult* tr=test_info.result();const int count=tr->total_part_count();for(int i=0;i<count;++i){const TestPartResult& part=tr->GetTestPartResult(i);if(part.skipped()){::std::string message=detail::FormatCompilerIndependentFileLocation(part.file_name(),part.line_number());message+=": ";message+=detail::MultiByteStringToUTF8(part.summary());OutputXmlAttribute(file,"message",EscapeXmlAttribute(message).c_str());file->Printf(" />\n");return;}}if(test_info.is_disabled_test()){OutputXmlAttribute(file,"message","disabled test.");}file->Printf("/>\n");}}namespace iutest{namespace detail{template<typename T,typename ::std::string(*GetXmlPath)()>class StderrXmlGeneratorListenerBase:public T{public: explicit StderrXmlGeneratorListenerBase(const ::std::string& path):T(path){}~StderrXmlGeneratorListenerBase(){}private: StdErrorFile m_stderr;virtual bool FileOpen(const char* path){if(m_stderr.Open(path,IFile::OpenAppend)){this->m_fp=&m_stderr;return true;}return false;}virtual void FileClose(){this->m_fp=0;}public: static bool SetUp(){::std::string xmlpath=GetXmlPath();if(!xmlpath.empty()){TestEnv::event_listeners().set_default_xml_generator(new StderrXmlGeneratorListenerBase(xmlpath));return true;}return false;}};}typedef detail::StderrXmlGeneratorListenerBase<DefaultXmlGeneratorListener,TestEnv::get_report_xml_filepath> StderrXmlGeneratorListener;typedef detail::StderrXmlGeneratorListenerBase<JunitXmlGeneratorListener,TestEnv::get_report_junit_xml_filepath> StderrJunitXmlGeneratorListener;}
#if IUTEST_HAS_STREAM_RESULT
#include <arpa/inet.h>
#include <netdb.h>
namespace iutest{namespace detail{class BasicSocket{public:typedef int descriptor_t;typedef size_t length_t;static const descriptor_t INVALID_DESCRIPTOR=-1;public: BasicSocket():m_socket(INVALID_DESCRIPTOR){}~BasicSocket(void){Close();}public: bool Open(const char* host,const char* port){if(m_socket!=INVALID_DESCRIPTOR){return true;}addrinfo* servinfo=0;addrinfo hints;memset(&hints,0,sizeof(hints));hints.ai_family=AF_UNSPEC;hints.ai_socktype=SOCK_STREAM;const int err_no=getaddrinfo(host,port,&hints,&servinfo);if(err_no!=0){return false;}for(addrinfo* curr=servinfo;curr!=0;curr=curr->ai_next){const descriptor_t fd=socket(curr->ai_family,curr->ai_socktype,curr->ai_protocol);if(fd!=INVALID_DESCRIPTOR){if(connect(fd,curr->ai_addr,static_cast<length_t>(curr->ai_addrlen))!=-1){m_socket=fd;break;}Close(fd);}}freeaddrinfo(servinfo);return(m_socket!=INVALID_DESCRIPTOR);}void Close(){Close(m_socket);m_socket=INVALID_DESCRIPTOR;}void CheckLastError(){}public: static int Close(descriptor_t d){return close(d);}public: bool IsValid()const{return m_socket!=INVALID_DESCRIPTOR;}protected: descriptor_t m_socket;IP_DIS_C_A_A(BasicSocket);};class SocketWriter:virtual public BasicSocket,public IOutStream{public: SocketWriter(){}public: bool Send(const ::std::string& message){return Write(message.c_str(),message.length(),1u);}bool SendLn(const ::std::string& message){return Send(message+"\r\n");}public: virtual bool Write(const void* buf,size_t size,size_t cnt) II_CXX_O{if(!IsValid()){return false;}const int size_=static_cast<int>(size);for(size_t i=0;i<cnt;++i){if(write(m_socket,buf,size_)==-1){return false;}}return true;}private: IP_DIS_C_A_A(SocketWriter);};class SocketReader:virtual public BasicSocket{public: SocketReader(){}public: bool Read(void* buf,size_t size){if(!IsValid()){return false;}const int size_=static_cast<int>(size);if(read(m_socket,buf,size_)==-1){return false;}return true;}private: IP_DIS_C_A_A(SocketReader);};class Socket:public SocketWriter,public SocketReader{public: Socket(){}};}}namespace iutest{class StreamResultListener:public EmptyTestEventListener{public: StreamResultListener(const char* host,const char* port);public: virtual void OnTestProgramStart(const UnitTest& test) II_CXX_O;virtual void OnTestIterationStart(const UnitTest& test,int iteration) II_CXX_O;virtual void OnTestCaseStart(const TestCase& test_case) II_CXX_O;virtual void OnTestStart(const TestInfo& test_info) II_CXX_O;virtual void OnTestPartResult(const TestPartResult& test_part_result) II_CXX_O;virtual void OnTestRecordProperty(const TestProperty& test_property) II_CXX_O;virtual void OnTestEnd(const TestInfo& test_info) II_CXX_O;virtual void OnTestCaseEnd(const TestCase& test_case) II_CXX_O;virtual void OnTestIterationEnd(const UnitTest& test,int iteration) II_CXX_O;virtual void OnTestProgramEnd(const UnitTest& test) II_CXX_O;private: ::std::string UrlEncode(const char* str);::std::string FormatBool(bool b);void Start();void SendLn(const ::std::string& message);private: detail::SocketWriter m_socket;IP_DIS_C_A_A(StreamResultListener);public: static TestEventListener* SetUp(){::std::string addr=TestEnv::get_stream_result_to();if(addr.empty()){return 0;}const size_t pos=addr.find(':');if(pos==::std::string::npos){return 0;}TestEventListener* p=new StreamResultListener(addr.substr(0,pos).c_str(),addr.substr(pos+1).c_str());UnitTest::GetInstance()->listeners().Append(p);return p;}};}
#if IUTEST_HAS_STREAM_RESULT
namespace iutest{inline StreamResultListener::StreamResultListener(const char* host,const char* port){if(!m_socket.Open(host,port)){IUTEST_LOG_(WARNING)<<"StreamResultListener: failed connect to " <<host<<":" <<port;}}inline void StreamResultListener::OnTestProgramStart(const UnitTest& test){(void)(test);Start();SendLn("event=TestProgramStart");}inline void StreamResultListener::OnTestIterationStart(const UnitTest& test,int iteration){(void)(test);SendLn("event=TestIterationStart&iteration=" + StreamableToString(iteration));}inline void StreamResultListener::OnTestCaseStart(const TestCase& test_case){SendLn("event=TestCaseStart&name=" + StreamableToString(test_case.name()));}inline void StreamResultListener::OnTestStart(const TestInfo& test_info){SendLn("event=TestStart&name=" + StreamableToString(test_info.name()));}inline void StreamResultListener::OnTestPartResult(const TestPartResult& test_part_result){const char* filename=test_part_result.file_name();if(filename==0){filename="";}SendLn("event=TestPartResult&file=" + UrlEncode(filename)+ "&line=" + StreamableToString(test_part_result.line_number())+ "&message=" + UrlEncode(test_part_result.message()));}inline void StreamResultListener::OnTestRecordProperty(const TestProperty& test_property){SendLn("event=TestRecordProperty&name=" + UrlEncode(test_property.key())+ "&value=" + UrlEncode(test_property.value()));}inline void StreamResultListener::OnTestEnd(const TestInfo& test_info){SendLn("event=TestEnd&passed="+ FormatBool(test_info.Passed())+ "&elapsed_time=" + StreamableToString(test_info.elapsed_time())+"ms");}inline void StreamResultListener::OnTestCaseEnd(const TestCase& test_case){SendLn("event=TestCaseEnd&passed="+ FormatBool(test_case.Passed())+ "&elapsed_time=" + StreamableToString(test_case.elapsed_time())+"ms");}inline void StreamResultListener::OnTestIterationEnd(const UnitTest& test,int iteration){(void)(iteration);SendLn("event=TestIterationEnd&passed="+ FormatBool(test.Passed())+ "&elapsed_time=" + StreamableToString(test.elapsed_time())+"ms");}inline void StreamResultListener::OnTestProgramEnd(const UnitTest& test){SendLn("event=TestProgramEnd&passed=" + FormatBool(test.Passed()));m_socket.Close();}inline ::std::string StreamResultListener::UrlEncode(const char* str){::std::string result;if(str!=0){result.reserve(strlen(str)+1);for(const char* p=str;*p!='\0';++p){const char ch=*p;switch(ch){case '%': case '=': case '&': case '\n': result.append(detail::ToHexString(ch));break;default: result.push_back(ch);}}}return result;}inline ::std::string StreamResultListener::FormatBool(bool b){return b?"1" : "0";}inline void StreamResultListener::Start(){SendLn("iutest_streaming_protocol_version=1.0");}inline void StreamResultListener::SendLn(const ::std::string& message){m_socket.SendLn(message);}}
#endif
#endif
#define IUTEST_TEST(t_c_,tn_) IUTEST_TEST_STRICT_(t_c_,tn_ ,::iutest::Test,::iutest::internal::GetTestTypeId())
#define IUTEST(t_c_,tn_) IUTEST_TEST(t_c_,tn_)
#define IUTEST_F(tf_,tn_) IUTEST_TEST_F_(tf_,tn_)
#if IUTEST_HAS_PARAM_METHOD_TEST
#define IUTEST_PMZ(t_c_,tn_,mtd_,...) II_TEST_PMZ_(t_c_,tn_ ,mtd_,::iutest::Test ,::iutest::internal::GetTestTypeId(),__VA_ARGS__)
#define IUTEST_PMZ_F(tf_,tn_,mtd_,...) II_TEST_PMZ_(tf_,tn_ ,mtd_,tf_ ,::iutest::internal::GetTypeId<tf_ >(),__VA_ARGS__)
#endif
#define IUTEST_ALIAS_TESTNAME(tn_) II_ALS_TN(tn_)
#define II_ALS_TN_F(tcn_,tf_) II_ALS_TN_F_(tcn_,tf_)
#define IUTEST_INIT(argc_,argv_) ::iutest::InitIrisUnitTest(argc_,argv_)
#define IUTEST_RUN_ALL_TESTS() ::iutest::UnitTestSource::GetInstance().Run()
#define IUTEST_SCOPED_TRACE(msg) II_S_MSG(msg)
#define IUTEST_SUCCEED() II_S()
#define IUTEST_FAIL() II_F()
#define IUTEST_ADD_FAILURE() II_ADD_F()
#define IUTEST_ADD_FAILURE_AT(file,line) II_ADD_F_AT(file,line)
#define IUTEST_SKIP() IUTEST_TEST_SKIP()
#define IUTEST_ASSERT(...) IUTEST_TEST_EXPRESSION_((__VA_ARGS__),true,II_A_FAIL)
#define IUTEST_ASSERT_NOT(...) IUTEST_TEST_EXPRESSION_((__VA_ARGS__),false,II_A_FAIL)
#define IUTEST_ASSERT_THAT(actual,matcher) IUTEST_TEST_THAT(actual,matcher,II_A_FAIL)
#define IUTEST_ASSERT_EQ(expected,actual) IUTEST_TEST_EQ(expected,actual,II_A_FAIL)
#define IUTEST_ASSERT_ALMOST_EQ(expected,actual) IUTEST_TEST_ALMOST_EQ(expected,actual,II_A_FAIL)
#define IUTEST_ASSERT_NE(v1,v2) IUTEST_TEST_NE(v1,v2,II_A_FAIL)
#define IUTEST_ASSERT_LE(v1,v2) IUTEST_TEST_LE(v1,v2,II_A_FAIL)
#define IUTEST_ASSERT_LT(v1,v2) IUTEST_TEST_LT(v1,v2,II_A_FAIL)
#define IUTEST_ASSERT_GE(v1,v2) IUTEST_TEST_GE(v1,v2,II_A_FAIL)
#define IUTEST_ASSERT_GT(v1,v2) IUTEST_TEST_GT(v1,v2,II_A_FAIL)
#define IUTEST_ASSERT_TRUE(...) IUTEST_TEST_TRUE((__VA_ARGS__),#__VA_ARGS__,II_A_FAIL)
#define IUTEST_ASSERT_FALSE(...) IUTEST_TEST_FALSE((__VA_ARGS__),#__VA_ARGS__,II_A_FAIL)
#define IUTEST_ASSERT_NULL(...) IUTEST_TEST_NULL((__VA_ARGS__),II_A_FAIL)
#define IUTEST_ASSERT_NOTNULL(...) IUTEST_TEST_NOTNULL((__VA_ARGS__),II_A_FAIL)
#define IUTEST_ASSERT_SAME(v1,v2) IUTEST_TEST_SAME(v1,v2,II_A_FAIL)
#define IUTEST_ASSERT_FLOAT_EQ(expected,actual) IUTEST_TEST_FLOAT_EQ(expected,actual,II_A_FAIL)
#define IUTEST_ASSERT_DOUBLE_EQ(expected,actual) IUTEST_TEST_DOUBLE_EQ(expected,actual,II_A_FAIL)
#if IUTEST_HAS_LONG_DOUBLE
#define IUTEST_ASSERT_LONG_DOUBLE_EQ(expected,actual) IUTEST_TEST_LONG_DOUBLE_EQ(expected,actual,II_A_FAIL)
#endif
#define IUTEST_ASSERT_NEAR(v1,v2,abs_v) IUTEST_TEST_NEAR(v1,v2,abs_v,II_A_FAIL)
#define IUTEST_ASSERT_STREQ(exp_s,act_s) IUTEST_TEST_STREQ(exp_s,act_s,II_A_FAIL)
#define IUTEST_ASSERT_STRNE(v1,v2) IUTEST_TEST_STRNE(v1,v2,II_A_FAIL)
#define IUTEST_ASSERT_STRCASEEQ(exp_s,act_s) IUTEST_TEST_STRCASEEQ(exp_s,act_s,II_A_FAIL)
#define IUTEST_ASSERT_STRCASENE(v1,v2) IUTEST_TEST_STRCASENE(v1,v2,II_A_FAIL)
#if IUTEST_HAS_EXCEPTIONS
#define IUTEST_ASSERT_THROW(st,exp_e) IUTEST_TEST_THROW_(st,exp_e,II_A_FAIL)
#define IUTEST_ASSERT_THROW_VALUE_EQ(st,exp_e,exp_v) IUTEST_TEST_THROW_VALUE_EQ_(st,exp_e,exp_v,II_A_FAIL)
#define IUTEST_ASSERT_THROW_VALUE_NE(st,exp_e,v) IUTEST_TEST_THROW_VALUE_NE_(st,exp_e,v,II_A_FAIL)
#define IUTEST_ASSERT_THROW_VALUE_STREQ(st,exp_e,exp_s) IUTEST_TEST_THROW_VALUE_STREQ_(st,exp_e,exp_s,II_A_FAIL)
#define IUTEST_ASSERT_THROW_VALUE_STRCASEEQ(st,exp_e,exp_s) IUTEST_TEST_THROW_VALUE_STRCASEEQ_(st,exp_e,exp_s,II_A_FAIL)
#define IUTEST_ASSERT_ANY_THROW(st) IUTEST_TEST_ANY_THROW_(st,II_A_FAIL)
#define IUTEST_ASSERT_NO_THROW(st) IUTEST_TEST_NO_THROW_(st,II_A_FAIL)
#endif
#define IUTEST_ASSERT_NO_FAILURE(st) IUTEST_TEST_NO_FAILURE_(st,II_A_FAIL)
#define IUTEST_ASSERT_NO_FATAL_FAILURE(st) IUTEST_TEST_NO_FATAL_FAILURE_(st,II_A_FAIL)
#define IUTEST_ASSERT_FAIL() II_F()
#define IUTEST_EXPECT(...) IUTEST_TEST_EXPRESSION_((__VA_ARGS__),true,II_E_FAIL)
#define IUTEST_EXPECT_NOT(...) IUTEST_TEST_EXPRESSION_((__VA_ARGS__),false,II_E_FAIL)
#define IUTEST_EXPECT_THAT(actual,matcher) IUTEST_TEST_THAT(actual,matcher,II_E_FAIL)
#define IUTEST_EXPECT_EQ(expected,actual) IUTEST_TEST_EQ(expected,actual,II_E_FAIL)
#define IUTEST_EXPECT_ALMOST_EQ(expected,actual) IUTEST_TEST_ALMOST_EQ(expected,actual,II_E_FAIL)
#define IUTEST_EXPECT_NE(v1,v2) IUTEST_TEST_NE(v1,v2,II_E_FAIL)
#define IUTEST_EXPECT_LE(v1,v2) IUTEST_TEST_LE(v1,v2,II_E_FAIL)
#define IUTEST_EXPECT_LT(v1,v2) IUTEST_TEST_LT(v1,v2,II_E_FAIL)
#define IUTEST_EXPECT_GE(v1,v2) IUTEST_TEST_GE(v1,v2,II_E_FAIL)
#define IUTEST_EXPECT_GT(v1,v2) IUTEST_TEST_GT(v1,v2,II_E_FAIL)
#define IUTEST_EXPECT_TRUE(...) IUTEST_TEST_TRUE((__VA_ARGS__),#__VA_ARGS__,II_E_FAIL)
#define IUTEST_EXPECT_FALSE(...) IUTEST_TEST_FALSE((__VA_ARGS__),#__VA_ARGS__,II_E_FAIL)
#define IUTEST_EXPECT_NULL(...) IUTEST_TEST_NULL((__VA_ARGS__),II_E_FAIL)
#define IUTEST_EXPECT_NOTNULL(...) IUTEST_TEST_NOTNULL((__VA_ARGS__),II_E_FAIL)
#define IUTEST_EXPECT_SAME(v1,v2) IUTEST_TEST_SAME(v1,v2,II_E_FAIL)
#define IUTEST_EXPECT_FLOAT_EQ(expected,actual) IUTEST_TEST_FLOAT_EQ(expected,actual,II_E_FAIL)
#define IUTEST_EXPECT_DOUBLE_EQ(expected,actual) IUTEST_TEST_DOUBLE_EQ(expected,actual,II_E_FAIL)
#if IUTEST_HAS_LONG_DOUBLE
#define IUTEST_EXPECT_LONG_DOUBLE_EQ(expected,actual) IUTEST_TEST_LONG_DOUBLE_EQ(expected,actual,II_E_FAIL)
#endif
#define IUTEST_EXPECT_NEAR(v1,v2,abs_v) IUTEST_TEST_NEAR(v1,v2,abs_v,II_E_FAIL)
#define IUTEST_EXPECT_STREQ(exp_s,act_s) IUTEST_TEST_STREQ(exp_s,act_s,II_E_FAIL)
#define IUTEST_EXPECT_STRNE(v1,v2) IUTEST_TEST_STRNE(v1,v2,II_E_FAIL)
#define IUTEST_EXPECT_STRCASEEQ(exp_s,act_s) IUTEST_TEST_STRCASEEQ(exp_s,act_s,II_E_FAIL)
#define IUTEST_EXPECT_STRCASENE(v1,v2) IUTEST_TEST_STRCASENE(v1,v2,II_E_FAIL)
#if IUTEST_HAS_EXCEPTIONS
#define IUTEST_EXPECT_THROW(st,exp_e) IUTEST_TEST_THROW_(st,exp_e,II_E_FAIL)
#define IUTEST_EXPECT_THROW_VALUE_EQ(st,exp_e,exp_v) IUTEST_TEST_THROW_VALUE_EQ_(st,exp_e,exp_v,II_E_FAIL)
#define IUTEST_EXPECT_THROW_VALUE_NE(st,exp_e,v) IUTEST_TEST_THROW_VALUE_NE_(st,exp_e,v,II_E_FAIL)
#define IUTEST_EXPECT_THROW_VALUE_STREQ(st,exp_e,exp_s) IUTEST_TEST_THROW_VALUE_STREQ_(st,exp_e,exp_s,II_E_FAIL)
#define IUTEST_EXPECT_THROW_VALUE_STRCASEEQ(st,exp_e,exp_s) IUTEST_TEST_THROW_VALUE_STRCASEEQ_(st,exp_e,exp_s,II_E_FAIL)
#define IUTEST_EXPECT_ANY_THROW(st) IUTEST_TEST_ANY_THROW_(st,II_E_FAIL)
#define IUTEST_EXPECT_NO_THROW(st) IUTEST_TEST_NO_THROW_(st,II_E_FAIL)
#endif
#define IUTEST_EXPECT_NO_FAILURE(st) IUTEST_TEST_NO_FAILURE_(st,II_E_FAIL)
#define IUTEST_EXPECT_NO_FATAL_FAILURE(st) IUTEST_TEST_NO_FATAL_FAILURE_(st,II_E_FAIL)
#define IUTEST_EXPECT_FAIL() II_ADD_F()
#ifndef IUTEST_EXPECT_FAIL_AT
#define IUTEST_EXPECT_FAIL_AT(file,line) II_ADD_F_AT(file,line)
#endif
#define IUTEST_INFORM(...) IUTEST_TEST_EXPRESSION_((__VA_ARGS__),true,II_I_FAIL)
#define IUTEST_INFORM_NOT(...) IUTEST_TEST_EXPRESSION_((__VA_ARGS__),false,II_I_FAIL)
#define IUTEST_INFORM_THAT(actual,matcher) IUTEST_TEST_THAT(actual,matcher,II_I_FAIL)
#define IUTEST_INFORM_EQ(expected,actual) IUTEST_TEST_EQ(expected,actual,II_I_FAIL)
#define IUTEST_INFORM_ALMOST_EQ(expected,actual) IUTEST_TEST_ALMOST_EQ(expected,actual,II_I_FAIL)
#define IUTEST_INFORM_NE(v1,v2) IUTEST_TEST_NE(v1,v2,II_I_FAIL)
#define IUTEST_INFORM_LE(v1,v2) IUTEST_TEST_LE(v1,v2,II_I_FAIL)
#define IUTEST_INFORM_LT(v1,v2) IUTEST_TEST_LT(v1,v2,II_I_FAIL)
#define IUTEST_INFORM_GE(v1,v2) IUTEST_TEST_GE(v1,v2,II_I_FAIL)
#define IUTEST_INFORM_GT(v1,v2) IUTEST_TEST_GT(v1,v2,II_I_FAIL)
#define IUTEST_INFORM_TRUE(...) IUTEST_TEST_TRUE((__VA_ARGS__),#__VA_ARGS__,II_I_FAIL)
#define IUTEST_INFORM_FALSE(...) IUTEST_TEST_FALSE((__VA_ARGS__),#__VA_ARGS__,II_I_FAIL)
#define IUTEST_INFORM_NULL(...) IUTEST_TEST_NULL((__VA_ARGS__),II_I_FAIL)
#define IUTEST_INFORM_NOTNULL(...) IUTEST_TEST_NOTNULL((__VA_ARGS__),II_I_FAIL)
#define IUTEST_INFORM_SAME(v1,v2) IUTEST_TEST_SAME(v1,v2,II_I_FAIL)
#define IUTEST_INFORM_FLOAT_EQ(expected,actual) IUTEST_TEST_FLOAT_EQ(expected,actual,II_I_FAIL)
#define IUTEST_INFORM_DOUBLE_EQ(expected,actual) IUTEST_TEST_DOUBLE_EQ(expected,actual,II_I_FAIL)
#if IUTEST_HAS_LONG_DOUBLE
#define IUTEST_INFORM_LONG_DOUBLE_EQ(expected,actual) IUTEST_TEST_LONG_DOUBLE_EQ(expected,actual,II_I_FAIL)
#endif
#define IUTEST_INFORM_NEAR(v1,v2,abs_v) IUTEST_TEST_NEAR(v1,v2,abs_v,II_I_FAIL)
#define IUTEST_INFORM_STREQ(exp_s,act_s) IUTEST_TEST_STREQ(exp_s,act_s,II_I_FAIL)
#define IUTEST_INFORM_STRNE(v1,v2) IUTEST_TEST_STRNE(v1,v2,II_I_FAIL)
#define IUTEST_INFORM_STRCASEEQ(exp_s,act_s) IUTEST_TEST_STRCASEEQ(exp_s,act_s,II_I_FAIL)
#define IUTEST_INFORM_STRCASENE(v1,v2) IUTEST_TEST_STRCASENE(v1,v2,II_I_FAIL)
#if IUTEST_HAS_EXCEPTIONS
#define IUTEST_INFORM_THROW(st,exp_e) IUTEST_TEST_THROW_(st,exp_e,II_I_FAIL)
#define IUTEST_INFORM_THROW_VALUE_EQ(st,exp_e,exp_v) IUTEST_TEST_THROW_VALUE_EQ_(st,exp_e,exp_v,II_I_FAIL)
#define IUTEST_INFORM_THROW_VALUE_NE(st,exp_e,v) IUTEST_TEST_THROW_VALUE_NE_(st,exp_e,v,II_I_FAIL)
#define IUTEST_INFORM_THROW_VALUE_STREQ(st,exp_e,exp_s) IUTEST_TEST_THROW_VALUE_STREQ_(st,exp_e,exp_s,II_I_FAIL)
#define IUTEST_INFORM_THROW_VALUE_STRCASEEQ(st,exp_e,exp_s) IUTEST_TEST_THROW_VALUE_STRCASEEQ_(st,exp_e,exp_s,II_I_FAIL)
#define IUTEST_INFORM_ANY_THROW(st) IUTEST_TEST_ANY_THROW_(st,II_I_FAIL)
#define IUTEST_INFORM_NO_THROW(st) IUTEST_TEST_NO_THROW_(st,II_I_FAIL)
#endif
#define IUTEST_INFORM_NO_FAILURE(st) IUTEST_TEST_NO_FAILURE_(st,II_I_FAIL)
#define IUTEST_INFORM_NO_FATAL_FAILURE(st) IUTEST_TEST_NO_FATAL_FAILURE_(st,II_I_FAIL)
#define IUTEST_ASSUME(...) IUTEST_TEST_EXPRESSION_((__VA_ARGS__),true,II_M_FAIL)
#define IUTEST_ASSUME_NOT(...) IUTEST_TEST_EXPRESSION_((__VA_ARGS__),false,II_M_FAIL)
#define IUTEST_ASSUME_THAT(actual,matcher) IUTEST_TEST_THAT(actual,matcher,II_M_FAIL)
#define IUTEST_ASSUME_EQ(expected,actual) IUTEST_TEST_EQ(expected,actual,II_M_FAIL)
#define IUTEST_ASSUME_ALMOST_EQ(expected,actual) IUTEST_TEST_ALMOST_EQ(expected,actual,II_M_FAIL)
#define IUTEST_ASSUME_NE(v1,v2) IUTEST_TEST_NE(v1,v2,II_M_FAIL)
#define IUTEST_ASSUME_LE(v1,v2) IUTEST_TEST_LE(v1,v2,II_M_FAIL)
#define IUTEST_ASSUME_LT(v1,v2) IUTEST_TEST_LT(v1,v2,II_M_FAIL)
#define IUTEST_ASSUME_GE(v1,v2) IUTEST_TEST_GE(v1,v2,II_M_FAIL)
#define IUTEST_ASSUME_GT(v1,v2) IUTEST_TEST_GT(v1,v2,II_M_FAIL)
#define IUTEST_ASSUME_TRUE(...) IUTEST_TEST_TRUE((__VA_ARGS__),#__VA_ARGS__,II_M_FAIL)
#define IUTEST_ASSUME_FALSE(...) IUTEST_TEST_FALSE((__VA_ARGS__),#__VA_ARGS__,II_M_FAIL)
#define IUTEST_ASSUME_NULL(...) IUTEST_TEST_NULL((__VA_ARGS__),II_M_FAIL)
#define IUTEST_ASSUME_NOTNULL(...) IUTEST_TEST_NOTNULL((__VA_ARGS__),II_M_FAIL)
#define IUTEST_ASSUME_SAME(v1,v2) IUTEST_TEST_SAME(v1,v2,II_M_FAIL)
#define IUTEST_ASSUME_FLOAT_EQ(expected,actual) IUTEST_TEST_FLOAT_EQ(expected,actual,II_M_FAIL)
#define IUTEST_ASSUME_DOUBLE_EQ(expected,actual) IUTEST_TEST_DOUBLE_EQ(expected,actual,II_M_FAIL)
#if IUTEST_HAS_LONG_DOUBLE
#define IUTEST_ASSUME_LONG_DOUBLE_EQ(expected,actual) IUTEST_TEST_LONG_DOUBLE_EQ(expected,actual,II_M_FAIL)
#endif
#define IUTEST_ASSUME_NEAR(v1,v2,abs_v) IUTEST_TEST_NEAR(v1,v2,abs_v,II_M_FAIL)
#define IUTEST_ASSUME_STREQ(exp_s,act_s) IUTEST_TEST_STREQ(exp_s,act_s,II_M_FAIL)
#define IUTEST_ASSUME_STRNE(v1,v2) IUTEST_TEST_STRNE(v1,v2,II_M_FAIL)
#define IUTEST_ASSUME_STRCASEEQ(exp_s,act_s) IUTEST_TEST_STRCASEEQ(exp_s,act_s,II_M_FAIL)
#define IUTEST_ASSUME_STRCASENE(v1,v2) IUTEST_TEST_STRCASENE(v1,v2,II_M_FAIL)
#if IUTEST_HAS_EXCEPTIONS
#define IUTEST_ASSUME_THROW(st,exp_e) IUTEST_TEST_THROW_(st,exp_e,II_M_FAIL)
#define IUTEST_ASSUME_THROW_VALUE_EQ(st,exp_e,exp_v) IUTEST_TEST_THROW_VALUE_EQ_(st,exp_e,exp_v,II_M_FAIL)
#define IUTEST_ASSUME_THROW_VALUE_NE(st,exp_e,v) IUTEST_TEST_THROW_VALUE_NE_(st,exp_e,v,II_M_FAIL)
#define IUTEST_ASSUME_THROW_VALUE_STREQ(st,exp_e,exp_s) IUTEST_TEST_THROW_VALUE_STREQ_(st,exp_e,exp_s,II_M_FAIL)
#define IUTEST_ASSUME_THROW_VALUE_STRCASEEQ(st,exp_e,exp_s) IUTEST_TEST_THROW_VALUE_STRCASEEQ_(st,exp_e,exp_s,II_M_FAIL)
#define IUTEST_ASSUME_ANY_THROW(st) IUTEST_TEST_ANY_THROW_(st,II_M_FAIL)
#define IUTEST_ASSUME_NO_THROW(st) IUTEST_TEST_NO_THROW_(st,II_M_FAIL)
#endif
#define IUTEST_ASSUME_NO_FAILURE(st) IUTEST_TEST_NO_FAILURE_(st,II_M_FAIL)
#define IUTEST_ASSUME_NO_FATAL_FAILURE(st) IUTEST_TEST_NO_FATAL_FAILURE_(st,II_M_FAIL)
namespace iutest{class UnitTestSource{public: static UnitTestSource& GetInstance(){static UnitTestSource inst;return inst;}private: UnitTestSource(){(void)(&detail::iuDebugInitialize);(void)(&detail::iuDebugBreakAlloc);TestEnv::event_listeners().set_default_result_printer(new DefaultResultPrintListener());}public: ~UnitTestSource(){TestEnv::event_listeners().set_default_result_printer(0);TestEnv::event_listeners().set_default_xml_generator(0);}public: void Initialize(){UnitTest::instance().Initialize();}int Run(){SetUpDefaultListener();return UnitTest::instance().Run();}private: void SetUpDefaultListener(){if(TestEnv::has_output_option()){do{if(StderrXmlGeneratorListener::SetUp()){break;}if(StderrJunitXmlGeneratorListener::SetUp()){break;}IUTEST_LOG_(WARNING)<<"unrecognized output format \"" <<TestEnv::get_output_option()<<"\" ignored.";}while(detail::AlwaysFalse());}
#if IUTEST_HAS_STREAM_RESULT
StreamResultListener::SetUp();
#endif
}};namespace detail{template<typename T>inline void II_ATR_U InitIrisUnitTest(int* pargc,T argv){UnitTestSource::GetInstance().Initialize();TestEnv::ParseCommandLine(pargc,argv);TestEnv::LoadFlagFile();}}inline void II_ATR_U InitIrisUnitTest(int* pargc,char** argv){detail::InitIrisUnitTest(pargc,argv);}inline void II_ATR_U InitIrisUnitTest(int* pargc,wchar_t** argv){detail::InitIrisUnitTest(pargc,argv);}inline void II_ATR_U InitIrisUnitTest(int* pargc,const char** argv){detail::InitIrisUnitTest(pargc,argv);}inline void II_ATR_U InitIrisUnitTest(int* pargc,const wchar_t** argv){detail::InitIrisUnitTest(pargc,argv);}inline void II_ATR_U InitIrisUnitTest(){detail::InitIrisUnitTest<char**>(0,0);}
#if IUTEST_HAS_NULLPTR
inline void II_ATR_U InitIrisUnitTest(int* pargc,::std::nullptr_t){detail::InitIrisUnitTest<char**>(pargc,0);}
#endif
template<typename CharType>inline void II_ATR_U InitIrisUnitTest(::std::vector< ::std::basic_string<CharType> >& argv){UnitTestSource::GetInstance().Initialize();TestEnv::ParseCommandLine(argv);TestEnv::LoadFlagFile();}inline Environment* II_ATR_U AddGlobalTestEnvironment(Environment* env){return TestEnv::AddGlobalTestEnvironment(env);}}
#define IUTEST_ASSERT_EQ_COLLECTIONS(b1,e1,b2,e2) II_T_EQ_CLCT(b1,e1,b2,e2,II_A_FAIL)
#define IUTEST_EXPECT_EQ_COLLECTIONS(b1,e1,b2,e2) II_T_EQ_CLCT(b1,e1,b2,e2,II_E_FAIL)
#define IUTEST_INFORM_EQ_COLLECTIONS(b1,e1,b2,e2) II_T_EQ_CLCT(b1,e1,b2,e2,II_I_FAIL)
#define IUTEST_ASSUME_EQ_COLLECTIONS(b1,e1,b2,e2) II_T_EQ_CLCT(b1,e1,b2,e2,II_M_FAIL)
#define IUTEST_ASSERT_NE_COLLECTIONS(b1,e1,b2,e2) II_T_NE_CLCT(b1,e1,b2,e2,II_A_FAIL)
#define IUTEST_EXPECT_NE_COLLECTIONS(b1,e1,b2,e2) II_T_NE_CLCT(b1,e1,b2,e2,II_E_FAIL)
#define IUTEST_INFORM_NE_COLLECTIONS(b1,e1,b2,e2) II_T_NE_CLCT(b1,e1,b2,e2,II_I_FAIL)
#define IUTEST_ASSUME_NE_COLLECTIONS(b1,e1,b2,e2) II_T_NE_CLCT(b1,e1,b2,e2,II_M_FAIL)
#define IUTEST_ASSERT_EQ_RANGE(expected,actual) II_T_EQ_RNG(expected,actual,II_A_FAIL)
#define IUTEST_EXPECT_EQ_RANGE(expected,actual) II_T_EQ_RNG(expected,actual,II_E_FAIL)
#define IUTEST_INFORM_EQ_RANGE(expected,actual) II_T_EQ_RNG(expected,actual,II_I_FAIL)
#define IUTEST_ASSUME_EQ_RANGE(expected,actual) II_T_EQ_RNG(expected,actual,II_M_FAIL)
#define IUTEST_ASSERT_NE_RANGE(expected,actual) II_T_NE_RNG(expected,actual,II_A_FAIL)
#define IUTEST_EXPECT_NE_RANGE(expected,actual) II_T_NE_RNG(expected,actual,II_E_FAIL)
#define IUTEST_INFORM_NE_RANGE(expected,actual) II_T_NE_RNG(expected,actual,II_I_FAIL)
#define IUTEST_ASSUME_NE_RANGE(expected,actual) II_T_NE_RNG(expected,actual,II_M_FAIL)
#define IUTEST_ASSERT_STRLNEQ(len,v2) II_T_SLN(len,v2,II_A_FAIL)
#define IUTEST_EXPECT_STRLNEQ(len,v2) II_T_SLN(len,v2,II_E_FAIL)
#define IUTEST_INFORM_STRLNEQ(len,v2) II_T_SLN(len,v2,II_I_FAIL)
#define IUTEST_ASSUME_STRLNEQ(len,v2) II_T_SLN(len,v2,II_M_FAIL)
#define IUTEST_ASSERT_STRIN(substr,actual) II_T_SIN(substr,actual,II_A_FAIL)
#define IUTEST_EXPECT_STRIN(substr,actual) II_T_SIN(substr,actual,II_E_FAIL)
#define IUTEST_INFORM_STRIN(substr,actual) II_T_SIN(substr,actual,II_I_FAIL)
#define IUTEST_ASSUME_STRIN(substr,actual) II_T_SIN(substr,actual,II_M_FAIL)
#define IUTEST_ASSERT_STRNOTIN(substr,actual) II_T_SNIN(substr,actual,II_A_FAIL)
#define IUTEST_EXPECT_STRNOTIN(substr,actual) II_T_SNIN(substr,actual,II_E_FAIL)
#define IUTEST_INFORM_STRNOTIN(substr,actual) II_T_SNIN(substr,actual,II_I_FAIL)
#define IUTEST_ASSUME_STRNOTIN(substr,actual) II_T_SNIN(substr,actual,II_M_FAIL)
#if IUTEST_HAS_REGEX
#define IUTEST_ASSERT_MATCHES_REGEXEQ(regex_s,actual) II_T_M_RGE(regex_s,actual,II_A_FAIL)
#define IUTEST_EXPECT_MATCHES_REGEXEQ(regex_s,actual) II_T_M_RGE(regex_s,actual,II_E_FAIL)
#define IUTEST_INFORM_MATCHES_REGEXEQ(regex_s,actual) II_T_M_RGE(regex_s,actual,II_I_FAIL)
#define IUTEST_ASSUME_MATCHES_REGEXEQ(regex_s,actual) II_T_M_RGE(regex_s,actual,II_M_FAIL)
#define IUTEST_ASSERT_MATCHES_REGEXNE(regex_s,actual) II_T_M_RGN(regex_s,actual,II_A_FAIL)
#define IUTEST_EXPECT_MATCHES_REGEXNE(regex_s,actual) II_T_M_RGN(regex_s,actual,II_E_FAIL)
#define IUTEST_INFORM_MATCHES_REGEXNE(regex_s,actual) II_T_M_RGN(regex_s,actual,II_I_FAIL)
#define IUTEST_ASSUME_MATCHES_REGEXNE(regex_s,actual) II_T_M_RGN(regex_s,actual,II_M_FAIL)
#define IUTEST_ASSERT_CONTAINS_REGEXEQ(regex_s,actual) II_T_C_RGE(regex_s,actual,II_A_FAIL)
#define IUTEST_EXPECT_CONTAINS_REGEXEQ(regex_s,actual) II_T_C_RGE(regex_s,actual,II_E_FAIL)
#define IUTEST_INFORM_CONTAINS_REGEXEQ(regex_s,actual) II_T_C_RGE(regex_s,actual,II_I_FAIL)
#define IUTEST_ASSUME_CONTAINS_REGEXEQ(regex_s,actual) II_T_C_RGE(regex_s,actual,II_M_FAIL)
#define IUTEST_ASSERT_CONTAINS_REGEXNE(regex_s,actual) II_T_C_RGN(regex_s,actual,II_A_FAIL)
#define IUTEST_EXPECT_CONTAINS_REGEXNE(regex_s,actual) II_T_C_RGN(regex_s,actual,II_E_FAIL)
#define IUTEST_INFORM_CONTAINS_REGEXNE(regex_s,actual) II_T_C_RGN(regex_s,actual,II_I_FAIL)
#define IUTEST_ASSUME_CONTAINS_REGEXNE(regex_s,actual) II_T_C_RGN(regex_s,actual,II_M_FAIL)
#endif
#define II_T_EQ_CLCT(b1,e1,b2,e2,on_f) II_PRD_FMT4_(::iuutil::CmpHelperEqCollections,b1,e1,b2,e2,on_f)
#define II_T_NE_CLCT(b1,e1,b2,e2,on_f) II_PRD_FMT4_(::iuutil::CmpHelperNeCollections,b1,e1,b2,e2,on_f)
#define II_T_EQ_RNG(expected,actual,on_f) II_PRD_FMT2_(::iuutil::CmpHelperEqRange,expected,actual,on_f)
#define II_T_NE_RNG(expected,actual,on_f) II_PRD_FMT2_(::iuutil::CmpHelperNeRange,expected,actual,on_f)
#define II_T_SLN(len,v2,on_f) II_PRD_FMT2_(::iuutil::CmpHelperSTRLNEQ,len,v2,on_f)
#define II_T_SIN(substr,actual,on_f) II_PRD_FMT2_(::iuutil::CmpHelperSTRIN,substr,actual,on_f)
#define II_T_SNIN(substr,actual,on_f) II_PRD_FMT2_(::iuutil::CmpHelperSTRNOTIN,substr,actual,on_f)
#if IUTEST_HAS_REGEX
#define II_T_M_RGE(regex,actual,on_f) II_PRD_FMT2_(::iuutil::CmpHelperMatchesRegexEq,regex,actual,on_f)
#define II_T_M_RGN(regex,actual,on_f) II_PRD_FMT2_(::iuutil::CmpHelperMatchesRegexNe,regex,actual,on_f)
#define II_T_C_RGE(regex,actual,on_f) II_PRD_FMT2_(::iuutil::CmpHelperContainsRegexEq,regex,actual,on_f)
#define II_T_C_RGN(regex,actual,on_f) II_PRD_FMT2_(::iuutil::CmpHelperContainsRegexNe,regex,actual,on_f)
#endif
namespace iuutil{template<typename T1,typename T2>::iutest::AssertionResult II_ATR_U CmpHelperEqIterator(T1 b1,T1 e1,T2 b2,T2 e2){int elem=0;bool result=true;::iutest::Message ar;for(elem=0;b1!=e1&&b2!=e2;++b1,++b2,++elem){if(!::iutest::internal::bkw::EqHelper<false>::Compare("","",*b1,*b2)){result=false;ar<<"\nMismatch in a position " <<elem<<": "<< ::iutest::internal::FormatForComparisonFailureMessage(*b1,*b2)<< " vs " << ::iutest::internal::FormatForComparisonFailureMessage(*b2,*b1);}}if(b1!=e1){int elem1=elem;for(;b1!=e1;++b1,++elem1){}result=false;ar<<"\nMismatch element : " <<elem1<<" vs " <<elem;}if(b2!=e2){int elem2=elem;for(;b2!=e2;++b2,++elem2){}result=false;ar<<"\nMismatch element : " <<elem<<" vs " <<elem2;}if(!result){return ::iutest::AssertionFailure()<<ar;}return ::iutest::AssertionSuccess();}template<typename T1,typename T2>::iutest::AssertionResult II_ATR_U CmpHelperNeIterator(T1 b1,T1 e1,T2 b2,T2 e2){int elem=0;bool result=false;::iutest::Message ar;for(elem=0;b1!=e1&&b2!=e2;++b1,++b2,++elem){if(!::iutest::internal::bkw::NeHelper<false>::Compare("","",*b1,*b2)){ar<<::iutest::internal::FormatForComparisonFailureMessage(*b1,*b2);}else{result=true;}}if((b1!=e1)||(b2!=e2)){result=true;}if(!result){return ::iutest::AssertionFailure()<<ar;}return ::iutest::AssertionSuccess();}template<typename T1,typename T2>::iutest::AssertionResult II_ATR_U CmpHelperEqCollections(const char* expr1b,const char* expr1e,const char* expr2b,const char* expr2e,T1 b1,T1 e1,T2 b2,T2 e2){if(::iutest::AssertionResult ar=CmpHelperEqIterator(b1,e1,b2,e2)){return ::iutest::AssertionSuccess();}else{return ::iutest::AssertionFailure()<<"error: Expected: { " <<expr1b<<", " <<expr1e<<" } == { "<<expr2b<<", " <<expr2e<<" }\n  Actual:" <<GetAssertionResultMessage(ar);}}template<typename T1,typename T2>::iutest::AssertionResult II_ATR_U CmpHelperNeCollections(const char* expr1b,const char* expr1e,const char* expr2b,const char* expr2e,T1 b1,T1 e1,T2 b2,T2 e2){if(::iutest::AssertionResult ar=CmpHelperNeIterator(b1,e1,b2,e2)){return ::iutest::AssertionSuccess();}else{return ::iutest::AssertionFailure()<<"error: Expected: { " <<expr1b<<", " <<expr1e<<" } != { "<<expr2b<<", " <<expr2e<<" }\n  Actual:" <<GetAssertionResultMessage(ar);}}namespace detail{template<typename T1,typename T2>::iutest::AssertionResult II_ATR_U CmpHelperEqRange(const char* expected_expr,const char* actual_expr,T1 b1,T1 e1,T2 b2,T2 e2){if(::iutest::AssertionResult ar=CmpHelperEqIterator(b1,e1,b2,e2)){return ::iutest::AssertionSuccess();}else{return ::iutest::AssertionFailure()<<"error: Expected: " <<expected_expr<<" == " <<actual_expr<< " \n  Actual:" <<GetAssertionResultMessage(ar);}}}template<typename T1,typename T2>::iutest::AssertionResult II_ATR_U CmpHelperEqRange(const char* expected_expr,const char* actual_expr,const T1& expected,const T2& actual){IUTEST_USING_BEGIN_END();return detail::CmpHelperEqRange(expected_expr,actual_expr,begin(expected),end(expected),begin(actual),end(actual));}template<typename T1,typename T2>::iutest::AssertionResult II_ATR_U CmpHelperNeRange(const char* expected_expr,const char* actual_expr,const T1& expected,const T2& actual){IUTEST_USING_BEGIN_END();if(::iutest::AssertionResult ar =CmpHelperNeIterator(begin(expected),end(expected),begin(actual),end(actual))){return ::iutest::AssertionSuccess();}else{return ::iutest::AssertionFailure()<<"error: Expected: " <<expected_expr<<" != " <<actual_expr<< " \n  Actual:" << ::iutest::internal::FormatForComparisonFailureMessage(expected,actual);}}inline ::iutest::AssertionResult II_ATR_U CmpHelperSTRLNEQ(const char* expr1,const char* expr2,size_t len1,const char* val2){const size_t len2=strlen(val2);if(len2==len1){return ::iutest::AssertionSuccess();}return ::iutest::AssertionFailure()<<"error: Value of: " <<expr1<<" == strlen(" <<expr2<<")"<< "\n  Actual: " <<val2<<" : " <<len2<<"\nExpected: " <<len1;}inline ::iutest::AssertionResult II_ATR_U CmpHelperSTRLNEQ(const char* expr1,const char* expr2,size_t len1,const wchar_t* val2){const size_t len2=wcslen(val2);if(len2==len1){return ::iutest::AssertionSuccess();}return ::iutest::AssertionFailure()<<"error: Value of: " <<expr1<<" == wcslen(" <<expr2<<")"<< "\n  Actual: " <<val2<<" : " <<len2<<"\nExpected: " <<len1;}namespace StrInHelper{inline bool II_ATR_U Compare(const char* substr,const char* actual){if(substr==0||actual==0){return substr==actual;}return strstr(actual,substr)!=0;}inline bool II_ATR_U Compare(const wchar_t* substr,const wchar_t* actual){if(substr==0||actual==0){return substr==actual;}return wcsstr(actual,substr)!=0;}template<typename Elem,typename Traits,typename Ax>inline bool II_ATR_U Compare(const ::std::basic_string<Elem,Traits,Ax>& substr,const ::std::basic_string<Elem,Traits,Ax>& actual){return Compare(substr.c_str(),actual.c_str());}template<typename Elem,typename Traits,typename Ax>inline bool II_ATR_U Compare(const Elem* substr,const ::std::basic_string<Elem,Traits,Ax>& actual){return Compare(substr,actual.c_str());}template<typename Elem,typename Traits,typename Ax>inline bool II_ATR_U Compare(const ::std::basic_string<Elem,Traits,Ax>& substr,const Elem* actual){return Compare(substr.c_str(),actual);}template<typename T1,typename T2>inline ::iutest::AssertionResult II_ATR_U Assertion(const char* substr_str,const char* act_s,const T1& substr,const T2& actual){if(Compare(substr,actual)){return ::iutest::AssertionSuccess();}return ::iutest::AssertionFailure()<<"error: Expected: " << "strstr(" <<act_s<<", " <<substr_str<<") != 0"<< "\n  Actual: " << "strstr(\"" <<actual<<"\", " <<substr<<") == 0";}}template<typename T1,typename T2>inline ::iutest::AssertionResult II_ATR_U CmpHelperSTRIN(const char* substr_str,const char* act_s,const T1& substr,const T2& actual){return StrInHelper::Assertion(substr_str,act_s,substr,actual);}namespace StrNotInHelper{template<typename T1,typename T2>inline bool II_ATR_U Compare(const T1& substr,const T2& actual){return !StrInHelper::Compare(substr,actual);}template<typename T1,typename T2>inline ::iutest::AssertionResult II_ATR_U Assertion(const char* substr_str,const char* act_s,const T1& substr,const T2& actual){if(Compare(substr,actual)){return ::iutest::AssertionSuccess();}return ::iutest::AssertionFailure()<<"error: Expected: " << "strstr(" <<act_s<<", " <<substr_str<<") == 0"<< "\n  Actual: " << "strstr(\"" <<actual<<"\", " <<substr<<") != 0";}}template<typename T1,typename T2>inline ::iutest::AssertionResult II_ATR_U CmpHelperSTRNOTIN(const char* substr_str,const char* act_s,const T1& substr,const T2& actual){return StrNotInHelper::Assertion(substr_str,act_s,substr,actual);}
#if IUTEST_HAS_REGEX
namespace RegexHelper{inline bool FullMatch(const ::std::string& str,const ::iutest::internal::RE& re){return ::iutest::internal::RE::FullMatch(str,re);}inline bool FullMatch(const char* str,const ::iutest::internal::RE& re){if(str==0){return false;}return ::iutest::internal::RE::FullMatch(str,re);}inline bool PartialMatch(const ::std::string& str,const ::iutest::internal::RE& re){return ::iutest::internal::RE::PartialMatch(str,re);}inline bool PartialMatch(const char* str,const ::iutest::internal::RE& re){if(str==0){return false;}return ::iutest::internal::RE::PartialMatch(str,re);}}namespace MatchesRegexEqHelper{template<typename T1,typename T2>inline bool II_ATR_U Compare(const T1& regex,const T2& actual){::iutest::internal::RE iure(regex);return RegexHelper::FullMatch(actual,iure);}template<typename T1,typename T2>inline ::iutest::AssertionResult II_ATR_U Assertion(const char* regex_s,const char* act_s,const T1& regex,const T2& actual){if(Compare(regex,actual)){return ::iutest::AssertionSuccess();}::std::string exp_s="Matches Regex (";exp_s+=regex_s;exp_s+=")";return ::iutest::internal::EqFailure(exp_s.c_str(),act_s,::iutest::PrintToString(regex),::iutest::PrintToString(actual),false);}}inline ::iutest::AssertionResult II_ATR_U CmpHelperMatchesRegexEq(const char* regex_s,const char* act_s,const char* regex,const char* actual){return MatchesRegexEqHelper::Assertion(regex_s,act_s,regex,actual);}namespace MatchesRegexNeHelper{template<typename T1,typename T2>inline ::iutest::AssertionResult II_ATR_U Assertion(const char* regex_s,const char* act_s,const T1& regex,const T2& actual){if(!MatchesRegexEqHelper::Compare(regex,actual)){return ::iutest::AssertionSuccess();}::std::string exp_s="Not Matches Regex (";exp_s+=regex_s;exp_s+=")";return ::iutest::internal::EqFailure(exp_s.c_str(),act_s,::iutest::PrintToString(regex),::iutest::PrintToString(actual),false);}}inline ::iutest::AssertionResult II_ATR_U CmpHelperMatchesRegexNe(const char* regex_s,const char* act_s,const char* regex,const char* actual){return MatchesRegexNeHelper::Assertion(regex_s,act_s,regex,actual);}namespace ContainsRegexEqHelper{template<typename T1,typename T2>inline bool II_ATR_U Compare(const T1& regex,const T2& actual){::iutest::internal::RE m(regex);return RegexHelper::PartialMatch(actual,m);}template<typename T1,typename T2>inline ::iutest::AssertionResult II_ATR_U Assertion(const char* regex_s,const char* act_s,const T1& regex,const T2& actual){if(Compare(regex,actual)){return ::iutest::AssertionSuccess();}::std::string exp_s="Contains Regex (";exp_s+=regex_s;exp_s+=")";return ::iutest::internal::EqFailure(exp_s.c_str(),act_s,::iutest::PrintToString(regex),::iutest::PrintToString(actual),false);}}inline ::iutest::AssertionResult II_ATR_U CmpHelperContainsRegexEq(const char* regex_s,const char* act_s,const char* regex,const char* actual){return ContainsRegexEqHelper::Assertion(regex_s,act_s,regex,actual);}namespace ContainsRegexNeHelper{template<typename T1,typename T2>inline ::iutest::AssertionResult II_ATR_U Assertion(const char* regex_s,const char* act_s,const T1& regex,const T2& actual){if(!ContainsRegexEqHelper::Compare(regex,actual)){return ::iutest::AssertionSuccess();}::std::string exp_s="Not Contains Regex (";exp_s+=regex_s;exp_s+=")";return ::iutest::internal::EqFailure(exp_s.c_str(),act_s,::iutest::PrintToString(regex),::iutest::PrintToString(actual),false);}}inline ::iutest::AssertionResult II_ATR_U CmpHelperContainsRegexNe(const char* regex_s,const char* act_s,const char* regex,const char* actual){return ContainsRegexNeHelper::Assertion(regex_s,act_s,regex,actual);}
#endif
}
namespace iuutil{typedef ::iutest::detail::iuConsole Console;}namespace iuutil{class QuietResultPrinter:public ::iutest::TestEventListener{public: explicit QuietResultPrinter(::iutest::TestEventListener* default_printer):m_default_printer(default_printer){}virtual ~QuietResultPrinter(){delete m_default_printer;}public: virtual void OnTestProgramStart(const ::iutest::UnitTest& unit_test) II_CXX_O{m_default_printer->OnTestProgramStart(unit_test);}virtual void OnTestIterationStart(const ::iutest::UnitTest& unit_test,int iteration) II_CXX_O{m_default_printer->OnTestIterationStart(unit_test,iteration);}virtual void OnEnvironmentsSetUpStart(const ::iutest::UnitTest& unit_test) II_CXX_O{m_default_printer->OnEnvironmentsSetUpStart(unit_test);}virtual void OnEnvironmentsSetUpEnd(const ::iutest::UnitTest& unit_test) II_CXX_O{m_default_printer->OnEnvironmentsSetUpEnd(unit_test);}virtual void OnTestCaseStart(const ::iutest::TestCase& test_case) II_CXX_O{m_default_printer->OnTestCaseStart(test_case);}virtual void OnTestStart(const ::iutest::TestInfo& test_info) II_CXX_O{m_default_printer->OnTestStart(test_info);}virtual void OnTestPartResult(const ::iutest::TestPartResult& test_part_result) II_CXX_O{m_default_printer->OnTestPartResult(test_part_result);}virtual void OnTestEnd(const ::iutest::TestInfo& test_info) II_CXX_O{if(test_info.result()->Failed()){m_default_printer->OnTestEnd(test_info);}}virtual void OnTestCaseEnd(const ::iutest::TestCase& test_case) II_CXX_O{m_default_printer->OnTestCaseEnd(test_case);}virtual void OnEnvironmentsTearDownStart(const ::iutest::UnitTest& unit_test) II_CXX_O{m_default_printer->OnEnvironmentsTearDownStart(unit_test);}virtual void OnEnvironmentsTearDownEnd(const ::iutest::UnitTest& unit_test) II_CXX_O{m_default_printer->OnEnvironmentsTearDownEnd(unit_test);}virtual void OnTestIterationEnd(const ::iutest::UnitTest& unit_test,int iteration) II_CXX_O{m_default_printer->OnTestIterationEnd(unit_test,iteration);}virtual void OnTestProgramEnd(const ::iutest::UnitTest& unit_test) II_CXX_O{m_default_printer->OnTestProgramEnd(unit_test);}private: ::iutest::TestEventListener* m_default_printer;public: static ::iutest::TestEventListener* SetUp(){::iutest::TestEventListeners& listeners=::iutest::UnitTest::GetInstance()->listeners();::iutest::TestEventListener* default_printer=listeners.Release(listeners.default_result_printer());if(default_printer==0){return 0;}::iutest::TestEventListener* p=new QuietResultPrinter(default_printer);listeners.Append(p);return p;}};}namespace iuutil{inline ::std::string TestFullName(const ::iutest::TestInfo* test_info){::std::string fullname=test_info->test_case_name();fullname+=".";fullname+=test_info->name();return fullname;}inline ::std::string TestNameRemoveIndexName(const char* name){const char* const p=strrchr(name,'/');if(p==0){return name;}return ::std::string(name,p);}inline ::std::string TestCaseNameRemoveIndexName(const char* name){return TestNameRemoveIndexName(name);}inline ::std::string TestCaseNameRemoveInstantiateAndIndexName(const char* name){const char* const pkg=strrchr(name,'.');const char* const p1=strchr(name,'/');if(p1==0){return name;}if(pkg==0){return TestCaseNameRemoveIndexName(p1+1);}else{return ::std::string(name,pkg+1)+TestCaseNameRemoveIndexName(p1+1);}}inline const ::iutest::TestCase* FindTestCase(const char* t_c_name){if(t_c_name==0){return 0;}const int t_c_count=::iutest::UnitTest::GetInstance()->total_test_case_count();for(int i=0;i<t_c_count;++i){const ::iutest::TestCase* testcase=::iutest::UnitTest::GetInstance()->GetTestCase(i);if(strcmp(testcase->name(),t_c_name)==0){return testcase;}}return 0;}inline const ::iutest::TestCase* FindParamTestCase(const char* t_c_name,const ::iutest::TestCase* begin=0){if(t_c_name==0){return 0;}const int t_c_count=::iutest::UnitTest::GetInstance()->total_test_case_count();int i=0;if(begin!=0){for(;i<t_c_count;++i){const ::iutest::TestCase* testcase=::iutest::UnitTest::GetInstance()->GetTestCase(i);if(testcase==begin){break;}}++i;}for(;i<t_c_count;++i){const ::iutest::TestCase* testcase=::iutest::UnitTest::GetInstance()->GetTestCase(i);const char* t_c_origin_name=strchr(testcase->name(),'/');if(t_c_origin_name!=0){if(strcmp(t_c_origin_name+1,t_c_name)==0){return testcase;}}}return 0;}inline const ::iutest::TestCase* FindTypedTestCase(const char* t_c_name,const ::iutest::TestCase* begin=0){if(t_c_name==0){return 0;}const int t_c_count=::iutest::UnitTest::GetInstance()->total_test_case_count();int i=0;if(begin!=0){for(;i<t_c_count;++i){const ::iutest::TestCase* testcase=::iutest::UnitTest::GetInstance()->GetTestCase(i);if(testcase==begin){break;}}++i;}for(;i<t_c_count;++i){const ::iutest::TestCase* testcase=::iutest::UnitTest::GetInstance()->GetTestCase(i);if(testcase!=0){const char* name=testcase->name();if(name!=0&& strstr(name,t_c_name)==name&& name[strlen(t_c_name)]=='/'){return testcase;}}}return 0;}inline const ::iutest::TestCase* FindParamTypedTestCase(const char* t_c_name,const ::iutest::TestCase* begin=0){if(t_c_name==0){return 0;}const int t_c_count=::iutest::UnitTest::GetInstance()->total_test_case_count();int i=0;if(begin!=0){for(;i<t_c_count;++i){const ::iutest::TestCase* testcase=::iutest::UnitTest::GetInstance()->GetTestCase(i);if(testcase==begin){break;}}++i;}for(;i<t_c_count;++i){const ::iutest::TestCase* testcase=::iutest::UnitTest::GetInstance()->GetTestCase(i);const char* name=strchr(testcase->name(),'/');if(name!=0){++name;if(strstr(name,t_c_name)==name&& name[strlen(t_c_name)]=='/'){return testcase;}}}return 0;}inline const ::iutest::TestInfo* FindTestInfo(const ::iutest::TestCase* testcase,const char* testinfo_name){if(testcase==0||testinfo_name==0){return 0;}const int testinfo_count=testcase->total_test_count();for(int i=0;i<testinfo_count;++i){const ::iutest::TestInfo* testinfo=testcase->GetTestInfo(i);if(strcmp(testinfo->name(),testinfo_name)==0){return testinfo;}}return 0;}inline const ::iutest::TestInfo* FindTestInfo(const char* t_c_name,const char* testinfo_name){if(t_c_name==0||testinfo_name==0){return 0;}const ::iutest::TestCase* testcase=FindTestCase(t_c_name);return FindTestInfo(testcase,testinfo_name);}inline const ::iutest::TestInfo* FindParamTestInfo(const ::iutest::TestCase* testcase,const char* testinfo_name,const ::iutest::TestInfo* begin=0){if(testcase==0||testinfo_name==0){return 0;}const int testinfo_count=testcase->total_test_count();int i=0;if(begin!=0){for(;i<testinfo_count;++i){const ::iutest::TestInfo* testinfo=testcase->GetTestInfo(i);if(testinfo==begin){break;}}++i;}for(;i<testinfo_count;++i){const ::iutest::TestInfo* testinfo=testcase->GetTestInfo(i);if(testinfo!=0){const char* name=testinfo->name();if(name!=0&& strstr(name,testinfo_name)==name&& name[strlen(testinfo_name)]=='/'){return testinfo;}}}return 0;}inline const ::iutest::TestResult* TestResultPointer(const ::iutest::TestResult* result){return result;}inline const ::iutest::TestResult* TestResultPointer(const ::iutest::TestResult& result){return &result;}inline const ::iutest::TestResult* GetAdHocTestResult(){return TestResultPointer(::iutest::UnitTest::GetInstance()->ad_hoc_test_result());}inline const ::iutest::TestResult* GetTestCaseAdHocResult(const ::iutest::TestCase* test_case){return TestResultPointer(test_case->ad_hoc_test_result());}inline const ::iutest::TestResult* GetCurrentTestCaseAdHocResult(){return GetTestCaseAdHocResult(::iutest::UnitTest::GetInstance()->current_test_case());}inline const ::iutest::TestResult* GetTestResult(const ::iutest::TestInfo* test_info){return TestResultPointer(test_info->result());}inline const ::iutest::TestResult* GetCurrentTestResult(){return GetTestResult(::iutest::UnitTest::GetInstance()->current_test_info());}}namespace iuutil{}
#define IUTEST_FILESYSTEM_INSTANTIATE(file_class_name) II_FS_I_(file_class_name)
#define II_FS_I_(file_class_name) static ::iutest::FileSystem<file_class_name>II_ATR_U s_iutest_filesystem_
#ifdef IUTEST_USE_MAIN
int main(int argc,char** argv){setlocale(LC_CTYPE,"");IUTEST_INIT(&argc,argv);return IUTEST_RUN_ALL_TESTS();}
#endif
#endif
#define IUTEST_CXX_CONSTEXPR II_CXX_CE
#define IUTEST_CXX14_CONSTEXPR II_CXX14_CE
#define IUTEST_CXX_CONSTEXPR_OR_CONST II_CXX_C_O_C
#define IUTEST_CXX_DELETED_FUNCTION II_CXX_DL_F
#define IUTEST_CXX_DEFAULT_FUNCTION II_CXX_DF_F
#define IUTEST_CXX_EXPLICIT_CONVERSION II_CXX_E_C
#define IUTEST_CXX_OVERRIDE II_CXX_O
#define IUTEST_CXX_FINAL II_CXX_F
#define IUTEST_CXX_NOEXCEPT_SPEC II_CXX_NEX_S
#define IUTEST_ATTRIBUTE_UNUSED_ II_ATR_U
#define IUTEST_ATTRIBUTE_NORETURN_ II_ATR_NR
#define IUTEST_ATTRIBUTE_FORMAT II_ATR_F
#define IUTEST_ATTRIBUTE_FORMAT_PRINTF II_ATR_F_P
#define IUTEST_PRAGMA_CLANG_WARN_PUSH II_PGM_C_W_PU
#define IUTEST_PRAGMA_CLANG_WARN_DISABLE II_PGM_C_W_D
#define IUTEST_PRAGMA_CLANG_WARN_POP II_PGM_C_W_PP
#define IUTEST_PRAGMA_GCC_WARN_PUSH II_PGM_G_W_PU
#define IUTEST_PRAGMA_GCC_WARN_DISABLE II_PGM_G_W_D
#define IUTEST_PRAGMA_GCC_WARN_POP II_PGM_G_W_PP
#define IUTEST_PRAGMA_WARN_PUSH II_PGM_W_PU
#define IUTEST_PRAGMA_WARN_POP II_PGM_W_PP
#define IUTEST_PRAGMA_ASSIGNMENT_OPERATOR_COULD_NOT_GENERATE_WARN_DISABLE_BEGIN II_PGM_A_O_CN_G_W_D_B
#define IUTEST_PRAGMA_ASSIGNMENT_OPERATOR_COULD_NOT_GENERATE_WARN_DISABLE_END II_PGM_A_O_CN_G_W_D_E
#define IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE II_PGM_W_D_S_C
#define IUTEST_PRAGMA_WARN_FLOAT_EQUAL II_PGM_W_FE
#define IUTEST_PRAGMA_WARN_CAST_ALIGN II_PGM_W_CA
#define IUTEST_PRAGMA_WARN_DISABLE_DANGLING_ELSE II_PGM_W_D_D_E
#define IUTEST_PRAGMA_WARN_DISABLE_NOEXCEPT_TPYE II_PGM_W_D_NE_T
#define IUTEST_PP_DISALLOW_COPY_AND_ASSIGN IP_DIS_C_A_A
#define IUTEST_PP_DISALLOW_ASSIGN IP_DIS_A
#define IUTEST_PP_DISALLOW_MOVE_AND_COPY_AND_ASSIGN IP_DIS_M_A_C_A_A
#define IUTEST_PP_CAT IP_CAT
#define IUTEST_PP_NAMESPACE_ENUM_CASE_RETURN_STRING IP_NS_E_C_R_S
#define IUTEST_PP_DEC IP_DEC
#define IUTEST_PP_INC IP_INC
#define IUTEST_PP_ENUM_PARAMS IP_ENM_P
#define IUTEST_PP_ENUM IP_ENM
#define IUTEST_PP_ENUM_SHIFTED_PARAMS IP_ENM_S_P
#define IUTEST_PP_ENUM_SHIFTED IP_ENM_S
#define IUTEST_PP_ENUM_BINARY_PARAMS IP_ENM_B_P
#define IUTEST_PP_ENUM_BINARY IP_ENM_B
#define IUTEST_PP_ENUM_SHIFTED_BINARY_PARAMS IP_ENM_S_B_P
#define IUTEST_PP_ENUM_SHIFTED_BINARY IP_ENM_S_B
#define IUTEST_PP_EMPTY IP_EMPTY
#define IUTEST_PP_IS_BEGIN_PARENS IP_IS_B_PAR
#define IUTEST_LIBSTDCXX_VERSION II_LSTDCXX_V
#define IUTEST_AMBIGUOUS_ELSE_BLOCKER_ II_AMB_E_B
#define IUTEST_SUPPRESS_UNREACHABLE_CODE_WARNING II_S_UR_C_W
#define IUTEST_APPEND_EXPLICIT_TEMPLATE_TYPE_ II_A_E_TT
#define IUTEST_IS_NULLLITERAL II_IS_NL
#define IUTEST_PRED1_ II_PRD1_
#define IUTEST_PRED_FORMAT1_ II_PRD_FMT1_
#define IUTEST_PRED2_ II_PRD2_
#define IUTEST_PRED_FORMAT2_ II_PRD_FMT2_
#define IUTEST_PRED3_ II_PRD3_
#define IUTEST_PRED_FORMAT3_ II_PRD_FMT3_
#define IUTEST_PRED4_ II_PRD4_
#define IUTEST_PRED_FORMAT4_ II_PRD_FMT4_
#define IUTEST_PRED5_ II_PRD5_
#define IUTEST_PRED_FORMAT5_ II_PRD_FMT5_
#define IUTEST_PRED_ II_PRD_
#define IUTEST_PRED_FORMAT_ II_PRD_FMT_
#define IUTEST_THROW_PRED_FORMAT2_ II_T_PRD_FMT2_
#define IUTEST_TEST_CLASS_NAME_ II_T_CLS_N_
#define IUTEST_TEST_INSTANCE_NAME_ II_T_INST_N_
#define IUTEST_ALIAS_TESTNAME_ II_ALS_TN
#define IUTEST_ALIAS_TESTNAME_F_ II_ALS_TN_F_
#define IUTEST_PMZ_TEST_CLASS_NAME_ II_P_T_CLS_N_
#define IUTEST_MESSAGE_AT II_MSG_AT
#define IUTEST_MESSAGE II_MSG
#define IUTEST_ASSERT_FAILURE II_A_FAIL
#define IUTEST_ASSERT_FAILURE_AT II_A_FAIL_AT
#define IUTEST_EXPECT_FAILURE II_E_FAIL
#define IUTEST_EXPECT_FAILURE_AT II_E_FAIL_AT
#define IUTEST_INFORM_FAILURE II_I_FAIL
#define IUTEST_INFORM_FAILURE_AT II_I_FAIL_AT
#define IUTEST_ASSUME_FAILURE II_M_FAIL
#define IUTEST_ASSUME_FAILURE_AT II_M_FAIL_AT
#define IUTEST_TEST_ASSERT_ II_T_ASRT_
#define IUTEST_THROUGH_ANALYSIS_ASSUME_ II_TRGH_A_A_
#define IUTEST_ALIAS_TESTNAME_F II_ALS_TN_F
#define IUTEST_TEST_EQ_COLLECTIONS II_T_EQ_CLCT
#define IUTEST_TEST_NE_COLLECTIONS II_T_NE_CLCT
#define IUTEST_TEST_EQ_RANGE II_T_EQ_RNG
#define IUTEST_TEST_NE_RANGE II_T_NE_RNG
#define IUTEST_TEST_STRLNEQ II_T_SLN
#define IUTEST_TEST_STRIN II_T_SIN
#define IUTEST_TEST_STRNOTIN II_T_SNIN
#define IUTEST_TEST_MATCHES_REGEXEQ II_T_M_RGE
#define IUTEST_TEST_MATCHES_REGEXNE II_T_M_RGN
#define IUTEST_TEST_CONTAINS_REGEXEQ II_T_C_RGE
#define IUTEST_TEST_CONTAINS_REGEXNE II_T_C_RGN
