//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_pred.hpp
 * @brief		iris unit test 述語 Assertion ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PRED_HPP_ADF851F3_C89B_4CA4_B9A0_A2B2229945C6_
#define INCG_IRIS_IUTEST_PRED_HPP_ADF851F3_C89B_4CA4_B9A0_A2B2229945C6_

//======================================================================
// include
#include "iutest_assertion.hpp"

//======================================================================
// define

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
*/
#define IUTEST_ASSERT_PRED1(pred, v1)		\
	IUTEST_PRED1_(pred, v1, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
*/
#define IUTEST_EXPECT_PRED1(pred, v1)		\
	IUTEST_PRED1_(pred, v1, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
*/
#define IUTEST_INFORM_PRED1(pred, v1)		\
	IUTEST_PRED1_(pred, v1, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
*/
#define IUTEST_ASSUME_PRED1(pred, v1)		\
	IUTEST_PRED1_(pred, v1, IUTEST_ASSUME_FAILURE)

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
*/
#define IUTEST_ASSERT_PRED_FORMAT1(pred_formatter, v1)		\
	IUTEST_PRED_FORMAT1_(pred_formatter, v1, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
*/
#define IUTEST_EXPECT_PRED_FORMAT1(pred_formatter, v1)		\
	IUTEST_PRED_FORMAT1_(pred_formatter, v1, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
*/
#define IUTEST_INFORM_PRED_FORMAT1(pred_formatter, v1)		\
	IUTEST_PRED_FORMAT1_(pred_formatter, v1, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
*/
#define IUTEST_ASSUME_PRED_FORMAT1(pred_formatter, v1)		\
	IUTEST_PRED_FORMAT1_(pred_formatter, v1, IUTEST_ASSUME_FAILURE)


/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
*/
#define IUTEST_ASSERT_PRED2(pred, v1, v2)		\
	IUTEST_PRED2_(pred, v1, v2, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
*/
#define IUTEST_EXPECT_PRED2(pred, v1, v2)		\
	IUTEST_PRED2_(pred, v1, v2, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
*/
#define IUTEST_INFORM_PRED2(pred, v1, v2)		\
	IUTEST_PRED2_(pred, v1, v2, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
*/
#define IUTEST_ASSUME_PRED2(pred, v1, v2)		\
	IUTEST_PRED2_(pred, v1, v2, IUTEST_ASSUME_FAILURE)

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
*/
#define IUTEST_ASSERT_PRED_FORMAT2(pred_formatter, v1, v2)		\
	IUTEST_PRED_FORMAT2_(pred_formatter, v1, v2, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
*/
#define IUTEST_EXPECT_PRED_FORMAT2(pred_formatter, v1, v2)		\
	IUTEST_PRED_FORMAT2_(pred_formatter, v1, v2, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
*/
#define IUTEST_INFORM_PRED_FORMAT2(pred_formatter, v1, v2)		\
	IUTEST_PRED_FORMAT2_(pred_formatter, v1, v2, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
*/
#define IUTEST_ASSUME_PRED_FORMAT2(pred_formatter, v1, v2)		\
	IUTEST_PRED_FORMAT2_(pred_formatter, v1, v2, IUTEST_ASSUME_FAILURE)


/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
*/
#define IUTEST_ASSERT_PRED3(pred, v1, v2, v3)		\
	IUTEST_PRED3_(pred, v1, v2, v3, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
*/
#define IUTEST_EXPECT_PRED3(pred, v1, v2, v3)		\
	IUTEST_PRED3_(pred, v1, v2, v3, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
*/
#define IUTEST_INFORM_PRED3(pred, v1, v2, v3)		\
	IUTEST_PRED3_(pred, v1, v2, v3, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
*/
#define IUTEST_ASSUME_PRED3(pred, v1, v2, v3)		\
	IUTEST_PRED3_(pred, v1, v2, v3, IUTEST_ASSUME_FAILURE)

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
*/
#define IUTEST_ASSERT_PRED_FORMAT3(pred_formatter, v1, v2, v3)		\
	IUTEST_PRED_FORMAT3_(pred_formatter, v1, v2, v3, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
*/
#define IUTEST_EXPECT_PRED_FORMAT3(pred_formatter, v1, v2, v3)		\
	IUTEST_PRED_FORMAT3_(pred_formatter, v1, v2, v3, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
*/
#define IUTEST_INFORM_PRED_FORMAT3(pred_formatter, v1, v2, v3)		\
	IUTEST_PRED_FORMAT3_(pred_formatter, v1, v2, v3, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
*/
#define IUTEST_ASSUME_PRED_FORMAT3(pred_formatter, v1, v2, v3)		\
	IUTEST_PRED_FORMAT3_(pred_formatter, v1, v2, v3, IUTEST_ASSUME_FAILURE)


/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
 * @param	v4		= 引数4
*/
#define IUTEST_ASSERT_PRED4(pred, v1, v2, v3, v4)		\
	IUTEST_PRED4_(pred, v1, v2, v3, v4, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
 * @param	v4		= 引数4
*/
#define IUTEST_EXPECT_PRED4(pred, v1, v2, v3, v4)		\
	IUTEST_PRED4_(pred, v1, v2, v3, v4, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
 * @param	v4		= 引数4
*/
#define IUTEST_INFORM_PRED4(pred, v1, v2, v3, v4)		\
	IUTEST_PRED4_(pred, v1, v2, v3, v4, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
 * @param	v4		= 引数4
*/
#define IUTEST_ASSUME_PRED4(pred, v1, v2, v3, v4)		\
	IUTEST_PRED4_(pred, v1, v2, v3, v4, IUTEST_ASSUME_FAILURE)

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
 * @param	v4				= 引数4
*/
#define IUTEST_ASSERT_PRED_FORMAT4(pred_formatter, v1, v2, v3, v4)		\
	IUTEST_PRED_FORMAT4_(pred_formatter, v1, v2, v3, v4, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
 * @param	v4				= 引数4
*/
#define IUTEST_EXPECT_PRED_FORMAT4(pred_formatter, v1, v2, v3, v4)		\
	IUTEST_PRED_FORMAT4_(pred_formatter, v1, v2, v3, v4, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
 * @param	v4				= 引数4
*/
#define IUTEST_INFORM_PRED_FORMAT4(pred_formatter, v1, v2, v3, v4)		\
	IUTEST_PRED_FORMAT4_(pred_formatter, v1, v2, v3, v4, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
 * @param	v4				= 引数4
*/
#define IUTEST_ASSUME_PRED_FORMAT4(pred_formatter, v1, v2, v3, v4)		\
	IUTEST_PRED_FORMAT4_(pred_formatter, v1, v2, v3, v4, IUTEST_ASSUME_FAILURE)



/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
 * @param	v4		= 引数4
 * @param	v5		= 引数5
*/
#define IUTEST_ASSERT_PRED5(pred, v1, v2, v3, v4, v5)		\
	IUTEST_PRED5_(pred, v1, v2, v3, v4, v5, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
 * @param	v4		= 引数4
 * @param	v5		= 引数5
*/
#define IUTEST_EXPECT_PRED5(pred, v1, v2, v3, v4, v5)		\
	IUTEST_PRED5_(pred, v1, v2, v3, v4, v5, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
 * @param	v4		= 引数4
 * @param	v5		= 引数5
*/
#define IUTEST_INFORM_PRED5(pred, v1, v2, v3, v4, v5)		\
	IUTEST_PRED5_(pred, v1, v2, v3, v4, v5, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	v1		= 引数1
 * @param	v2		= 引数2
 * @param	v3		= 引数3
 * @param	v4		= 引数4
 * @param	v5		= 引数5
*/
#define IUTEST_ASSUME_PRED5(pred, v1, v2, v3, v4, v5)		\
	IUTEST_PRED5_(pred, v1, v2, v3, v4, v5, IUTEST_ASSUME_FAILURE)

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
 * @param	v4				= 引数4
 * @param	v5				= 引数5
*/
#define IUTEST_ASSERT_PRED_FORMAT5(pred_formatter, v1, v2, v3, v4, v5)		\
	IUTEST_PRED_FORMAT5_(pred_formatter, v1, v2, v3, v4, v5, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
 * @param	v4				= 引数4
 * @param	v5				= 引数5
*/
#define IUTEST_EXPECT_PRED_FORMAT5(pred_formatter, v1, v2, v3, v4, v5)		\
	IUTEST_PRED_FORMAT5_(pred_formatter, v1, v2, v3, v4, v5, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
 * @param	v4				= 引数4
 * @param	v5				= 引数5
*/
#define IUTEST_INFORM_PRED_FORMAT5(pred_formatter, v1, v2, v3, v4, v5)		\
	IUTEST_PRED_FORMAT5_(pred_formatter, v1, v2, v3, v4, v5, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	v1				= 引数1
 * @param	v2				= 引数2
 * @param	v3				= 引数3
 * @param	v4				= 引数4
 * @param	v5				= 引数5
*/
#define IUTEST_ASSUME_PRED_FORMAT5(pred_formatter, v1, v2, v3, v4, v5)		\
	IUTEST_PRED_FORMAT5_(pred_formatter, v1, v2, v3, v4, v5, IUTEST_ASSUME_FAILURE)


#ifndef IUTEST_NO_VARIADIC_MACROS

#if IUTEST_HAS_VARIADIC_TEMPLATES

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	...		= 引数
*/
#define IUTEST_ASSERT_PRED(pred, ...)		\
	IUTEST_PRED_(pred, IUTEST_ASSERT_FAILURE, __VA_ARGS__)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	...		= 引数
*/
#define IUTEST_EXPECT_PRED(pred, ...)		\
	IUTEST_PRED_(pred, IUTEST_EXPECT_FAILURE, __VA_ARGS__)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	...		= 引数
*/
#define IUTEST_INFORM_PRED(pred, ...)		\
	IUTEST_PRED_(pred, IUTEST_INFORM_FAILURE, __VA_ARGS__)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト
 * @param	pred	= 述語
 * @param	...		= 引数
*/
#define IUTEST_ASSUME_PRED(pred, ...)		\
	IUTEST_PRED_(pred, IUTEST_ASSUME_FAILURE, __VA_ARGS__)

#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	...				= 引数
*/
#define IUTEST_ASSERT_PRED_FORMAT(pred_formatter, ...)		\
	IUTEST_PRED_FORMAT_(pred_formatter, IUTEST_ASSERT_FAILURE, __VA_ARGS__)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	...				= 引数
*/
#define IUTEST_EXPECT_PRED_FORMAT(pred_formatter, ...)		\
	IUTEST_PRED_FORMAT_(pred_formatter, IUTEST_EXPECT_FAILURE, __VA_ARGS__)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	...				= 引数
*/
#define IUTEST_INFORM_PRED_FORMAT(pred_formatter, ...)		\
	IUTEST_PRED_FORMAT_(pred_formatter, IUTEST_INFORM_FAILURE, __VA_ARGS__)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter	= 述語フォーマッター
 * @param	...				= 引数
*/
#define IUTEST_ASSUME_PRED_FORMAT(pred_formatter, ...)		\
	IUTEST_PRED_FORMAT_(pred_formatter, IUTEST_ASSUME_FAILURE, __VA_ARGS__)

#endif


/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	例外値 述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter			= 述語フォーマッター
 * @param	statement				= ステートメント
 * @param	expected_exception		= 期待する例外
 * @param	expected_exception_value= 期待値
*/
#define IUTEST_ASSERT_THROW_PRED_FORMAT2(pred_formatter, statement, expected_exception, expected_exception_value)		\
	IUTEST_THROW_PRED_FORMAT2_(pred_formatter, statement, expected_exception, expected_exception_value, IUTEST_ASSERT_FAILURE)
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	例外値 述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter			= 述語フォーマッター
 * @param	statement				= ステートメント
 * @param	expected_exception		= 期待する例外
 * @param	expected_exception_value= 期待値
*/
#define IUTEST_EXPECT_THROW_PRED_FORMAT2(pred_formatter, statement, expected_exception, expected_exception_value)		\
	IUTEST_THROW_PRED_FORMAT2_(pred_formatter, statement, expected_exception, expected_exception_value, IUTEST_EXPECT_FAILURE)
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	例外値 述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter			= 述語フォーマッター
 * @param	statement				= ステートメント
 * @param	expected_exception		= 期待する例外
 * @param	expected_exception_value= 期待値
*/
#define IUTEST_INFORM_THROW_PRED_FORMAT2(pred_formatter, statement, expected_exception, expected_exception_value)		\
	IUTEST_THROW_PRED_FORMAT2_(pred_formatter, statement, expected_exception, expected_exception_value, IUTEST_INFORM_FAILURE)
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	例外値 述語 ASSERTION テスト(メッセージフォーマッター指定)
 * @param	pred_formatter			= 述語フォーマッター
 * @param	statement				= ステートメント
 * @param	expected_exception		= 期待する例外
 * @param	expected_exception_value= 期待値
*/
#define IUTEST_ASSUME_THROW_PRED_FORMAT2(pred_formatter, statement, expected_exception, expected_exception_value)		\
	IUTEST_THROW_PRED_FORMAT2_(pred_formatter, statement, expected_exception, expected_exception_value, IUTEST_ASSUME_FAILURE)


/**
 * @private
 * @{
*/

#define IUTEST_PRED1_(pred, v1, on_failure)	\
	IUTEST_TEST_ASSERT_(::iutest::AssertPred1Helper(#pred, #v1, pred, v1), on_failure)
#define IUTEST_PRED_FORMAT1_(pred_formatter, v1, on_failure)	\
	IUTEST_TEST_ASSERT_(pred_formatter(#v1, v1), on_failure)


#define IUTEST_PRED2_(pred, v1, v2, on_failure)	\
	IUTEST_TEST_ASSERT_(::iutest::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), on_failure)
#define IUTEST_PRED_FORMAT2_(pred_formatter, v1, v2, on_failure)	\
	IUTEST_TEST_ASSERT_(pred_formatter(#v1, #v2, v1, v2), on_failure)


#define IUTEST_PRED3_(pred, v1, v2, v3, on_failure)	\
	IUTEST_TEST_ASSERT_(::iutest::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), on_failure)
#define IUTEST_PRED_FORMAT3_(pred_formatter, v1, v2, v3, on_failure)	\
	IUTEST_TEST_ASSERT_(pred_formatter(#v1, #v2, #v3, v1, v2, v3), on_failure)


#define IUTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)	\
	IUTEST_TEST_ASSERT_(::iutest::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, v1, v2, v3, v4), on_failure)
#define IUTEST_PRED_FORMAT4_(pred_formatter, v1, v2, v3, v4, on_failure)	\
	IUTEST_TEST_ASSERT_(pred_formatter(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure)


#define IUTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)	\
	IUTEST_TEST_ASSERT_(::iutest::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, pred, v1, v2, v3, v4, v5), on_failure)
#define IUTEST_PRED_FORMAT5_(pred_formatter, v1, v2, v3, v4, v5, on_failure)	\
	IUTEST_TEST_ASSERT_(pred_formatter(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), on_failure)

#ifndef IUTEST_NO_VARIADIC_MACROS

#if IUTEST_HAS_VARIADIC_TEMPLATES

#define IUTEST_PRED_(pred, on_failure, ...)	\
	IUTEST_TEST_ASSERT_(::iutest::AssertPredVariadicHelper(#pred, #__VA_ARGS__, pred, __VA_ARGS__), on_failure)

#endif

#define IUTEST_PRED_FORMAT_(pred_formatter, on_failure, ...)	\
	IUTEST_TEST_ASSERT_(pred_formatter(#__VA_ARGS__, __VA_ARGS__), on_failure)

#endif

#define IUTEST_THROW_PRED_FORMAT2_(pred_formatter, statement, expected_exception, expected_exception_value, on_failure)	\
	IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, pred_formatter)

/**
 * @}
*/

namespace iutest
{

//======================================================================
// function
/** @private */
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 ;
}

/** @private */
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 ;
}

/** @private */
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 ;
}

/** @private */
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 ;
}

/** @private */
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

/** @private */
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

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_PRED_HPP_ADF851F3_C89B_4CA4_B9A0_A2B2229945C6_
