//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest.hpp
 * @brief		iris unit test
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
 *
 * @see			iutest_ver.hpp
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_HPP_
#define INCG_IRIS_IUTEST_HPP_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_ver.hpp
 * @brief		iris unit test version 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_VER_HPP_D65CB7A7_D2AD_40FE_8F5F_8FBF376A0010_
#define INCG_IRIS_IUTEST_VER_HPP_D65CB7A7_D2AD_40FE_8F5F_8FBF376A0010_

//======================================================================
// define
#define IUTEST_VER			0x01130000u //!< iutest version 1.13.0.0
#define IUTEST_MAJORVER		0x01u		//!< Major Version
#define IUTEST_MINORVER		0x13u		//!< Minor Version
#define IUTEST_BUILD		0x00u		//!< Build
#define IUTEST_REVISION		0x00u		//!< Revision

/**
 * @mainpage
 * @sa	@b	ProjectHome \n
 *			OSDN        : http://osdn.jp/projects/iutest/ \n
 *			github		: https://github.com/srz-zumix/iutest \n
 *			google group: https://groups.google.com/forum/?fromgroups#!forum/g-iutest \n
 *
 * @par		copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License.
 *
 * @par		LICENSE

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:\n
\n
  1. Redistributions of source code must retain the above copyright notice,\n
     this list of conditions and the following disclaimer.\n
  2. Redistributions in binary form must reproduce the above copyright notice,\n
     this list of conditions and the following disclaimer in the documentation \n
     and/or other materials provided with the distribution.\n
  3. the copyright holder's name is not used to endorse products \n
     built using this software without specific written permission.\n
\n
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/**
 * @page	CMDLINE		コマンドラインオプション
 * @par		Command Line Options
 <table>
   <tr><td>--help, -h                        </td><td></td><td>Generate help message.</td></tr>
   <tr><td>--iutest_output                   </td><td>xml|junit[:path]</td><td>Path of xml report.</td></tr>
   <tr><td>--iutest_list_tests               </td><td></td><td>List up tests.</td></tr>
   <tr><td>--iutest_list_tests_with_where    </td><td></td><td>List up tests with where.</td></tr>
   <tr><td>--iutest_color                    </td><td>&lt;yes|no|auto|ansi&gt;</td><td>Console color enable.</td></tr>
   <tr><td>--iutest_flagfile                 </td><td>&lt;file&gt;</td><td>Set the flag from the file.</td></tr>
   <tr><td>--iutest_filter                   </td><td>&lt;filter&gt;</td><td>Select the test run.</td></tr>
   <tr><td>--iutest_shuffle                  </td><td></td><td>Do shuffle test.</td></tr>
   <tr><td>--iutest_random_seed              </td><td>&lt;seed&gt;</td><td>Set random seed.</td></tr>
   <tr><td>--iutest_also_run_disabled_tests  </td><td></td><td>Run disabled tests.</td></tr>
   <tr><td>--iutest_break_on_failure         </td><td>[yes|no]</td><td>When that failed to break.</td></tr>
   <tr><td>--iutest_throw_on_failure         </td><td>[yes|no]</td><td>When that failed to throw.</td></tr>
   <tr><td>--iutest_catch_exceptions         </td><td>&lt;yes|no&gt;</td><td>Catch exceptions enable.</td></tr>
   <tr><td>--iutest_print_time               </td><td>&lt;yes|no&gt;</td><td>Setting the display of elapsed time.</td></tr>
   <tr><td>--iutest_repeat                   </td><td>&lt;count&gt;</td><td>Set the number of repetitions of the test.</td></tr>
   <tr><td>--iutest_stream_result_to         </td><td>&lt;host:port&gt;</td><td>Set stream test results server.</td></tr>
   <tr><td>--iutest_file_location            </td><td>&lt;auto|vs|gcc&gt;</td><td>Format file location messages.</td></tr>
   <tr><td>--iutest_default_package_name     </td><td>[name]</td><td>Set default root package name.</td></tr>
   <tr><td>--verbose                         </td><td></td><td>Verbose option.</td></tr>
   <tr><td>--feature                         </td><td></td><td>Show iutest feature.</td></tr>
   <tr><td>--version, -v                     </td><td></td><td>Show iutest version.</td></tr>
 </table>
  * yes or no option can use "yes|y|on|true|t|1|no|n|off|false|f|0"
*/

/**
 * @page	ENVIRONMENT_OPTIONS	環境変数オプション
 * @par		Environment variable Options
 <table>
   <tr><td>IUTEST_OUTPUT=xml|junit[:path]  </td><td>Path of xml report.</td></tr>
   <tr><td>IUTEST_COLOR=yes|no|auto        </td><td>Console color enable.</td></tr>
   <tr><td>IUTEST_FLAGFILE=file            </td><td>Set the flag from the file.</td></tr>
   <tr><td>IUTEST_FILTER=filter            </td><td>Select the test run.</td></tr>
   <tr><td>IUTEST_SHUFFLE                  </td><td>Do shuffle test.</td></tr>
   <tr><td>IUTEST_RANDOM_SEED=seed         </td><td>Set random seed.</td></tr>
   <tr><td>IUTEST_ALSO_RUN_DISABLED_TESTS  </td><td>Run disabled tests.</td></tr>
   <tr><td>IUTEST_BREAK_ON_FAILURE=0|1     </td><td>When that failed to break.</td></tr>
   <tr><td>IUTEST_THROW_ON_FAILURE=0|1     </td><td>When that failed to throw.</td></tr>
   <tr><td>IUTEST_CATCH_EXCEPTIONS=0|1     </td><td>Catch exceptions enable.</td></tr>
   <tr><td>IUTEST_PRINT_TIME=0|1           </td><td>Setting the display of elapsed time.</td></tr>
   <tr><td>IUTEST_REPEAT=count             </td><td>Set the number of repetitions of the test.</td></tr>
   <tr><td>IUTEST_FILE_LOCATION=auto|vs|gcc</td><td>Format file location messages.</td></tr>
   <tr><td>IUTEST_ROOT_PACKAGE_NAME=[name] </td><td>Set root package name.</td></tr>
 </table>
*/

/**
 * @page	CHANGELOG	変更履歴
 * @par		Changes
 <ul>
  <li>v1.13.0.0
    <ul>
      <li>--iutest_flagfile コマンドラインオプションに対応</li>
      <li>MFC コンテナ対応</li>
      <li>値のパラメータ化テストのテスト名指定に対応</li>
      <li>型付けテストのテスト名に型名をつけるオプションマクロ (IUTEST_TYPED_TEST_APPEND_TYPENAME) を追加</li>
      <li>非ヨーダ記法を提供するヘッダーを追加</li>
      <li>Visual Studio 2015 対応</li>
      <li>tr1/iutest_vc_unittest.hpp を修正</li>
    </ul>
  </li>
  <li>v1.12.0.0
    <ul>
      <li>IUTEST_PACKAGE v2 (多重定義制限の撤廃)</li>
      <li>Matcher に MatchesRegex,ContainsRegex を追加</li>
      <li>Matcher に ElementsAreArrayForward を追加</li>
      <li>ElementsAreArray で要素数の一致チェックを行うように変更（以前までの ElementsAreArray は ElementsAreArrayForward に変更）</li>
      <li>IUTEST_*_MATCHES_REGEXEQ,NE、IUTEST_*_CONTAINS_REGEXEQ,NE 追加</li>
      <li>--iutest_filter=@filter.txt のようにファイルからフィルター指定できるように対応</li>
      <li>IUTEST_MAKE_PEEP で関数ポインターの typedef をしなくてもいいように修正</li>
      <li>quick_exit 対応</li>
      <li>IUTEST_REPORT_SKIPPED を IUTEST_HAS_REPORT_SKIPPED に変更</li>
      <li>Visual Studio 2015 Preview 対応</li>
      <li>twilio 対応</li>
    </ul>
  </li>
  <li>v1.11.1.0
    <ul>
      <li>IUTEST_REGISTER_TYPED_TEST_CASE_P でテスト名の後ろの空白が名前に含まれてしまう不具合を修正</li>
    </ul>
  </li>
  <li>v1.11.0.0
    <ul>
      <li>fused-src 対応</li>
      <li>Wandbox 対応</li>
      <li>Matcher に Eq,Ne,Le,Lt,Ge,Gt,IsNull,NotNull,TypeEq を追加</li>
      <li>Matcher に StrEq,StrNe,StrCaseEq,StrCaseNe,HasSubstr を追加</li>
      <li>Matcher に FloatEq,DoubleEq,NanSensitiveFloatEq,NanSensitiveDoubleEq を追加</li>
      <li>Matcher に Not,ResultOf,Pointee を追加</li>
      <li>コンテナMatcher に Each,ContainerEq,Pointwise,At,IsEmpty,SizeIs,ElementsAre,ElementsAreArray を追加</li>
      <li>コンテナMatcher の Contains から HasSubstr 機能を削除</li>
      <li>コンテナMatcher の条件に Matcher を使えるように修正</li>
      <li>メンバーMatcher に Key,Pair,Field を追加</li>
      <li>ワイルドカードMatcher A,_ を追加</li>
      <li>IUTEST_*_FLOAT_EQ,DOUBLE_EQ で NAN の比較が真を返す不具合を修正</li>
      <li>Visual Studio 2015 Preview 対応</li>
    </ul>
  </li>
  <li>v1.10.0.0
    <ul>
      <li>--verbose コマンドラインオプションを追加</li>
      <li>--iutest_default_package_name コマンドラインオプションを追加</li>
      <li>operatoer == のないオブジェクトの IUTEST_*_EQ 対応</li>
      <li>operatoer != のないオブジェクトの IUTEST_*_NE 対応</li>
      <li>junit xml 出力に対応（--iutest_output=junit）</li>
      <li>tuple の要素を取得する GetParam template 関数を追加</li>
      <li>IUTEST_FLAG(ostream_formatter) を追加</li>
      <li>tuple 要素を取得する GetParam tempalate 関数を追加</li>
      <li>ARM対応</li>
      <li>--iutest_break_on_failure でスキップや警告でも停止していた不具合を修正</li>
      <li>Visual Studio 14 CTP 3 対応</li>
    </ul>
  </li>
  <li>v1.9.1.0
    <ul>
      <li>IUTEST_P,IUTEST_TYPED_TEST_P で DISABLED_ 指定が機能しない問題を修正</li>
      <li>TestFixutre を定義しなくても IUTEST_P が使えるように対応</li>
      <li>Visual Studio 14 CTP 対応</li>
    </ul>
  </li>
  <li>v1.9.0.0
    <ul>
      <li>IUTEST_*_THAT 追加</li>
      <li>式アサーション追加（IUTEST_ASSERT, IUTEST_EXPECT, IUTEST_INFORM, IUTEST_ASSUME）</li>
      <li>式アサーション追加（IUTEST_*_NOT）</li>
      <li>IUTEST_USE_MAIN 追加(main 関数定義 config)</li>
      <li>IUTEST_ASSERT を IUTEST_ASSERT_EXIT に変更</li>
    </ul>
  </li>
  <li>v1.8.1.0
    <ul>
      <li>SetUp/SetUpTestCase での SKIP/ASSUME に対応</li>
      <li>MAC OS 判定、ビルドエラー修正 (thanks to mogemimi for the pull request)</li>
      <li>--iutest_filter で : 区切りの複数条件指定が正しく動作しない不具合を修正</li>
      <li>--iutest_list_tests_with_where で値のパラメータも出力するように修正</li>
      <li>バグ修正</li>
    </ul>
  </li>
  <li>v1.8.0.0
    <ul>
      <li>IUTEST_USE_THROW_ON_ASSERT_FAILURE を IUTEST_USE_THROW_ON_ASSERTION_FAILURE に変更</li>
      <li>IUTEST_USE_THROW_ON_ASSERTION_FAILURE を指定した場合 SKIP や ASSUME も例外を投げるように変更</li>
      <li>IUTEST_*_EQ_RANGE を追加</li>
      <li>IUTEST_*_STRIN,IUTEST_*_STRNOTIN を追加</li>
      <li>IUTEST_FLAG(output) に対応</li>
      <li>IUTEST_*_NO_FAILURE の gtest モード対応</li>
      <li>AVR 対応</li>
      <li>IUTEST_*_NO_FAILURE が警告やスキップを失敗と判断しないように変更</li>
      <li>IUTEST_*_TRUE/FALSE を可変長対応</li>
      <li>フィクスチャークラス名を IUTEST_TEST マクロのテストケース名に使用した場合にエラーになるように修正(MSVC拡張)</li>
      <li>パッケージ内の値のパラメータ化テストのテストケース名が pkg.prefix/testcase となるように変更</li>
      <li>Visual C++ Compiler November 2013 CTP 対応</li>
      <li>リスナーのセットアップ関数を変更</li>
      <li>IUTEST_SCOPED_PEEP,IUTEST_MAKE_SCOPED_PEEP を廃止</li>
      <li>ソースコードのエンコーディングを UTF8 BOM 有りに変更</li>
      <li>バグ修正</li>
    </ul>
  </li>
  <li>v1.7.0.0
    <ul>
      <li>テストフィクスチャの定義が省ける値のパラメータ化テストを追加(IUTEST_AP,IUTEST_INSTANTIATE_TEST_CASE_AP)</li>
      <li>値のパラメータを operator + で連結できるように修正</li>
      <li>値のパラメータを連結する ::iutest::Concat を追加</li>
      <li>IUTEST_TYPED_TEST,IUTEST_TYPED_TEST_P の別名マクロを追加(IUTEST_T, IUTEST_TP)</li>
      <li>xml 出力に timestamp を追加</li>
      <li>前提条件の検証用マクロ IUTEST_ASSUME_* を追加</li>
      <li>SSTP 通知リスナーを追加</li>
      <li>Windows 向けメニュー登録ユーティリティを追加</li>
      <li>値のパラメータ化テストが日本語テスト名に対応していなかった問題を修正</li>
      <li>ビルドエラー修正</li>
    </ul>
  </li>
  <li>v1.6.1.0
    <ul>
      <li>Visual Studio 2013 Preview 対応</li>
    </ul>
  </li>
  <li>v1.6.0.0
    <ul>
      <li>stream result 対応</li>
      <li>gtest モードで AssertionReturn が使えるように対応</li>
      <li>AssertionReturn の仕様変更</li>
      <li>::iutest::RandomGenerator を追加</li>
      <li>::iutest::RandomValues で乱数シードを指定できるように修正</li>
      <li>spi で TestPartResult 数をチェックするように変更</li>
      <li>spi で substr でメッセージをチェックするように変更</li>
      <li>ASSERT_*, EXPECT_*, INFORM_* マクロのストリームに iomanip が使用できなかった問題を修正</li>
    </ul>
  </li>
  <li>v1.5.0.4
    <ul>
      <li>--iutest_filter でマッチしなかったテストは XML に出力しないように変更</li>
      <li>XML 出力の skipped にメッセージを出力するように修正</li>
      <li>--iutest_filter にマッチしたテスト数が取得できるように修正</li>
      <li>デフォルトログ出力を --iutest_filter の結果を考慮した出力に変更</li>
    </ul>
  </li>
  <li>v1.5.0.0
    <ul>
      <li>日本語テスト名に対応</li>
      <li>SetUpTestCase などのテスト実行中以外でも RecordProperty できるように変更</li>
      <li>iutest_list_tests_with_where コマンドラインオプションを追加</li>
      <li>IUTEST_TYPED_TEST_CASE,IUTEST_TYPED_TEST_CASE_P に直接 ::iutest::Types を書けるように修正/li>
      <li>誤った使い方をした場合にエラーを出力するように修正</li>
      <li>IUTEST_PEEP の仕様変更</li>
      <li>MiniDump 出力に対応</li>
      <li>noexcept に対応</li>
    </ul>
  </li>
  <li>v1.4.0.0
    <ul>
      <li>IUTEST_ASSERT_* で void 以外の戻り値を返せるように修正(::iutest::AssertionReturn)</li>
      <li>::iutest::Types メンバーに型を取得する get を追加</li>
      <li>::iutest::ValuesIn を initializer_list に対応</li>
      <li>値のパラメータ化テスト向けに任意のパラメータを生成する ValuesGen を追加</li>
      <li>値のパラメータ化テスト向けに乱数パラメータを生成する RandomValues を追加</li>
      <li>extern template 対応</li>
      <li>C++11 random ヘッダーが使用できるとき distribution を使うように変更</li>
      <li>コード分析ツールのためのコードの追加情報(__analysis_assume) を IUTEST_*_NULL と IUTEST_*_NOTNULL に追加(MSVC)</li>
      <li>古いコンパイラへの対応</li>
    </ul>
  </li>
  <li>v1.3.1.0
    <ul>
      <li>IUTEST_SKIP したときのログを追加</li>
      <li>IUTEST_SKIP() << "message" に対応</li>
      <li>スキップしたテストのログ出力を修正</li>
      <li>コンパイルの通らないテストコードを許可するテスト生成マクロ(*_IGNORE)を追加</li>
    </ul>
  </li>
  <li>v1.3.0.1
    <ul>
      <li>IUTEST_THROW_ON_ASSERT_FAILURE を IUTEST_USE_THROW_ON_ASSERT_FAILURE に変更</li>
      <li>IUTEST_FRIEND_TYPED_TEST を追加</li>
      <li>乱数シードが繰り返し毎に必ず変わるように修正</li>
      <li>GTEST で始まる環境変数に対応</li>
      <li>メッセージ出力のファイル/行のフォーマットを動的に変更できるオプションを追加(--iutest_file_location)</li>
      <li>gtest モードでのビルドエラー修正</li>
      <li>IUTEST_*_FATAL_FAILURE, IUTEST_*_NONFATAL_FAILURE で lambda を利用して変数にアクセスできるように修正</li>
      <li>IUTEST_*_NO_FATAL_FAILURE が FATAL FAILURE のみで判断するように変更</li>
      <li>IUTEST_*_NO_FAILURE を追加</li>
      <li>ライブラリビルド対応</li>
      <li>CUDA 対応</li>
      <li>explicit conversion operator 対応</li>
    </ul>
  </li>
  <li>v1.2.0.2
    <ul>
      <li>IUTEST_*_EQ_COLLECTIONS アサーションを追加</li>
      <li>Android NDK 対応</li>
      <li>名前空間を提供する IUTEST_PACKAGE 追加</li>
      <li>IUTEST_*_STRNE, IUTEST_*_STRCASENE の失敗メッセージを改善</li>
      <li>プログレス出力リスナーを追加</li>
    </ul>
  </li>
  <li>v1.1.2.0
    <ul>
      <li>IUTEST_*_NO_THROW で失敗したときに例外の情報を出力するように修正</li>
      <li>printer 修正</li>
    </ul>
  </li>
  <li>v1.1.1.2
    <ul>
      <li>Windows Mobile でのビルドエラー修正</li>
      <li>IUTEST_HAS_STRINGSTREAM=0 のときのビルドエラー修正</li>
      <li>宣言と定義を分離</li>
    </ul>
  </li>
  <li>v1.1.0.0
    <ul>
      <li>v1.1.0 リリースバージョン</li>
    </ul>
  </li>
  <li>v1.0.7.1
    <ul>
      <li>2バイト文字が xml に正しく出力されない問題を修正（setlocale が必要）</li>
      <li>例外の値を検査する述語アサーションを IUTEST_*_THROW_PRED_FORMAT2 追加</li>
      <li>例外の値を検査するアサーションのログ出力を修正</li>
    </ul>
  </li>
  <li>v1.0.6.0
    <ul>
      <li>例外の値を検査するアサーションを EQ/NE/STREQ/STRCASEEQ に修正</li>
    </ul>
  </li>
  <li>v1.0.5.2
    <ul>
      <li>明示的なスキップとして IUTEST_SKIP を追加</li>
      <li>コンソール出力先を動的に変更できるように修正</li>
      <li>実行すべきテストが実行されなかった場合に失敗を出力するように修正</li>
      <li>Visual Studio UnitTest Framework で IUTEST_P,IUTEST_TYPED_TEST,IUTEST_TYPED_TEST_P が使用できるように修正(tr1)</li>
    </ul>
  </li>
  <li>v1.0.4.0
    <ul>
      <li>iutest::Pairwise を追加</li>
      <li>コードサイズ削減</li>
    </ul>
  </li>
  <li>v1.0.3.1
    <ul>
      <li>ファイルパス操作補助クラスの追加</li>
      <li>IUTEST_*_EQ で if( expected == actual ) から if( actual == expected ) に変更</li>
      <li>IUTEST_*_NO_FATAL_FAILURE に空の statement を与えても警告が出ないように修正</li>
    </ul>
  </li>
  <li>v1.0.2.0
    <ul>
      <li>例外の値を検査するアサーションを追加</li>
    </ul>
  </li>
  <li>v1.0.1.0
    <ul>
      <li>CRT セキュリティ強化関数の失敗時ハンドラに対応</li>
      <li>iutest::InitIrisUnitTest が呼ばれていない場合に警告を出すように変更</li>
    </ul>
  </li>
  <li>v1.0.0.0
    <ul>
      <li>初期リリース</li>
    </ul>
  </li>
  <li>v0.36.2.1
    <ul>
      <li>型名表記をデマングルするように修正</li>
      <li>Google Test を使用した場合でも std::string に対応した文字列比較アサーションを使えるように修正</li>
      <li>Google Test を使用した時に wchar_t 版の STRCASENE が使えるように修正</li>
      <li>IUTEST_THROW_ON_ASSERT_FAILURE のデフォルト値を 0 に変更</li>
      <li>IUTEST_THROW_ON_ASSERT_FAILURE が有効なとき IUTEST_*_FATAL_FAILURE が正しく動作しない問題を修正</li>
      <li>spi テスト中に break_on_failure/throw_on_failure で止まらないように修正</li>
      <li>アサーションのみの利用ができるように修正</li>
      <li>グローバルスコープ解決演算子をつけるように修正</li>
      <li>Google Test のバージョン判別を追加</li>
    </ul>
  </li>
  <li>v0.35.0.0
    <ul>
      <li>IUTEST_PMZ, IUTEST_PMZ_F テスト生成マクロを追加</li>
    </ul>
  </li>
  <li>v0.34.0.0
    <ul>
      <li>複数 IUTEST_REGISTER_TYPED_TEST_CASE_P できない不具合を修正</li>
      <li>テストが中断した際に実行されなかったテストを notrun で XML 出力するように修正</li>
      <li>--iutest_break_on_failure を有効にしデバッグなし実行をしたときにダイアログがでないように修正</li>
    </ul>
  </li>
  <li>v0.33.1.0
    <ul>
      <li>iutest::UnitTest::repeat_counter 関数を追加</li>
      <li>OnTestIterationStart/End の iteration 引数が 0 から始まるように修正</li>
      <li>QuietResultPrinter 追加</li>
      <li>util 修正</li>
    </ul>
  </li>
  <li>v0.32.0.0
    <ul>
      <li>iutest::Combine を可変長に対応</li>
      <li>IUTEST_PEEP を cv 修飾されたメンバに対応</li>
      <li>テスト全体、テストケースの経過時間の計測方法を変更</li>
    </ul>
  </li>
  <li>v0.31.2.1
    <ul>
      <li>IUTEST_STATIC_ASSERT 追加</li>
      <li>IUTEST_SCOPED_TRACE で gtest と同じ記法が使えるように修正</li>
      <li>std::chrono::high_resolution_clock に対応</li>
      <li>iutest::PrintToString でストリーム出力できない型に対応（バイト配列を出力）</li>
      <li>テスト用乱数のシード取得を追加</li>
      <li>IUTEST_*_TRUE|FALSE で iutest::AssertionResult を受け取れるように修正</li>
      <li>--feature オプションを追加</li>
    </ul>
  </li>
  <li>v0.30.1.0
    <ul>
      <li>IUTEST_*_STREQ, IUTEST_*_STRNE を char16_t, char32_t に対応</li>
      <li>一部の環境でワイド文字列の IUTEST_*_STRCASEEQ, IUTEST_*_STRCASENE が大文字小文字が区別されていた不具合を修正</li>
      <li>nullptr に対応</li>
      <li>乱数シードを指定しなかった場合に現在時刻（ミリ秒）からシードを決定するように修正</li>
      <li>シャッフルテスト時に乱数シードをログ出力するように修正</li>
      <li>時刻取得用のコンフィグマクロを追加</li>
      <li>iutest::PrintToString でコンパイルが通らない型があったので修正</li>
      <li>EQ系アサーションのメッセージを修正</li>
    </ul>
  </li>
  <li>v0.29.1.0
    <ul>
      <li>IUTEST_INSTANTIATE_TYPED_TEST_CASE_P の型リストに単一の型(int, char...)を使用できるように修正</li>
      <li>ASSERT マクロが例外を throw するか設定する IUTEST_THROW_ON_ASSERT_FAILURE を追加(default=1) </li>
      <li>--iutest_throw_on_failure 時に致命的ではないエラーで失敗した場合 throw されない不具合を修正</li>
      <li>2回 IUTEST_RUN_ALL_TESTS したときの不具合を修正</li>
      <li>Environment の解放タイミングを修正</li>
    </ul>
  </li>
  <li>v0.28.0.1
    <ul>
      <li>iutest::Environment::SetUp などテスト以外の場所で失敗した場合に対応</li>
    </ul>
  </li>
  <li>v0.27.0.0
    <ul>
      <li>namespace を考慮した IUTEST_MAKE_SCOPED_PEEP, IUTEST_SCOPED_PEEP マクロを追加</li>
      <li>iutest::AddGlobalTestEnvironment を使うとコンパイルエラーになる問題を修正</li>
      <li>iutest::Environment は new して使うように仕様変更</li>
      <li>iutest::Environment の TearDown の実行順序を SetUp の逆順に変更</li>
    </ul>
  </li>
  <li>v0.26.2.0
    <ul>
      <li>RecordProperty でキーが重複した場合に上書きするように修正</li>
      <li>IUTEST_HAS_PEEP, IUTEST_HAS_PEEP_FUNC, IUTEST_PEEP_STATIC_FUNC コンフィグマクロを追加</li>
      <li>iutest_prod.hpp に private メンバーへのアクセス機能を追加(IUTEST_MAKE_PEEP, IUTEST_PEEP_GET etc...)</li>
      <li>IUTEST_FRIEND_TEST 不具合修正</li>
    </ul>
  </li>
  <li>v0.25.2.0
    <ul>
      <li>gtest との互換性がとれていなかった箇所を修正</li>
      <li>IUTEST_FLAG に filter を追加</li>
      <li>オプションに対応してない値を指定したときにヘルプを出力するように修正</li>
      <li>真偽値を指定するコマンドラインオプションを yes|no に対応</li>
      <li>xml 出力に type param, value param を出力するように修正</li>
      <li>RTTI が有効なときに型情報が出力されていなかった問題を修正</li>
      <li>PrintTo を tuple に対応</li>
    </ul>
  </li>
  <li>v0.24.1.0
    <ul>
      <li>Test Anything Protocol ファイル出力リスナーを追加</li>
      <li>DISABLE テストが xml に run として出力される問題を修正</li>
      <li>DISABLE テスト関係の不具合を修正</li>
      <li>IUTEST_REPORT_SKIPPED マクロでデフォルトxml出力リスナーが skip を出力するか選択できるように修正</li>
      <li>0|1 のフラグを渡すオプションに yes|no, y|n, true|false, t|f が使えるように修正</li>
      <li>--iutest_color に ANSI オプションを追加（エスケープシーケンスで色を出力）</li>
      <li>--iutest_color で大文字小文字を区別しないように修正</li>
    </ul>
  </li>
  <li>v0.23.3.0
    <ul>
      <li>IUTEST_*_SAME アサーションを追加</li>
      <li>IUTEST_*_NULL, IUTEST_*_NOTNULL アサーションを追加</li>
      <li>Test Anyting Protocol リスナーの追加</li>
      <li>デフォルトリスナーを解放したときに NULL 参照する不具合を修正</li>
      <li>テストユーティリティのテスト用に iutest_spi.hpp を追加</li>
      <li>IUTEST_*_STR* アサーションで NULL を与えて失敗させると落ちる問題を修正</li>
      <li>--iutest_throw_on_failure=1 でテスト全体を中断するように変更</li>
    </ul>
  </li>
  <li>v0.22.0.1
    <ul>
      <li>Variadic Templates 対応（iutest::Types, iutest::Values）</li>
      <li>Variadic Templates に対応した述語アサーションを追加（IUTEST_*_PRED）</li>
      <li>IUTEST_*_PRED_FORMAT を追加</li>
      <li>--iutest_throw_on_failure=1 としたとき、テスト中に例外が発生するとテスト側で catch されない不具合を修正</li>
    </ul>
  </li>
  <li>v0.21.0.1
    <ul>
      <li>IUTEST_*_NO_FATAL_FAILURE を追加</li>
      <li>STRCASEEQ, STRCASENE が ASSERT でしか使えなかった問題を修正</li>
      <li>IUTEST_*_PRED5 がコンパイルエラーになる問題を修正</li>
      <li>INFORM マクロが一部コンパイルエラーになる問題を修正</li>
      <li>gcc で例外が使えるかどうかの判定が逆になっていた問題を修正</li>
      <li>アサーションマクロに渡した式の出力を修正</li>
      <li>Visual Studio 11 対応</li>
      <li>clang対応</li>
      <li>サンプルソースを修正</li>
    </ul>
  </li>
  <li>v0.20.0.0
    <ul>
      <li>--iutest_filter を使用したときに、失敗テスト出力が出ない不具合を修正</li>
      <li>テスト、テストケース総数の取得関数が、実行してないものを含めていなかった不具合を修正</li>
      <li>テスト、テストケースの実行した（実行予定）総数の取得関数を追加</li>
      <li>IUTEST_*_STREQ 等、文字列比較マクロに NULL を渡した場合に例外が発生する不具合を修正</li>
      <li>IUTEST_RUN_ALL_TESTS の戻り値が間違っていた不具合を修正</li>
    </ul>
  </li>
  <li>v0.19.0.0
    <ul>
      <li>イベントリスナーに RecordProperty 時のイベントを追加</li>
      <li>google mock 対応</li>
      <li>IUTEST_*_STRCASE* に std::string をそのまま使えるように修正</li>
      <li>rvalue reference 対応</li>
    </ul>
  </li>
  <li>v0.18.1.1
    <ul>
      <li>On*End イベントは、リストの後ろから実行するように変更</li>
      <li>警告用（失敗にならない）テスト IUTEST_INFORM_*** マクロを追加</li>
      <li>iutest::TestPartResult のインターフェイスを修正</li>
      <li>エラー出力の Actual と Expected が逆になっていた不具合を修正</li>
      <li>char もしくは unsigned char の 0 をメッセージ出力する際にヌル文字にならないように修正</li>
      <li>ターミナルの色つき出力処理を修正</li>
      <li>Visual Studio 以外でビルドした場合の環境変数に対応</li>
      <li>IUTEST_ASSERT_EQ のエラー出力が、 Actual と Expected が逆になっていた不具合を修正</li>
    </ul>
  </li>
  <li>v0.17.0.0
    <ul>
      <li>.h から .hpp に変更</li>
      <li>gtest のコマンドライン引数に対応</li>
      <li>--iutest_filter オプションで *Test*-*TestA* のように除外フィルタをかけたときに正しく動作しない不具合を修正</li>
    </ul>
  </li>
  <li>v0.16.1.1
    <ul>
      <li>iutest::InitIrisUnitTest の vector 対応</li>
      <li>NaCl, ARM 対応</li>
      <li>RecordProperty の template 対応</li>
    </ul>
  </li>
  <li>v0.16.0.2
    <ul>
      <li>型アサーション 対応</li>
      <li>RecoredProperty 対応</li>
      <li>iutest::Combine 対応/li>
      <li>型をパラメータ化したテスト<に対応/li>
      <li>googletest との切り替え対応</li>
      <li>googletest との差異を吸収</li>
      <li>致命的な失敗時に throw するオプション対応( --iutest_throw_on_failure=<0|1> )</li>
      <li>経過時間の出力オプション対応( --iutest_print_time=<0|1> )</li>
      <li>実行するテストの選択オプション対応( --iutest_filter=selection )</li>
      <li>iutest::PrintToString 対応</li>
      <li>IUTEST_FLAG マクロによるオプション指定に対応</li>
      <li>繰り返しオプション対応( --iutest_repeat=count )</li>
      <li>イベントリスナー対応</li>
      <li>グローバル環境セットに対応(iutest::AddGlobalTestEnvironment)</li>
      <li>複合条件テスト用に述語アサーションのヘルパーを追加(iuutil::CmpHelperOR)</li>
      <li>型付けテスト対応</li>
      <li>テストに乱数生成機能を追加( genrand )</li>
      <li>環境変数でのテストオプション指定に対応</li>
      <li>DISABLEDテスト実行オプション対応( --iutest_also_run_disabled_tests )</li>
      <li>例外キャッチオプション対応( --iutest_catch_exceptions=<0|1> )</li>
      <li>失敗時ブレークオプション対応( --iutest_break_on_failure )</li>
      <li>シャッフルテスト対応</li>
      <li>出力カラーオプション対応( --iutest_color=<yes|no|auto> )</li>
      <li>ヘルプオプション対応( --help )</li>
      <li>パラメータテスト対応</li>
      <li>DISABLED_ に対応</li>
      <li>xml 出力に対応</li>
    </ul>
  </li>
</ul>
*/

/**
 * @example main.cpp
 * @example assertion.cpp
 * @example disabledtest.cpp
 * @example exception.cpp
 * @example fixture.cpp
 * @example matcher.cpp
 * @example parameterized.cpp
 * @example printto.cpp
 * @example simple.cpp
 * @example typed.cpp
*/

#endif // INCG_IRIS_IUTEST_VER_HPP_D65CB7A7_D2AD_40FE_8F5F_8FBF376A0010_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_core.hpp
 * @brief		iris unit test core
 *
 * @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_CORE_HPP_33560431_783B_4AE7_8FC8_6E78355CAF87_
#define INCG_IRIS_IUTEST_CORE_HPP_33560431_783B_4AE7_8FC8_6E78355CAF87_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_result_reporter.hpp
 * @brief		iris unit test TestPartResult リポーター ファイル
 *
 * @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_RESULT_REPORTER_HPP_803FD1F7_1FD2_4D1E_9AFC_A5851284316F_
#define INCG_IRIS_IUTEST_RESULT_REPORTER_HPP_803FD1F7_1FD2_4D1E_9AFC_A5851284316F_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_core_impl.hpp
 * @brief		iris unit test UnitTest 実装 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CORE_IMPL_HPP_D5ABC7DE_C751_4AC0_922F_547880163891_
#define INCG_IRIS_IUTEST_CORE_IMPL_HPP_D5ABC7DE_C751_4AC0_922F_547880163891_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_internal.hpp
 * @brief		iris unit test 内部定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_INTERNAL_HPP_A5BD9FBB_B57A_4C1D_B205_0ADB7798DBF9_
#define INCG_IRIS_IUTEST_INTERNAL_HPP_A5BD9FBB_B57A_4C1D_B205_0ADB7798DBF9_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @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
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_assertion.hpp
 * @brief		iris unit test assertion 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_ASSERTION_HPP_E6AF3476_DA81_46F7_A961_ACCEF7363932_
#define INCG_IRIS_IUTEST_ASSERTION_HPP_E6AF3476_DA81_46F7_A961_ACCEF7363932_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_result.hpp
 * @brief		iris unit test result
 *
 * @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_RESULT_HPP_D27B1599_F42F_4E2D_B3EB_FACE24C2B921_
#define INCG_IRIS_IUTEST_RESULT_HPP_D27B1599_F42F_4E2D_B3EB_FACE24C2B921_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_message.hpp
 * @brief		iris unit test メッセージ ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_MESSAGE_HPP_0A05C876_F204_41F5_895F_F8454AB283B1_
#define INCG_IRIS_IUTEST_MESSAGE_HPP_0A05C876_F204_41F5_895F_F8454AB283B1_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_env.hpp
 * @brief		iris unit test 環境 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_ENV_HPP_F4017EAB_6CA3_4E6E_8983_059393DADD04_
#define INCG_IRIS_IUTEST_ENV_HPP_F4017EAB_6CA3_4E6E_8983_059393DADD04_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_charcode.hpp
 * @brief		iris unit test 文字コード対応 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CHARCODE_HPP_D444FB3E_3AFA_46D0_AD69_33FAAF5615E3_
#define INCG_IRIS_IUTEST_CHARCODE_HPP_D444FB3E_3AFA_46D0_AD69_33FAAF5615E3_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_port.hpp
 * @brief		iris unit test 依存関数 ファイル
 *
 * @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_PORT_HPP_7893F685_A1A9_477A_82E8_BF06237697FF_
#define INCG_IRIS_IUTEST_PORT_HPP_7893F685_A1A9_477A_82E8_BF06237697FF_

//======================================================================
// include
#if defined(__MWERKS__)
#  define _MSL_USING_NAMESPACE
#endif

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_internal_defs.hpp
 * @brief		iris unit test internal definition
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_INTERNAL_DEFS_HPP_4B0AF5C2_8E8D_43EF_BFC5_F385E68F18DB_
#define INCG_IRIS_IUTEST_INTERNAL_DEFS_HPP_4B0AF5C2_8E8D_43EF_BFC5_F385E68F18DB_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_defs.hpp
 * @brief		iris unit test definition
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_DEFS_HPP_839F06DB_E0B6_4E6A_84F2_D99C0A44E06C_
#define INCG_IRIS_IUTEST_DEFS_HPP_839F06DB_E0B6_4E6A_84F2_D99C0A44E06C_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_compiler.hpp
 * @brief		iris unit test compiler 依存の吸収 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_COMPILER_HPP_6DDB27E8_E2FF_4754_80B0_F500025820C4_
#define INCG_IRIS_IUTEST_COMPILER_HPP_6DDB27E8_E2FF_4754_80B0_F500025820C4_

//======================================================================
// include

//======================================================================
// define
#if defined(_MSC_VER) && _MSC_VER == 1700
#  ifndef _VARIADIC_MAX
#    define _VARIADIC_MAX	10
#  endif
#endif

// os
#if   defined(__CYGWIN__)
#  define IUTEST_OS_CYGWIN				1
#  define IUTEST_PLATFORM				"CYGWIN"
#elif defined(_WIN32) || defined(WIN32) || defined(__WIN32__) || defined(WINAPI_FAMILY)
#  define IUTEST_OS_WINDOWS				1
#  if !defined(WIN32_LEAN_AND_MEAN)
#    define WIN32_LEAN_AND_MEAN
#  endif
#  include <windows.h>
#  if defined(_WIN32_WCE)
#    define IUTEST_OS_WINDOWS_MOBILE	1
#    define IUTEST_PLATFORM				"Windows CE"
#  elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
#    define IUTEST_OS_WINDOWS_MINGW		1
#  elif defined(__WINE__)
#    define IUTEST_OS_WINDOWS_WINE		1
#    define IUTEST_PLATFORM				"WINE"
#  elif defined(__CUDACC__)
#    define IUTEST_OS_WINDOWS_CUDA		1
#  elif defined(WINAPI_FAMILY)
#    if defined(WINAPI_FAMILY_PHONE_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
#      define IUTEST_OS_WINDOWS_PHONE	1
#      define IUTEST_PLATFORM			"Windows Phone"
#    elif defined(WINAPI_FAMILY_APP) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
#      define IUTEST_OS_WINDOWS_RT		1
#      define IUTEST_PLATFORM			"Windows RT"
#    else
#      define IUTEST_OS_WINDOWS_DESKTOP	1
#    endif
#  else
#    define IUTEST_OS_WINDOWS_DESKTOP	1
#  endif
#  if !defined(IUTEST_PLATFORM)
#    define IUTEST_PLATFORM				"Windows"
#  endif
#elif defined(__APPLE__)
#  include "TargetConditionals.h"
#  if TARGET_OS_IPHONE
#    define IUTEST_OS_IOS				1
#    define IUTEST_PLATFORM				"iOS"
#  else
#    define IUTEST_OS_MAC				1
#    define IUTEST_PLATFORM				"Mac OS"
#  endif
#elif defined(__FreeBSD__)
#  define IUTEST_OS_FREEBSD				1
#  define IUTEST_PLATFORM				"FreeBSD"
#elif defined(sun) || defined(__sun)
#  define IUTEST_OS_SOLARIS				1
#  define IUTEST_PLATFORM				"Solaris"
#elif defined(__linux__)
#  define IUTEST_OS_LINUX				1
#  if defined(ANDROID) || defined(__ANDROID__)
#    define IUTEST_OS_LINUX_ANDROID		1
#    define IUTEST_PLATFORM				"Android"
#  else
#    define IUTEST_PLATFORM				"LINUX"
#  endif
#elif defined(__native_client__)
#  define IUTEST_OS_NACL				1
#  define IUTEST_PLATFORM				"Google Native Client"
#elif defined(__AVR32__) || defined(__avr32__)
#  define IUTEST_OS_AVR32				1
#  define IUTEST_PLATFORM				"AVR32"
#elif defined(__arm__)
#  define IUTEST_OS_ARM					1
#  define IUTEST_PLATFORM				"ARM"
#endif

#if defined(IUTEST_OS_LINUX_ANDROID)
#  include <android/api-level.h>
#endif

// c++11

//! is c++11 compiler
#if !defined(IUTEST_HAS_CXX11)
#  if (defined(__cplusplus) && __cplusplus >= 201103L) || defined(__GXX_EXPERIMENTAL_CXX0X__)
#    define IUTEST_HAS_CXX11		1
#  endif
#endif

#if !defined(IUTEST_HAS_CXX11)
#  define IUTEST_HAS_CXX11			0
#endif

//! has nullptr
#if !defined(IUTEST_HAS_NULLPTR)
#  if   defined(__clang__)
#    if __has_feature(cxx_nullptr)
#      define IUTEST_HAS_NULLPTR	1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_NULLPTR	1
#    endif
#  elif defined(_MSC_VER)
#    if _MSC_VER > 1500
#      define IUTEST_HAS_NULLPTR	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER > 1200
#      define IUTEST_HAS_NULLPTR	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_NULLPTR)
#  define IUTEST_HAS_NULLPTR		0
#endif

//! has decltype
#if !defined(IUTEST_HAS_DECLTYPE)
#  if   defined(__clang__)
#    if __has_feature(cxx_decltype)
#      define IUTEST_HAS_DECLTYPE	1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_DECLTYPE	1
#    endif
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1600
#      define IUTEST_HAS_DECLTYPE	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1200
#      define IUTEST_HAS_DECLTYPE	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_DECLTYPE)
#  define IUTEST_HAS_DECLTYPE		0
#endif

//! has static_assert
#if !defined(IUTEST_HAS_STATIC_ASSERT)
#  if   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__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_STATIC_ASSERT	1
#    endif
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1600
#      define IUTEST_HAS_STATIC_ASSERT	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER > 1100
#      define IUTEST_HAS_STATIC_ASSERT	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_STATIC_ASSERT)
#  define IUTEST_HAS_STATIC_ASSERT	0
#endif


//! has constexpr
#if !defined(IUTEST_HAS_CONSTEXPR)
#  if   defined(__clang__)
#    if __has_feature(cxx_constexpr)
#      define IUTEST_HAS_CONSTEXPR	1
#    endif
#  elif defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_CONSTEXPR	1
#    endif
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1900 || _MSC_FULL_VER == 180021114
#      define IUTEST_HAS_CONSTEXPR	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1400
#      define IUTEST_HAS_CONSTEXPR	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_CONSTEXPR)
#  define IUTEST_HAS_CONSTEXPR		0
#endif

#if IUTEST_HAS_CONSTEXPR
#  define IUTEST_CXX_CONSTEXPR			constexpr
#  define IUTEST_CXX_CONSTEXPR_OR_CONST	constexpr
#else
#  define IUTEST_CXX_CONSTEXPR
#  define IUTEST_CXX_CONSTEXPR_OR_CONST	const
#endif

//! has rvalue reference
#if !defined(IUTEST_HAS_RVALUE_REFS)
#  if   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__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_RVALUE_REFS	1
#    endif
#  elif defined(_MSC_VER)
#    if (_MSC_VER >= 1700)
#      define IUTEST_HAS_RVALUE_REFS	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1200
#      define IUTEST_HAS_RVALUE_REFS	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_RVALUE_REFS)
#  define IUTEST_HAS_RVALUE_REFS	0
#endif

//! has delete function
#ifndef IUTEST_HAS_DELETED_FUNCTIONS
#  if   defined(__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
#  elif defined(_MSC_VER)
#    if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 180020827)
#      define IUTEST_HAS_DELETED_FUNCTIONS	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1200
#      define IUTEST_HAS_DELETED_FUNCTIONS	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_DELETED_FUNCTIONS)
#  define IUTEST_HAS_DELETED_FUNCTIONS		0
#endif

//! delete function
#if IUTEST_HAS_DELETED_FUNCTIONS
#  define IUTEST_CXX_DELETED_FUNCTION	= delete
#else
#  define IUTEST_CXX_DELETED_FUNCTION
#endif

//! has default function
#if !defined(IUTEST_HAS_DEFAULT_FUNCTIONS)
#  if   defined(__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
#    endif
#  elif defined(_MSC_VER)
#    if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 180020827)
#      define IUTEST_HAS_DEFAULT_FUNCTIONS	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1200
#      define IUTEST_HAS_DEFAULT_FUNCTIONS	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_DEFAULT_FUNCTIONS)
#  define IUTEST_HAS_DEFAULT_FUNCTIONS		0
#endif

//! default function
#if IUTEST_HAS_DEFAULT_FUNCTIONS
#  define IUTEST_CXX_DEFAULT_FUNCTION	= default;
#else
#  define IUTEST_CXX_DEFAULT_FUNCTION	{}
#endif

//! has initializer_list
#if !defined(IUTEST_HAS_INITIALIZER_LIST)
#  if   defined(__clang__)
#    if __has_feature(cxx_generalized_initializers)
#      define IUTEST_HAS_INITIALIZER_LIST	1
#    endif
#  elif defined(__GLIBC__)
#    if IUTEST_HAS_CXX11 && (__GLIBCXX__ > 20110325)
#      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
#  elif defined(_MSC_VER)
#    if   (_MSC_VER >= 1800)
#      define IUTEST_HAS_INITIALIZER_LIST	1
#    elif (_MSC_FULL_VER == 170051025)
#      define IUTEST_HAS_INITIALIZER_LIST	1
#      include <initializer_list>
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1400
#      define IUTEST_HAS_INITIALIZER_LIST	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_INITIALIZER_LIST)
#  define IUTEST_HAS_INITIALIZER_LIST		0
#endif

//! has variadic template
#if !defined(IUTEST_HAS_VARIADIC_TEMPLATES)
#  if   defined(__clang__)
#    if __has_feature(cxx_variadic_templates)
#      define IUTEST_HAS_VARIADIC_TEMPLATES	1
#    endif
#  elif defined(__GNUC__)
	// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35722
#    if defined(__VARIADIC_TEMPLATES) || ( ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))) && defined(__GXX_EXPERIMENTAL_CXX0X__) )
#      define IUTEST_HAS_VARIADIC_TEMPLATES	1
#    endif
#  elif defined(_MSC_VER)
#    if   (_MSC_VER >= 1800)
#      define IUTEST_HAS_VARIADIC_TEMPLATES	1
#    elif (_MSC_FULL_VER == 170051025)
#      define IUTEST_HAS_VARIADIC_TEMPLATES	1
#      define IUTEST_HAS_VARIADIC_COMBINE	0
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER > 1200
#      define IUTEST_HAS_VARIADIC_TEMPLATES	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_VARIADIC_TEMPLATES)
#  define IUTEST_HAS_VARIADIC_TEMPLATES		0
#endif

//! has variadic template templates
#if !defined(IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES)
#  if   defined(__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__ > 7)) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7) && (__GNUC_PATCHLEVEL__ >= 1))) && defined(__GXX_EXPERIMENTAL_CXX0X__) )
#      define IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES	1
#    endif
#  elif defined(_MSC_VER)
#    define IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES	IUTEST_HAS_VARIADIC_TEMPLATES
#  elif defined(__INTEL_COMPILER)
#    define IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES	IUTEST_HAS_VARIADIC_TEMPLATES
#  endif
#endif

#ifndef IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES
#  define IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES	0
#endif

//! has char16_t
#if !defined(IUTEST_HAS_CHAR16_T)
#  if 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
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1900
#      define IUTEST_HAS_CHAR16_T	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1400
#      define IUTEST_HAS_CHAR16_T	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_CHAR16_T)
#  define IUTEST_HAS_CHAR16_T	0
#endif

//! has char32_t
#ifndef IUTEST_HAS_CHAR32_T
#  if 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
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1900
#      define IUTEST_HAS_CHAR32_T	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1400
#      define IUTEST_HAS_CHAR32_T	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_CHAR32_T)
#  define IUTEST_HAS_CHAR32_T	0
#endif

//! has lambda
#if !defined(IUTEST_HAS_LAMBDA)
#  if   defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_LAMBDA		1
#    endif
#  elif defined(_MSC_VER)
#    if   _MSC_VER > 1600
#      define IUTEST_HAS_LAMBDA		1
#    elif _MSC_VER == 1600
#      define IUTEST_HAS_LAMBDA		1
#      define IUTEST_NO_LAMBDA_SCOPE_RESOLUTION	// VC++10 lambda v1.0 is not supported.
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1200
#      define IUTEST_HAS_LAMBDA		1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_LAMBDA)
#  define IUTEST_HAS_LAMBDA		0
#endif

#if IUTEST_HAS_LAMBDA
#  if defined(__GNUC__)
#    if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7))
#      define IUTEST_NO_LAMBDA_LOCAL_OBJECT_TEMPLATE_PARAMETERS
#    endif
#  elif defined(_MSC_VER)
#    define IUTEST_NO_LAMBDA_LOCAL_OBJECT_TEMPLATE_PARAMETERS
#  endif
#endif

//! explicit conversion operator
#if !defined(IUTEST_HAS_EXPLICIT_CONVERSION)
#  if   defined(__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
#  elif defined(_MSC_VER)
#    if (_MSC_VER >= 1800) || (_MSC_FULL_VER == 170051025)
#      define IUTEST_HAS_EXPLICIT_CONVERSION	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1300
#      define IUTEST_HAS_EXPLICIT_CONVERSION	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_EXPLICIT_CONVERSION)
#  define IUTEST_HAS_EXPLICIT_CONVERSION		0
#endif

//! explicit conversion definition
#if !defined(IUTEST_CXX_EXPLICIT_CONVERSION)
#  if IUTEST_HAS_EXPLICIT_CONVERSION
#    define IUTEST_CXX_EXPLICIT_CONVERSION		explicit
#  else
#    define IUTEST_CXX_EXPLICIT_CONVERSION
#  endif
#endif

//! has override and final
#if !defined(IUTEST_HAS_OVERRIDE_AND_FINAL)
#  if   defined(__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
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1700
#      define IUTEST_HAS_OVERRIDE_AND_FINAL	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1400
#      define IUTEST_HAS_OVERRIDE_AND_FINAL	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_OVERRIDE_AND_FINAL)
#  define IUTEST_HAS_OVERRIDE_AND_FINAL		0
#endif

//! override definition
#if !defined(IUTEST_CXX_OVERRIDE)
#  if IUTEST_HAS_OVERRIDE_AND_FINAL
#    define IUTEST_CXX_OVERRIDE		override
#  else
#    define IUTEST_CXX_OVERRIDE
#  endif
#endif

//! final definition
#if !defined(IUTEST_CXX_FINAL)
#  if IUTEST_HAS_OVERRIDE_AND_FINAL
#    define IUTEST_CXX_FINAL		final
#  else
#    define IUTEST_CXX_FINAL
#  endif
#endif

//! has noexcept
#ifndef IUTEST_HAS_NOEXCEPT
#  if   defined(__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
#  elif defined(_MSC_VER)
#    if _MSC_FULL_VER >= 190022816
#      define IUTEST_HAS_NOEXCEPT	1 // https://connect.microsoft.com/VisualStudio/feedback/details/809079/torino-compile-error-template-noexcept
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1400
#      define IUTEST_HAS_NOEXCEPT	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_NOEXCEPT)
#  define IUTEST_HAS_NOEXCEPT	0
#endif

//! noexcept definition
#if !defined(IUTEST_CXX_NOEXCEPT)
#  if IUTEST_HAS_NOEXCEPT
#    define IUTEST_CXX_NOEXCEPT(expr_)		noexcept(expr_)
#  else
#    define IUTEST_CXX_NOEXCEPT(expr_)
#  endif
#endif

//! noexcept specification definition
#if !defined(IUTEST_CXX_NOEXCEPT_SPEC)
#  if IUTEST_HAS_NOEXCEPT
#    define IUTEST_CXX_NOEXCEPT_SPEC		noexcept
#  else
#    define IUTEST_CXX_NOEXCEPT_SPEC
#  endif
#endif

#if !defined(IUTEST_CXX_NOEXCEPT_AS)
#  if IUTEST_HAS_NOEXCEPT
#    define IUTEST_CXX_NOEXCEPT_AS(expr_)	noexcept( noexcept(expr_) )
#  else
#    define IUTEST_CXX_NOEXCEPT_AS(expr_)
#  endif
#endif

//! nothrow definition
#if !defined(IUTEST_CXX_NOTHROW)
#  if IUTEST_HAS_NOEXCEPT
#    define IUTEST_CXX_NOTHROW	noexcept
#  else
#    define IUTEST_CXX_NOTHROW	throw()
#  endif
#endif

//! has extern template
#if !defined(IUTEST_HAS_EXTERN_TEMPLATE)
#  if defined(_MSC_VER) && _MSC_VER >= 1400
#    define IUTEST_HAS_EXTERN_TEMPLATE		1
#  elif defined(__GNUC__) || defined(__clang__)
#    define IUTEST_HAS_EXTERN_TEMPLATE		1
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER > 1100
#      define IUTEST_HAS_EXTERN_TEMPLATE	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_EXTERN_TEMPLATE)
#  define IUTEST_HAS_EXTERN_TEMPLATE	0
#endif

//! has enum class
#if !defined(IUTEST_HAS_STRONG_ENUMS)
#  if   defined(__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
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1700
#      define IUTEST_HAS_STRONG_ENUMS	1
#    endif
#  elif defined(__INTEL_COMPILER)
#    if __INTEL_COMPILER >= 1400
#      define IUTEST_HAS_STRONG_ENUMS	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_STRONG_ENUMS)
#  define IUTEST_HAS_STRONG_ENUMS		0
#endif

//! quick_exit
#if !defined(IUTEST_HAS_QUICK_EXIT)
#  if   (defined(_GLIBCXX_HAVE_QUICK_EXIT) && defined(_GLIBCXX_HAVE_AT_QUICK_EXIT)) || defined(_LIBCPP_HAS_QUICK_EXIT)
#    define IUTEST_HAS_QUICK_EXIT	1
#  elif defined(_MSC_VER)
#    if _MSC_VER > 1800
#      define IUTEST_HAS_QUICK_EXIT	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_QUICK_EXIT)
#  define IUTEST_HAS_QUICK_EXIT		0
#endif

// c++
//! has exceptions
#if !defined(IUTEST_HAS_EXCEPTIONS)
#  if   defined(_MSC_VER) || defined(__BORLANDC__)
#    ifndef _HAS_EXCEPTIONS
#      define _HAS_EXCEPTIONS		1
#    endif
#    define IUTEST_HAS_EXCEPTIONS	_HAS_EXCEPTIONS
#  elif defined(__clang__)
#    if __EXCEPTIONS && __has_feature(cxx_exceptions)
#      define IUTEST_HAS_EXCEPTIONS	1
#    endif
#  elif defined(__GNUC__)
#    if defined(__EXCEPTIONS)
#      define IUTEST_HAS_EXCEPTIONS	1
#    endif
#  elif defined(__MWERKS__)
#    if __option(exceptions)
#      define IUTEST_HAS_EXCEPTIONS	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_EXCEPTIONS)
#  define IUTEST_HAS_EXCEPTIONS	0
#endif

//! has Structured Exception Handling
#if !defined(IUTEST_HAS_SEH)
#  if   defined(_WIN32)
#    if	defined(_MSC_VER) && _MSC_VER > 1400
#      define IUTEST_HAS_SEH	1
#    endif
#  elif defined(__BORLANDC__)
#    define IUTEST_HAS_SEH		1
#  endif
#endif

#if !defined(IUTEST_HAS_SEH)
#  define IUTEST_HAS_SEH		0
#endif

//! has RTTI
#if !defined(IUTEST_HAS_RTTI)
#  if   defined(__clang__)
#    if __has_feature(cxx_rtti)
#      define IUTEST_HAS_RTTI	1
#    endif
#    if defined(_MSC_VER)	// clang for windows
#      if !defined(_CPPRTTI)
#        include <exception>
#      endif
#    endif
#  elif defined(__GNUC__)
#    ifdef __RTTI
#      define IUTEST_HAS_RTTI	1
#    endif
#    ifdef __GXX_RTTI
#      define IUTEST_HAS_RTTI	1
#    endif
#  elif defined(__MWERKS__)
#    if	__option(RTTI)
#      define IUTEST_HAS_RTTI	1
#    endif
#  elif defined(__ARMCC_VERSION)
#    ifdef __RTTI
#      define IUTEST_HAS_RTTI	1
#    endif
#  elif defined(__IBMCPP__)
#    if (__IBMCPP__ >= 900)
#      define IUTEST_HAS_RTTI	1
#    endif
#  elif defined(_MSC_VER)
#    ifdef _CPPRTTI
#      define IUTEST_HAS_RTTI	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_RTTI)
#  define IUTEST_HAS_RTTI		0
#endif

#if IUTEST_HAS_RTTI
#  include <typeinfo>
#endif

//! explicit instantiation access checking
#if !defined(IUTEST_EXPLICIT_INSTANTIATION_ACCESS_PRIVATE_MEMBER_FUNCTION)
#  if defined(_MSC_VER) && ((_MSC_VER < 1600) || (_MSC_VER == 1900))
     // VS2008 以前では、private なメンバー関数に explicit instantiation でもアクセスできない
#    define IUTEST_EXPLICIT_INSTANTIATION_ACCESS_PRIVATE_MEMBER_FUNCTION	0
#  else
#    define IUTEST_EXPLICIT_INSTANTIATION_ACCESS_PRIVATE_MEMBER_FUNCTION	1
#  endif
#endif

//! explicit instantiation access checking (static member function)
#if !defined(IUTEST_EXPLICIT_INSTANTIATION_ACCESS_PRIVATE_STATIC_MEMBER_FUNCTION)
#  if defined(_MSC_VER)
// Visual Studio では、private な static メンバー関数に explicit instantiation でもアクセスできない
#    define IUTEST_EXPLICIT_INSTANTIATION_ACCESS_PRIVATE_STATIC_MEMBER_FUNCTION	0
#  else
#    define IUTEST_EXPLICIT_INSTANTIATION_ACCESS_PRIVATE_STATIC_MEMBER_FUNCTION	1
#  endif
#endif

// 可変長引数マクロ
#if !defined(IUTEST_NO_VARIADIC_MACROS)
#  if defined(_MSC_VER) && (_MSC_VER < 1500)
#    define IUTEST_NO_VARIADIC_MACROS		1
#  endif
#endif

//! has __COUNTER__
#if !defined(IUTEST_HAS_COUNTER_MACRO)
#  if   defined(_MSC_VER) && (_MSC_VER >= 1300)
#    define IUTEST_HAS_COUNTER_MACRO		1
#  elif 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

#if !defined(IUTEST_HAS_COUNTER_MACRO)
#  define IUTEST_HAS_COUNTER_MACRO			0
#endif

//! has file stat
#if !defined(IUTEST_HAS_FILE_STAT)
#  if !defined(IUTEST_OS_WINDOWS_MOBILE)
#    define	IUTEST_HAS_FILE_STAT			1
#  endif
#endif

//! explicit class member template specialization
#if !defined(IUTEST_HAS_CLASS_MEMBER_TEMPLATE_SPECIALIZATION)
#  if defined(_MSC_VER)
#    define IUTEST_HAS_CLASS_MEMBER_TEMPLATE_SPECIALIZATION	1
#  else
#    define IUTEST_HAS_CLASS_MEMBER_TEMPLATE_SPECIALIZATION	0
#  endif
#endif

//! partial template specialization
#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#  if defined(_MSC_VER) && (_MSC_VER < 1310)
#    define IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION	1
#  endif
#endif

//! has Two pahse name lookup
#if !defined(IUTEST_NO_TWO_PHASE_NAME_LOOKUP)
#  if defined(_MSC_VER)
#    define IUTEST_NO_TWO_PHASE_NAME_LOOKUP				1
#  endif
#endif

//! function template ordering
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
#  if defined(_MSC_VER) && (_MSC_VER < 1310)
#    define IUTEST_NO_FUNCTION_TEMPLATE_ORDERING		1
#  endif
#endif

//! in class member initialization
#if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
#  if defined(_MSC_VER) && _MSC_VER < 1310
#    define IUTEST_NO_INCLASS_MEMBER_INITIALIZATION		1
#  endif
#endif

//! explicit function template instantiation
#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
#  if defined(_MSC_VER) && _MSC_VER < 1310
#    define IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS	1
#  endif
#endif

//! SFINAE
#if !defined(IUTEST_NO_SFINAE)
#  if defined(_MSC_VER) && _MSC_VER < 1310
#    define IUTEST_NO_SFINAE	1
#  endif
#endif

//! template template
#if !defined(IUTEST_NO_TEMPLATE_TEMPLATES)
#  if defined(_MSC_VER) && _MSC_VER < 1310
#    define IUTEST_NO_TEMPLATE_TEMPLATES	1
#  endif
#endif

//! void return
#if !defined(IUTEST_NO_VOID_RETURNS)
#  if defined(_MSC_VER) && _MSC_VER < 1300
#    define IUTEST_NO_VOID_RETURNS			1
#  endif
#endif

//! ADL
#if !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)
#  if defined(_MSC_VER) && _MSC_VER < 1310
#    define IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP	1
#  endif
#endif

#if !defined(IUTEST_NO_PRIVATE_IN_AGGREGATE)
#  if defined(_MSC_VER) && _MSC_VER < 1310
#    define IUTEST_NO_PRIVATE_IN_AGGREGATE	1
#  endif
#endif

//! secure lib
#if !defined(IUTEST_HAS_WANT_SECURE_LIB)
#  if defined(_MSC_VER)
#    if defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__
#      define IUTEST_HAS_WANT_SECURE_LIB	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_WANT_SECURE_LIB)
#  define IUTEST_HAS_WANT_SECURE_LIB		0
#endif

//! has Microsoft compiler extension
#if !defined(IUTEST_HAS_MS_EXTENSIONS)
#  if defined(__clang__)
//#    if defined(_MSC_VER)
//#      define IUTEST_HAS_MS_EXTENSIONS		1
//#    endif
#  elif defined(_MSC_VER)
#    define IUTEST_HAS_MS_EXTENSIONS		1
#  endif
#endif

#if !defined(IUTEST_HAS_MS_EXTENSIONS)
#  define IUTEST_HAS_MS_EXTENSIONS			0
#endif

//! has __if_exists
#if !defined(IUTEST_HAS_IF_EXISTS)
#  if defined(__clang__)
#    if (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 5) ) && IUTEST_HAS_MS_EXTENSIONS
#      define IUTEST_HAS_IF_EXISTS			1
#    endif
#  elif defined(_MSC_VER) && _MSC_VER >= 1310
#    define IUTEST_HAS_IF_EXISTS			1
#  endif
#endif

#if !defined(IUTEST_HAS_IF_EXISTS)
#  define IUTEST_HAS_IF_EXISTS		0
#endif

//! has __analysis_assume
#if !defined(IUTEST_HAS_ANALYSIS_ASSUME)
#  if defined(_MSC_VER) && (_MSC_VER >= 1500) && !defined(__CUDACC__)
#    define IUTEST_HAS_ANALYSIS_ASSUME		1
#    define IUTEST_ANALYSIS_ASSUME			__analysis_assume
#  elif defined(__clang__)
#    if __has_builtin(__builtin_assume)
#      define IUTEST_HAS_ANALYSIS_ASSUME	1
#      define IUTEST_ANALYSIS_ASSUME		__builtin_assume
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_ANALYSIS_ASSUME)
#  define IUTEST_HAS_ANALYSIS_ASSUME		0
#endif
#if !defined(IUTEST_ANALYSIS_ASSUME)
#  define IUTEST_ANALYSIS_ASSUME(...)		(void)0
#endif

// C11

//! has _Generic
#if !defined(IUTEST_HAS_GENERIC)
#  if   defined(__clang__)
#    if __has_feature(c_generic_selections)
#      define IUTEST_HAS_GENERIC	1
#    endif
#  elif defined(__GNUC__)
//#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
//#      define IUTEST_HAS_GENERIC	1
//#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_GENERIC)
#  define IUTEST_HAS_GENERIC		0
#endif

// attribute

//! unused attribute
#if !defined(IUTEST_ATTRIBUTE_UNUSED_)
#  if (defined(__GNUC__) && !defined(COMPILER_ICC))
#    define IUTEST_ATTRIBUTE_UNUSED_	__attribute__ ((unused))
#  elif defined(__clang__)
#    if __has_attribute(unused)
#      define IUTEST_ATTRIBUTE_UNUSED_	__attribute__ ((unused))
#    endif
#  endif
#endif

#if !defined(IUTEST_ATTRIBUTE_UNUSED_)
#  define IUTEST_ATTRIBUTE_UNUSED_
#endif

//! pure attribute
#if !defined(IUTEST_ATTRIBUTE_PURE_)
#  if defined(__GNUC__) && !defined(COMPILER_ICC)
#    define IUTEST_ATTRIBUTE_PURE_		__attribute__ ((pure))
#  else
#    define IUTEST_ATTRIBUTE_PURE_
#  endif
#endif

//! noreturn
#if !defined(IUTEST_ATTRIBUTE_NORETURN_)
#  if   defined(__clang__)
#    if __has_feature(cxx_attributes)
#      define IUTEST_ATTRIBUTE_NORETURN_	[[noreturn]]
#    elif __has_attribute(noreturn)
#      define IUTEST_ATTRIBUTE_NORETURN_	__attribute__ ((noreturn))
#    endif
#  elif defined(__GNUC__) && !defined(COMPILER_ICC)
#    define IUTEST_ATTRIBUTE_NORETURN_		__attribute__ ((noreturn))
#  elif defined(_MSC_VER)
#    define IUTEST_ATTRIBUTE_NORETURN_		__declspec(noreturn)
#  endif
#endif

#if !defined(IUTEST_ATTRIBUTE_NORETURN_)
#  define IUTEST_ATTRIBUTE_NORETURN_
#endif

// workaround
#if defined(_MSC_VER)
// http://stackoverflow.com/questions/14487241/avoiding-an-inheritance-by-dominance-warning-for-a-mocked-stdfstream-class
#  define IUTEST_WORKAROUND_MSC_STLSTREAM_C4250()	\
	void _Add_vtordisp1() {}	\
	void _Add_vtordisp2() {}
#else
#  define IUTEST_WORKAROUND_MSC_STLSTREAM_C4250()	
#endif

// pragma
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_pragma.hpp
 * @brief		iris unit test pragma 依存の吸収 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PRAGMA_HPP_FBC5A1DE_3D0C_443E_84B1_5F0618DF9A6B_
#define INCG_IRIS_IUTEST_PRAGMA_HPP_FBC5A1DE_3D0C_443E_84B1_5F0618DF9A6B_

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

// pragma
#if   defined(_MSC_VER) && _MSC_VER >= 1310
#  define IUTEST_PRAGMA(x)	__pragma(x)
#elif defined(__GNUC__)
#  define IUTEST_PRAGMA(x)	_Pragma(#x)
#elif defined(__clang__)
#  define IUTEST_PRAGMA(x)	_Pragma(#x)
#else
#  define IUTEST_PRAGMA(x)
#endif

#define IUTEST_PRAGMA_MESSAGE(m)	IUTEST_PRAGMA(message (m))

// pragma warning
#if defined(_MSC_VER)
#  define IUTEST_PRAGMA_MSC_WARN_PUSH()			IUTEST_PRAGMA(warning (push))
#  define IUTEST_PRAGMA_MSC_WARN_DISABLE(x)		IUTEST_PRAGMA(warning (disable: x))
#  define IUTEST_PRAGMA_MSC_WARN_POP()			IUTEST_PRAGMA(warning (pop))
#endif

#if defined(__GNUC__)
#  if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#    define IUTEST_PRAGMA_GCC_WARN_PUSH()		IUTEST_PRAGMA(GCC diagnostic push)
#    define IUTEST_PRAGMA_GCC_WARN_DISABLE(x)	IUTEST_PRAGMA(GCC diagnostic ignored x)
#    define IUTEST_PRAGMA_GCC_WARN_POP()		IUTEST_PRAGMA(GCC diagnostic pop)
#  else
#    define IUTEST_PRAGMA_GCC_WARN_PUSH()		
#    define IUTEST_PRAGMA_GCC_WARN_DISABLE(x)	
#    define IUTEST_PRAGMA_GCC_WARN_POP()		
#  endif
#endif

#if defined(__clang__)
#  define IUTEST_PRAGMA_CLANG_WARN_PUSH()		IUTEST_PRAGMA(clang diagnostic push)
#  define IUTEST_PRAGMA_CLANG_WARN_DISABLE(x)	IUTEST_PRAGMA(clang diagnostic ignored x)
#  define IUTEST_PRAGMA_CLANG_WARN_POP()		IUTEST_PRAGMA(clang diagnostic pop)
#  if defined(__GNUC__)
#    undef IUTEST_PRAGMA_GCC_WARN_PUSH		
#    undef IUTEST_PRAGMA_GCC_WARN_DISABLE
#    undef IUTEST_PRAGMA_GCC_WARN_POP	
#  endif
#  define IUTEST_PRAGMA_GCC_WARN_PUSH			IUTEST_PRAGMA_CLANG_WARN_PUSH
#  define IUTEST_PRAGMA_GCC_WARN_DISABLE		IUTEST_PRAGMA_CLANG_WARN_DISABLE
#  define IUTEST_PRAGMA_GCC_WARN_POP			IUTEST_PRAGMA_CLANG_WARN_POP
#endif

#ifndef IUTEST_PRAGMA_MSC_WARN_PUSH
#  define IUTEST_PRAGMA_MSC_WARN_PUSH()
#endif
#ifndef IUTEST_PRAGMA_MSC_WARN_DISABLE
#  define IUTEST_PRAGMA_MSC_WARN_DISABLE(x)
#endif
#ifndef IUTEST_PRAGMA_MSC_WARN_POP
#  define IUTEST_PRAGMA_MSC_WARN_POP()
#endif

#ifndef IUTEST_PRAGMA_GCC_WARN_PUSH
#  define IUTEST_PRAGMA_GCC_WARN_PUSH()
#endif
#ifndef IUTEST_PRAGMA_GCC_WARN_DISABLE
#  define IUTEST_PRAGMA_GCC_WARN_DISABLE(x)
#endif
#ifndef IUTEST_PRAGMA_GCC_WARN_POP
#  define IUTEST_PRAGMA_GCC_WARN_POP()
#endif

#ifndef IUTEST_PRAGMA_CLANG_WARN_PUSH
#  define IUTEST_PRAGMA_CLANG_WARN_PUSH()
#endif
#ifndef IUTEST_PRAGMA_CLANG_WARN_DISABLE
#  define IUTEST_PRAGMA_CLANG_WARN_DISABLE(x)
#endif
#ifndef IUTEST_PRAGMA_CLANG_WARN_POP
#  define IUTEST_PRAGMA_CLANG_WARN_POP()
#endif

#if   defined(_MSC_VER)
#  define IUTEST_PARGMA_WARN_PUSH()		IUTEST_PRAGMA_MSC_WARN_PUSH()
#  define IUTEST_PARGMA_WARN_POP()		IUTEST_PRAGMA_MSC_WARN_POP()
#elif defined(__GNUC__)
#  define IUTEST_PARGMA_WARN_PUSH()		IUTEST_PRAGMA_GCC_WARN_PUSH()
#  define IUTEST_PARGMA_WARN_POP()		IUTEST_PRAGMA_GCC_WARN_POP()
#elif defined(__clang__)
#  define IUTEST_PARGMA_WARN_PUSH()		IUTEST_PRAGMA_CLANG_WARN_PUSH()
#  define IUTEST_PARGMA_WARN_POP()		IUTEST_PRAGMA_CLANG_WARN_PUSH()
#else
#  define IUTEST_PARGMA_WARN_PUSH()
#  define IUTEST_PARGMA_WARN_POP()
#endif


// pragma warning xxx
#if defined(_MSC_VER) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()		IUTEST_PRAGMA_MSC_WARN_PUSH()	\
															IUTEST_PRAGMA_MSC_WARN_DISABLE(4996)
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()		IUTEST_PRAGMA_MSC_WARN_POP()
#else
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
#endif

#if defined(_MSC_VER) && _MSC_VER < 1700
#  define IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()	IUTEST_PRAGMA_MSC_WARN_PUSH()	\
																IUTEST_PRAGMA_MSC_WARN_DISABLE(4231)
#  define IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()		IUTEST_PRAGMA_MSC_WARN_POP()
#else
#  define IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()
#  define IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()
#endif

#if defined(_MSC_VER) && IUTEST_HAS_CONSTEXPR
#  define IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()	IUTEST_PRAGMA_MSC_WARN_PUSH()	\
																			IUTEST_PRAGMA_MSC_WARN_DISABLE(4592)
#  define IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()		IUTEST_PRAGMA_MSC_WARN_POP()
#else
#  define IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
#  define IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
#endif


#if   defined(_MSC_VER)
#  define IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()	IUTEST_PRAGMA(warning (disable:4389 4018))
#elif defined(__clang__)
#  define IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()	IUTEST_PRAGMA_CLANG_WARN_DISABLE("-Wsign-compare")
#elif defined(__GNUC__)
#  define IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()	IUTEST_PRAGMA_GCC_WARN_DISABLE("-Wsign-compare")
#else
#  define IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()
#endif

#if   defined(_MSC_VER)
#  define IUTEST_PRAGMA_WARN_DISABLE_EMPTY_BODY()	IUTEST_PRAGMA(warning (disable:4390))
#elif defined(__clang__)
#  define IUTEST_PRAGMA_WARN_DISABLE_EMPTY_BODY()	IUTEST_PRAGMA_CLANG_WARN_DISABLE("-Wempty-body")
#elif defined(__GNUC__)
#  define IUTEST_PRAGMA_WARN_DISABLE_EMPTY_BODY()	IUTEST_PRAGMA_GCC_WARN_DISABLE("-Wempty-body")
#else
#  define IUTEST_PRAGMA_WARN_DISABLE_EMPTY_BODY()
#endif

#endif // INCG_IRIS_IUTEST_PRAGMA_HPP_FBC5A1DE_3D0C_443E_84B1_5F0618DF9A6B_

#if defined(_MSC_VER) && _MSC_VER < 1300
#  pragma warning(disable:4786)	// ident trunc to '255' chars in debug info
#endif

#endif // INCG_IRIS_IUTEST_COMPILER_HPP_6DDB27E8_E2FF_4754_80B0_F500025820C4_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_pp.hpp
 * @brief		iris unit test プリプロセッサ 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PP_HPP_E8F72184_9C72_4E74_B581_A1F51F291F3A_
#define INCG_IRIS_IUTEST_PP_HPP_E8F72184_9C72_4E74_B581_A1F51F291F3A_

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

/**
 * @brief	コピー禁止定義
*/
#define IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TypeName)	\
	TypeName( const TypeName& );						\
	TypeName& operator = ( const TypeName& )

/**
 * @brief	代入禁止定義
*/
#define IUTEST_PP_DISALLOW_ASSIGN(TypeName)		\
	TypeName& operator = ( const TypeName& )

/**
 * @brief	コピー/ムーブ禁止定義
*/
#if defined(IUTEST_HAS_RVALUE_REFS) && IUTEST_HAS_RVALUE_REFS
#  define IUTEST_PP_DISALLOW_MOVE_AND_COPY_AND_ASSIGN(TypeName)	\
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TypeName);				\
	TypeName( TypeName&& rhs );									\
	TypeName& operator = ( TypeName&& )
#else
#  define IUTEST_PP_DISALLOW_MOVE_AND_COPY_AND_ASSIGN(TypeName)	\
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TypeName)
#endif

/**
 * @private
 * @{
*/

#if !defined(IUTEST_PP_TOSTRING)
#  define IUTEST_PP_TOSTRING(z_)	IUTEST_PP_TOSTRING_(z_)
#endif
#define IUTEST_PP_TOSTRING_(z_)		#z_

#if !defined(IUTEST_PP_CAT)
#  define IUTEST_PP_CAT(a_, b_)		IUTEST_PP_CAT_(a_, b_)
#endif
#define IUTEST_PP_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		IUTEST_PP_CAT(__LINE__, __COUNTER__)
#else
#  define IUTEST_PP_UNIQUEID		__LINE__
#endif

#define IUTEST_UNUSED_VAR(x)		(void)(x)

// DEC
#define IUTEST_PP_DEC(n)	IUTEST_PP_DEC_I(n)
#define IUTEST_PP_DEC_I(n)	IUTEST_PP_DEC_##n
#define IUTEST_PP_DEC_0		nil
#define IUTEST_PP_DEC_1		0
#define IUTEST_PP_DEC_2		1
#define IUTEST_PP_DEC_3		2
#define IUTEST_PP_DEC_4		3
#define IUTEST_PP_DEC_5		4
#define IUTEST_PP_DEC_6		5
#define IUTEST_PP_DEC_7		6
#define IUTEST_PP_DEC_8		7
#define IUTEST_PP_DEC_9		8
#define IUTEST_PP_DEC_10	9
#define IUTEST_PP_DEC_11	10
#define IUTEST_PP_DEC_12	11
#define IUTEST_PP_DEC_13	12
#define IUTEST_PP_DEC_14	13
#define IUTEST_PP_DEC_15	14
#define IUTEST_PP_DEC_16	15
#define IUTEST_PP_DEC_17	16
#define IUTEST_PP_DEC_18	17
#define IUTEST_PP_DEC_19	18
#define IUTEST_PP_DEC_20	19
#define IUTEST_PP_DEC_21	20
#define IUTEST_PP_DEC_22	21
#define IUTEST_PP_DEC_23	22
#define IUTEST_PP_DEC_24	23
#define IUTEST_PP_DEC_25	24
#define IUTEST_PP_DEC_26	25
#define IUTEST_PP_DEC_27	26
#define IUTEST_PP_DEC_28	27
#define IUTEST_PP_DEC_29	28
#define IUTEST_PP_DEC_30	29
#define IUTEST_PP_DEC_31	30
#define IUTEST_PP_DEC_32	31
#define IUTEST_PP_DEC_33	32
#define IUTEST_PP_DEC_34	33
#define IUTEST_PP_DEC_35	34
#define IUTEST_PP_DEC_36	35
#define IUTEST_PP_DEC_37	36
#define IUTEST_PP_DEC_38	37
#define IUTEST_PP_DEC_39	38
#define IUTEST_PP_DEC_40	39
#define IUTEST_PP_DEC_41	40
#define IUTEST_PP_DEC_42	41
#define IUTEST_PP_DEC_43	42
#define IUTEST_PP_DEC_44	43
#define IUTEST_PP_DEC_45	44
#define IUTEST_PP_DEC_46	45
#define IUTEST_PP_DEC_47	46
#define IUTEST_PP_DEC_48	47
#define IUTEST_PP_DEC_49	48
#define IUTEST_PP_DEC_50	49
#define IUTEST_PP_DEC_51	50
#define IUTEST_PP_DEC_52	51
#define IUTEST_PP_DEC_53	52
#define IUTEST_PP_DEC_54	53
#define IUTEST_PP_DEC_55	54
#define IUTEST_PP_DEC_56	55
#define IUTEST_PP_DEC_57	56
#define IUTEST_PP_DEC_58	57
#define IUTEST_PP_DEC_59	58
#define IUTEST_PP_DEC_60	59
#define IUTEST_PP_DEC_61	60
#define IUTEST_PP_DEC_62	61
#define IUTEST_PP_DEC_63	62
#define IUTEST_PP_DEC_64	63
#define IUTEST_PP_DEC_65	64
#define IUTEST_PP_DEC_66	65
#define IUTEST_PP_DEC_67	66
#define IUTEST_PP_DEC_68	67
#define IUTEST_PP_DEC_69	68
#define IUTEST_PP_DEC_70	69
#define IUTEST_PP_DEC_71	70
#define IUTEST_PP_DEC_72	71
#define IUTEST_PP_DEC_73	72
#define IUTEST_PP_DEC_74	73
#define IUTEST_PP_DEC_75	74
#define IUTEST_PP_DEC_76	75
#define IUTEST_PP_DEC_77	76
#define IUTEST_PP_DEC_78	77
#define IUTEST_PP_DEC_79	78
#define IUTEST_PP_DEC_80	79
#define IUTEST_PP_DEC_81	80
#define IUTEST_PP_DEC_82	81
#define IUTEST_PP_DEC_83	82
#define IUTEST_PP_DEC_84	83
#define IUTEST_PP_DEC_85	84
#define IUTEST_PP_DEC_86	85
#define IUTEST_PP_DEC_87	86
#define IUTEST_PP_DEC_88	87
#define IUTEST_PP_DEC_89	88
#define IUTEST_PP_DEC_90	89
#define IUTEST_PP_DEC_91	90
#define IUTEST_PP_DEC_92	91
#define IUTEST_PP_DEC_93	92
#define IUTEST_PP_DEC_94	93
#define IUTEST_PP_DEC_95	94
#define IUTEST_PP_DEC_96	95
#define IUTEST_PP_DEC_97	96
#define IUTEST_PP_DEC_98	97
#define IUTEST_PP_DEC_99	98
#define IUTEST_PP_DEC_100	99

// INC
#define IUTEST_PP_INC(n)	IUTEST_PP_INC_I(n)
#define IUTEST_PP_INC_I(n)	IUTEST_PP_INC_##n
#define IUTEST_PP_INC_0		1
#define IUTEST_PP_INC_1		2
#define IUTEST_PP_INC_2		3
#define IUTEST_PP_INC_3		4
#define IUTEST_PP_INC_4		5
#define IUTEST_PP_INC_5		6
#define IUTEST_PP_INC_6		7
#define IUTEST_PP_INC_7		8
#define IUTEST_PP_INC_8		9
#define IUTEST_PP_INC_9		10
#define IUTEST_PP_INC_10	11
#define IUTEST_PP_INC_11	12
#define IUTEST_PP_INC_12	13
#define IUTEST_PP_INC_13	14
#define IUTEST_PP_INC_14	15
#define IUTEST_PP_INC_15	16
#define IUTEST_PP_INC_16	17
#define IUTEST_PP_INC_17	18
#define IUTEST_PP_INC_18	19
#define IUTEST_PP_INC_19	20
#define IUTEST_PP_INC_20	21
#define IUTEST_PP_INC_21	22
#define IUTEST_PP_INC_22	23
#define IUTEST_PP_INC_23	24
#define IUTEST_PP_INC_24	25
#define IUTEST_PP_INC_25	26
#define IUTEST_PP_INC_26	27
#define IUTEST_PP_INC_27	28
#define IUTEST_PP_INC_28	29
#define IUTEST_PP_INC_29	30
#define IUTEST_PP_INC_30	31
#define IUTEST_PP_INC_31	32
#define IUTEST_PP_INC_32	33
#define IUTEST_PP_INC_33	34
#define IUTEST_PP_INC_34	35
#define IUTEST_PP_INC_35	36
#define IUTEST_PP_INC_36	37
#define IUTEST_PP_INC_37	38
#define IUTEST_PP_INC_38	39
#define IUTEST_PP_INC_39	40
#define IUTEST_PP_INC_40	41
#define IUTEST_PP_INC_41	42
#define IUTEST_PP_INC_42	43
#define IUTEST_PP_INC_43	44
#define IUTEST_PP_INC_44	45
#define IUTEST_PP_INC_45	46
#define IUTEST_PP_INC_46	47
#define IUTEST_PP_INC_47	48
#define IUTEST_PP_INC_48	49
#define IUTEST_PP_INC_49	50
#define IUTEST_PP_INC_50	51
#define IUTEST_PP_INC_51	52
#define IUTEST_PP_INC_52	53
#define IUTEST_PP_INC_53	54
#define IUTEST_PP_INC_54	55
#define IUTEST_PP_INC_55	56
#define IUTEST_PP_INC_56	57
#define IUTEST_PP_INC_57	58
#define IUTEST_PP_INC_58	59
#define IUTEST_PP_INC_59	60
#define IUTEST_PP_INC_60	61
#define IUTEST_PP_INC_61	62
#define IUTEST_PP_INC_62	63
#define IUTEST_PP_INC_63	64
#define IUTEST_PP_INC_64	65
#define IUTEST_PP_INC_65	66
#define IUTEST_PP_INC_66	67
#define IUTEST_PP_INC_67	68
#define IUTEST_PP_INC_68	69
#define IUTEST_PP_INC_69	70
#define IUTEST_PP_INC_70	71
#define IUTEST_PP_INC_71	72
#define IUTEST_PP_INC_72	73
#define IUTEST_PP_INC_73	74
#define IUTEST_PP_INC_74	75
#define IUTEST_PP_INC_75	76
#define IUTEST_PP_INC_76	77
#define IUTEST_PP_INC_77	78
#define IUTEST_PP_INC_78	79
#define IUTEST_PP_INC_79	80
#define IUTEST_PP_INC_80	81
#define IUTEST_PP_INC_81	82
#define IUTEST_PP_INC_82	83
#define IUTEST_PP_INC_83	84
#define IUTEST_PP_INC_84	85
#define IUTEST_PP_INC_85	86
#define IUTEST_PP_INC_86	87
#define IUTEST_PP_INC_87	88
#define IUTEST_PP_INC_88	89
#define IUTEST_PP_INC_89	90
#define IUTEST_PP_INC_90	91
#define IUTEST_PP_INC_91	92
#define IUTEST_PP_INC_92	93
#define IUTEST_PP_INC_93	94
#define IUTEST_PP_INC_94	95
#define IUTEST_PP_INC_95	96
#define IUTEST_PP_INC_96	97
#define IUTEST_PP_INC_97	98
#define IUTEST_PP_INC_98	99
#define IUTEST_PP_INC_99	100
#define IUTEST_PP_INC_100	nil

// REPEAT
#define IUTEST_PP_LIMIT_REPEAT	50

#define IUTEST_PP_REPEAT_PARAMS_MACRO_(i, param)	param
#define IUTEST_PP_REPEAT_PARAMS_MACRO_IN_BINARY_(i, param1, param2)	param2(i, param1)

#define IUTEST_PP_REPEAT_PARAMS(n, param)			IUTEST_PP_REPEAT(n, IUTEST_PP_REPEAT_PARAMS_MACRO_, param)
#define IUTEST_PP_REPEAT(n, m, param)				IUTEST_PP_REPEAT_BINARY(n, IUTEST_PP_REPEAT_PARAMS_MACRO_IN_BINARY_, param, m)

#define IUTEST_PP_REPEAT_BINARY_PARAMS_MACRO_(i, param1, param2)	param1 param2

#define IUTEST_PP_REPEAT_BINARY_PARAMS(n, param1, param2)	IUTEST_PP_REPEAT_BINARY(n, IUTEST_PP_REPEAT_BINARY_PARAMS_MACRO_, param1, param2)
#define IUTEST_PP_REPEAT_BINARY(n, m, param1, param2)		IUTEST_PP_REPEAT_BINARY_PARAMS_I(n, m, param1, param2)

#define IUTEST_PP_REPEAT_BINARY_PARAMS_I(n, m, p1, p2)	IUTEST_PP_CAT(IUTEST_PP_REPEAT_I_, IUTEST_PP_DEC(n))(0, m, p1, p2)

#define IUTEST_PP_REPEAT_I_nil(i, m, p1, p2)
#define IUTEST_PP_REPEAT_I_0( i, m, p1, p2)		m(i, p1, p2)
#define IUTEST_PP_REPEAT_I_1( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_0 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_2( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_1 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_3( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_2 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_4( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_3 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_5( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_4 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_6( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_5 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_7( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_6 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_8( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_7 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_9( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_8 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_10(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_9 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_11(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_10(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_12(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_11(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_13(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_12(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_14(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_13(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_15(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_14(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_16(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_15(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_17(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_16(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_18(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_17(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_19(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_18(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_20(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_19(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_21(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_20(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_22(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_21(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_23(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_22(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_24(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_23(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_25(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_24(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_26(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_25(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_27(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_26(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_28(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_27(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_29(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_28(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_30(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_29(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_31(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_30(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_32(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_31(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_33(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_32(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_34(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_33(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_35(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_34(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_36(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_35(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_37(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_36(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_38(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_37(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_39(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_38(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_40(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_39(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_41(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_40(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_42(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_41(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_43(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_42(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_44(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_43(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_45(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_44(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_46(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_45(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_47(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_46(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_48(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_47(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_49(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_48(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_50(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_49(IUTEST_PP_INC(i), m, p1, p2)

// ENUM
#define IUTEST_PP_LIMIT_ENUM	50

#define IUTEST_PP_ENUM_PARAMS_MACRO_(i, param)	IUTEST_PP_CAT(param, i)
#define IUTEST_PP_ENUM_PARAMS_MACRO_IN_BINARY_(i, param1, param2)	param2(i, param1)

#define IUTEST_PP_ENUM_PARAMS(n, param)			IUTEST_PP_ENUM(n, IUTEST_PP_ENUM_PARAMS_MACRO_, param)
#define IUTEST_PP_ENUM(n, m, param)				IUTEST_PP_ENUM_BINARY(n, IUTEST_PP_ENUM_PARAMS_MACRO_IN_BINARY_, param, m)

#define IUTEST_PP_ENUM_SHIFTED_PARAMS(n, param)	IUTEST_PP_ENUM_SHIFTED(n, IUTEST_PP_ENUM_PARAMS_MACRO_, param)
#define IUTEST_PP_ENUM_SHIFTED(n, m, param)		IUTEST_PP_ENUM_SHIFTED_BINARY(n, IUTEST_PP_ENUM_PARAMS_MACRO_IN_BINARY_, param, m)

#define IUTEST_PP_ENUM_BINARY_PARAMS_MACRO_(i, param1, param2)	IUTEST_PP_CAT(param1, i) IUTEST_PP_CAT(param2, i)

#define IUTEST_PP_ENUM_BINARY_PARAMS(n, param1, param2)			IUTEST_PP_ENUM_BINARY(n, IUTEST_PP_ENUM_BINARY_PARAMS_MACRO_, param1, param2)
#define IUTEST_PP_ENUM_BINARY(n, m, param1, param2)				IUTEST_PP_ENUM_BINARY_PARAMS_I(0, n, m, param1, param2)

#define IUTEST_PP_ENUM_SHIFTED_BINARY_PARAMS(n, param1, param2)	IUTEST_PP_ENUM_BINARY(n, IUTEST_PP_ENUM_BINARY_PARAMS_MACRO_, param1, param2)
#define IUTEST_PP_ENUM_SHIFTED_BINARY(n, m, param1, param2)		IUTEST_PP_ENUM_BINARY_PARAMS_I(1, n, m, param1, param2)

#define IUTEST_PP_ENUM_BINARY_PARAMS_I(begin, n, m, p1, p2)	IUTEST_PP_CAT(IUTEST_PP_ENUM_I_, IUTEST_PP_DEC(n))(begin, m, p1, p2)

#define IUTEST_PP_ENUM_I_nil(i, m, p1, p2)	
#define IUTEST_PP_ENUM_I_0( i, m, p1, p2)	m(i, p1, p2)
#define IUTEST_PP_ENUM_I_1( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_0 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_2( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_1 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_3( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_2 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_4( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_3 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_5( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_4 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_6( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_5 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_7( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_6 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_8( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_7 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_9( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_8 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_10(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_9 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_11(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_10(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_12(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_11(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_13(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_12(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_14(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_13(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_15(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_14(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_16(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_15(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_17(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_16(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_18(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_17(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_19(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_18(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_20(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_19(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_21(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_20(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_22(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_21(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_23(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_22(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_24(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_23(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_25(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_24(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_26(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_25(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_27(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_26(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_28(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_27(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_29(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_28(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_30(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_29(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_31(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_30(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_32(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_31(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_33(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_32(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_34(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_33(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_35(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_34(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_36(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_35(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_37(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_36(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_38(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_37(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_39(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_38(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_40(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_39(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_41(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_40(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_42(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_41(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_43(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_42(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_44(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_43(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_45(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_44(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_46(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_45(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_47(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_46(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_48(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_47(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_49(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_48(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_50(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_49(IUTEST_PP_INC(i), m, p1, p2)

// BOOL
#define IUTEST_PP_BOOL(n)	IUTEST_PP_BOOL_I(n)
#define IUTEST_PP_BOOL_I(n)	IUTEST_PP_BOOL_##n
#define IUTEST_PP_BOOL_0	0
#define IUTEST_PP_BOOL_1	1
#define IUTEST_PP_BOOL_2	1
#define IUTEST_PP_BOOL_3	1
#define IUTEST_PP_BOOL_4	1
#define IUTEST_PP_BOOL_5	1
#define IUTEST_PP_BOOL_6	1
#define IUTEST_PP_BOOL_7	1
#define IUTEST_PP_BOOL_8	1
#define IUTEST_PP_BOOL_9	1
#define IUTEST_PP_BOOL_10	1
#define IUTEST_PP_BOOL_11	1
#define IUTEST_PP_BOOL_12	1
#define IUTEST_PP_BOOL_13	1
#define IUTEST_PP_BOOL_14	1
#define IUTEST_PP_BOOL_15	1
#define IUTEST_PP_BOOL_16	1
#define IUTEST_PP_BOOL_17	1
#define IUTEST_PP_BOOL_18	1
#define IUTEST_PP_BOOL_19	1
#define IUTEST_PP_BOOL_20	1
#define IUTEST_PP_BOOL_21	1
#define IUTEST_PP_BOOL_22	1
#define IUTEST_PP_BOOL_23	1
#define IUTEST_PP_BOOL_24	1
#define IUTEST_PP_BOOL_25	1
#define IUTEST_PP_BOOL_26	1
#define IUTEST_PP_BOOL_27	1
#define IUTEST_PP_BOOL_28	1
#define IUTEST_PP_BOOL_29	1
#define IUTEST_PP_BOOL_30	1
#define IUTEST_PP_BOOL_31	1
#define IUTEST_PP_BOOL_32	1
#define IUTEST_PP_BOOL_33	1
#define IUTEST_PP_BOOL_34	1
#define IUTEST_PP_BOOL_35	1
#define IUTEST_PP_BOOL_36	1
#define IUTEST_PP_BOOL_37	1
#define IUTEST_PP_BOOL_38	1
#define IUTEST_PP_BOOL_39	1
#define IUTEST_PP_BOOL_40	1
#define IUTEST_PP_BOOL_41	1
#define IUTEST_PP_BOOL_42	1
#define IUTEST_PP_BOOL_43	1
#define IUTEST_PP_BOOL_44	1
#define IUTEST_PP_BOOL_45	1
#define IUTEST_PP_BOOL_46	1
#define IUTEST_PP_BOOL_47	1
#define IUTEST_PP_BOOL_48	1
#define IUTEST_PP_BOOL_49	1
#define IUTEST_PP_BOOL_50	1
#define IUTEST_PP_BOOL_51	1
#define IUTEST_PP_BOOL_52	1
#define IUTEST_PP_BOOL_53	1
#define IUTEST_PP_BOOL_54	1
#define IUTEST_PP_BOOL_55	1
#define IUTEST_PP_BOOL_56	1
#define IUTEST_PP_BOOL_57	1
#define IUTEST_PP_BOOL_58	1
#define IUTEST_PP_BOOL_59	1
#define IUTEST_PP_BOOL_60	1
#define IUTEST_PP_BOOL_61	1
#define IUTEST_PP_BOOL_62	1
#define IUTEST_PP_BOOL_63	1
#define IUTEST_PP_BOOL_64	1
#define IUTEST_PP_BOOL_65	1
#define IUTEST_PP_BOOL_66	1
#define IUTEST_PP_BOOL_67	1
#define IUTEST_PP_BOOL_68	1
#define IUTEST_PP_BOOL_69	1
#define IUTEST_PP_BOOL_70	1
#define IUTEST_PP_BOOL_71	1
#define IUTEST_PP_BOOL_72	1
#define IUTEST_PP_BOOL_73	1
#define IUTEST_PP_BOOL_74	1
#define IUTEST_PP_BOOL_75	1
#define IUTEST_PP_BOOL_76	1
#define IUTEST_PP_BOOL_77	1
#define IUTEST_PP_BOOL_78	1
#define IUTEST_PP_BOOL_79	1
#define IUTEST_PP_BOOL_80	1
#define IUTEST_PP_BOOL_81	1
#define IUTEST_PP_BOOL_82	1
#define IUTEST_PP_BOOL_83	1
#define IUTEST_PP_BOOL_84	1
#define IUTEST_PP_BOOL_85	1
#define IUTEST_PP_BOOL_86	1
#define IUTEST_PP_BOOL_87	1
#define IUTEST_PP_BOOL_88	1
#define IUTEST_PP_BOOL_89	1
#define IUTEST_PP_BOOL_90	1
#define IUTEST_PP_BOOL_91	1
#define IUTEST_PP_BOOL_92	1
#define IUTEST_PP_BOOL_93	1
#define IUTEST_PP_BOOL_94	1
#define IUTEST_PP_BOOL_95	1
#define IUTEST_PP_BOOL_96	1
#define IUTEST_PP_BOOL_97	1
#define IUTEST_PP_BOOL_98	1
#define IUTEST_PP_BOOL_99	1
#define IUTEST_PP_BOOL_100	1
#define IUTEST_PP_BOOL_101	1
#define IUTEST_PP_BOOL_102	1
#define IUTEST_PP_BOOL_103	1
#define IUTEST_PP_BOOL_104	1
#define IUTEST_PP_BOOL_105	1
#define IUTEST_PP_BOOL_106	1
#define IUTEST_PP_BOOL_107	1
#define IUTEST_PP_BOOL_108	1
#define IUTEST_PP_BOOL_109	1
#define IUTEST_PP_BOOL_110	1
#define IUTEST_PP_BOOL_111	1
#define IUTEST_PP_BOOL_112	1
#define IUTEST_PP_BOOL_113	1
#define IUTEST_PP_BOOL_114	1
#define IUTEST_PP_BOOL_115	1
#define IUTEST_PP_BOOL_116	1
#define IUTEST_PP_BOOL_117	1
#define IUTEST_PP_BOOL_118	1
#define IUTEST_PP_BOOL_119	1
#define IUTEST_PP_BOOL_120	1
#define IUTEST_PP_BOOL_121	1
#define IUTEST_PP_BOOL_122	1
#define IUTEST_PP_BOOL_123	1
#define IUTEST_PP_BOOL_124	1
#define IUTEST_PP_BOOL_125	1
#define IUTEST_PP_BOOL_126	1
#define IUTEST_PP_BOOL_127	1
#define IUTEST_PP_BOOL_128	1
#define IUTEST_PP_BOOL_129	1
#define IUTEST_PP_BOOL_130	1
#define IUTEST_PP_BOOL_131	1
#define IUTEST_PP_BOOL_132	1
#define IUTEST_PP_BOOL_133	1
#define IUTEST_PP_BOOL_134	1
#define IUTEST_PP_BOOL_135	1
#define IUTEST_PP_BOOL_136	1
#define IUTEST_PP_BOOL_137	1
#define IUTEST_PP_BOOL_138	1
#define IUTEST_PP_BOOL_139	1
#define IUTEST_PP_BOOL_140	1
#define IUTEST_PP_BOOL_141	1
#define IUTEST_PP_BOOL_142	1
#define IUTEST_PP_BOOL_143	1
#define IUTEST_PP_BOOL_144	1
#define IUTEST_PP_BOOL_145	1
#define IUTEST_PP_BOOL_146	1
#define IUTEST_PP_BOOL_147	1
#define IUTEST_PP_BOOL_148	1
#define IUTEST_PP_BOOL_149	1
#define IUTEST_PP_BOOL_150	1
#define IUTEST_PP_BOOL_151	1
#define IUTEST_PP_BOOL_152	1
#define IUTEST_PP_BOOL_153	1
#define IUTEST_PP_BOOL_154	1
#define IUTEST_PP_BOOL_155	1
#define IUTEST_PP_BOOL_156	1
#define IUTEST_PP_BOOL_157	1
#define IUTEST_PP_BOOL_158	1
#define IUTEST_PP_BOOL_159	1
#define IUTEST_PP_BOOL_160	1
#define IUTEST_PP_BOOL_161	1
#define IUTEST_PP_BOOL_162	1
#define IUTEST_PP_BOOL_163	1
#define IUTEST_PP_BOOL_164	1
#define IUTEST_PP_BOOL_165	1
#define IUTEST_PP_BOOL_166	1
#define IUTEST_PP_BOOL_167	1
#define IUTEST_PP_BOOL_168	1
#define IUTEST_PP_BOOL_169	1
#define IUTEST_PP_BOOL_170	1
#define IUTEST_PP_BOOL_171	1
#define IUTEST_PP_BOOL_172	1
#define IUTEST_PP_BOOL_173	1
#define IUTEST_PP_BOOL_174	1
#define IUTEST_PP_BOOL_175	1
#define IUTEST_PP_BOOL_176	1
#define IUTEST_PP_BOOL_177	1
#define IUTEST_PP_BOOL_178	1
#define IUTEST_PP_BOOL_179	1
#define IUTEST_PP_BOOL_180	1
#define IUTEST_PP_BOOL_181	1
#define IUTEST_PP_BOOL_182	1
#define IUTEST_PP_BOOL_183	1
#define IUTEST_PP_BOOL_184	1
#define IUTEST_PP_BOOL_185	1
#define IUTEST_PP_BOOL_186	1
#define IUTEST_PP_BOOL_187	1
#define IUTEST_PP_BOOL_188	1
#define IUTEST_PP_BOOL_189	1
#define IUTEST_PP_BOOL_190	1
#define IUTEST_PP_BOOL_191	1
#define IUTEST_PP_BOOL_192	1
#define IUTEST_PP_BOOL_193	1
#define IUTEST_PP_BOOL_194	1
#define IUTEST_PP_BOOL_195	1
#define IUTEST_PP_BOOL_196	1
#define IUTEST_PP_BOOL_197	1
#define IUTEST_PP_BOOL_198	1
#define IUTEST_PP_BOOL_199	1
#define IUTEST_PP_BOOL_200	1
#define IUTEST_PP_BOOL_201	1
#define IUTEST_PP_BOOL_202	1
#define IUTEST_PP_BOOL_203	1
#define IUTEST_PP_BOOL_204	1
#define IUTEST_PP_BOOL_205	1
#define IUTEST_PP_BOOL_206	1
#define IUTEST_PP_BOOL_207	1
#define IUTEST_PP_BOOL_208	1
#define IUTEST_PP_BOOL_209	1
#define IUTEST_PP_BOOL_210	1
#define IUTEST_PP_BOOL_211	1
#define IUTEST_PP_BOOL_212	1
#define IUTEST_PP_BOOL_213	1
#define IUTEST_PP_BOOL_214	1
#define IUTEST_PP_BOOL_215	1
#define IUTEST_PP_BOOL_216	1
#define IUTEST_PP_BOOL_217	1
#define IUTEST_PP_BOOL_218	1
#define IUTEST_PP_BOOL_219	1
#define IUTEST_PP_BOOL_220	1
#define IUTEST_PP_BOOL_221	1
#define IUTEST_PP_BOOL_222	1
#define IUTEST_PP_BOOL_223	1
#define IUTEST_PP_BOOL_224	1
#define IUTEST_PP_BOOL_225	1
#define IUTEST_PP_BOOL_226	1
#define IUTEST_PP_BOOL_227	1
#define IUTEST_PP_BOOL_228	1
#define IUTEST_PP_BOOL_229	1
#define IUTEST_PP_BOOL_230	1
#define IUTEST_PP_BOOL_231	1
#define IUTEST_PP_BOOL_232	1
#define IUTEST_PP_BOOL_233	1
#define IUTEST_PP_BOOL_234	1
#define IUTEST_PP_BOOL_235	1
#define IUTEST_PP_BOOL_236	1
#define IUTEST_PP_BOOL_237	1
#define IUTEST_PP_BOOL_238	1
#define IUTEST_PP_BOOL_239	1
#define IUTEST_PP_BOOL_240	1
#define IUTEST_PP_BOOL_241	1
#define IUTEST_PP_BOOL_242	1
#define IUTEST_PP_BOOL_243	1
#define IUTEST_PP_BOOL_244	1
#define IUTEST_PP_BOOL_245	1
#define IUTEST_PP_BOOL_246	1
#define IUTEST_PP_BOOL_247	1
#define IUTEST_PP_BOOL_248	1
#define IUTEST_PP_BOOL_249	1
#define IUTEST_PP_BOOL_250	1
#define IUTEST_PP_BOOL_251	1
#define IUTEST_PP_BOOL_252	1
#define IUTEST_PP_BOOL_253	1
#define IUTEST_PP_BOOL_254	1
#define IUTEST_PP_BOOL_255	1

// IF
#define IUTEST_PP_IF(cond, t, f)	IUTEST_PP_IF_I(IUTEST_PP_BOOL(cond), t, f)
#define IUTEST_PP_IF_I(cond, t, f)	IUTEST_PP_CAT(IUTEST_PP_IF_, cond)(t, f)
#define IUTEST_PP_IF_0(t, f)		f
#define IUTEST_PP_IF_1(t, f)		t

// IS EMPTY
#define IUTEST_PP_IS_EMPTY(x)		IUTEST_PP_IS_EMPTY_I(x IUTEST_PP_EMPTY_TAG)
#define IUTEST_PP_IS_EMPTY_I(x)		IUTEST_PP_IS_EMPTY_I_( IUTEST_PP_CAT(IUTEST_PP_EMPTY_TAG_, x)() )
#define IUTEST_PP_IS_EMPTY_I_(x)	IUTEST_PP_IS_EMPTY_II((x))
#define IUTEST_PP_IS_EMPTY_II(x)	IUTEST_PP_IS_EMPTY_II_ x
#define IUTEST_PP_IS_EMPTY_II_(a, b)	b

#define IUTEST_PP_EMPTY()		
#define IUTEST_PP_EMPTY_TAG()	, 0
#define IUTEST_PP_EMPTY_TAG_IUTEST_PP_EMPTY_TAG	1, 1 IUTEST_PP_EMPTY

/**
 * @}
*/

#endif // INCG_IRIS_IUTEST_PP_HPP_E8F72184_9C72_4E74_B581_A1F51F291F3A_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_stdlib.hpp
 * @brief		iris unit test stdlib
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_STDLIB_HPP_54D4BEEE_7B6B_4AF4_B1F6_138560480D55_
#define INCG_IRIS_IUTEST_STDLIB_HPP_54D4BEEE_7B6B_4AF4_B1F6_138560480D55_

//======================================================================
// include
#if defined(IUTEST_USE_GTEST) && defined(__STRICT_ANSI__)
#  undef __STRICT_ANSI__
#  include <cstdio>
#  include <string.h>
#  include <stdlib.h>
#  define __STRICT_ANSI__
#endif
#include <cstdlib>

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

// tuple
#if defined(IUTEST_USE_EXTERNAL_TR1_TUPLE) && IUTEST_USE_EXTERNAL_TR1_TUPLE
# define IUTEST_HAS_STD_TUPLE	0
#endif

#if !defined(IUTEST_USE_EXTERNAL_TR1_TUPLE)
#  define IUTEST_USE_EXTERNAL_TR1_TUPLE	0
#endif

//! has ::std::tuple
#if !defined(IUTEST_HAS_STD_TUPLE)
#  if   defined(IUTEST_USE_EXTERNAL_STD_TUPLE) && IUTEST_USE_EXTERNAL_STD_TUPLE
#    define IUTEST_HAS_STD_TUPLE	1
#  elif defined(_STLPORT_VERSION)
#    define IUTEST_HAS_STD_TUPLE	0
#  elif defined(_MSC_VER)
#    if (_MSC_VER > 1700) || (_MSC_VER == 1700 && _VARIADIC_MAX >= 9)
#      define IUTEST_HAS_STD_TUPLE	1
#    endif
#  elif defined(__clang__)
#    if __has_include( <tuple> ) && IUTEST_HAS_VARIADIC_TEMPLATES
#      define IUTEST_HAS_STD_TUPLE	1
#    endif
#  elif defined(__GNUC__)
#    if IUTEST_HAS_VARIADIC_TEMPLATES
#      define IUTEST_HAS_STD_TUPLE	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_STD_TUPLE)
#  define IUTEST_HAS_STD_TUPLE		0
#endif

#ifndef IUTEST_USE_EXTERNAL_STD_TUPLE
#  define IUTEST_USE_EXTERNAL_STD_TUPLE	0
#endif

#if !IUTEST_HAS_STD_TUPLE

// ::std::tr1::tuple
#if !defined(IUTEST_HAS_TR1_TUPLE)
#  if   defined(IUTEST_USE_EXTERNAL_TR1_TUPLE) && IUTEST_USE_EXTERNAL_TR1_TUPLE
#    define IUTEST_HAS_TR1_TUPLE	1
#  elif defined(_STLPORT_VERSION)
#    define IUTEST_HAS_TR1_TUPLE	0
#  elif defined(IUTEST_OS_LINUX_ANDROID) && defined(_STLPORT_MAJOR)
#    define IUTEST_HAS_TR1_TUPLE	0
#  elif defined(_MSC_VER) && defined(_MSC_FULL_VER)
#    if (_MSC_VER >= 1500) && (_MSC_VER < 1700) && (_MSC_FULL_VER > 150021022)
#      define IUTEST_HAS_TR1_TUPLE	1
#    endif
#  elif defined(__clang__)
#    if __has_include( <tr1/tuple> )
#      define IUTEST_HAS_TR1_TUPLE	1
#    endif
#  elif defined(__GNUC__)
#    if (!defined(__CUDACC__) && !defined(__ARMCC_VERSION) && (__GNUC__ >= 4))
#      define IUTEST_HAS_TR1_TUPLE	1
#    endif
#  endif
#endif

#endif

#if !defined(IUTEST_HAS_TR1_TUPLE)
#  define IUTEST_HAS_TR1_TUPLE		0
#endif

#if !defined(IUTEST_USE_OWN_TR1_TUPLE)
#  define IUTEST_USE_OWN_TR1_TUPLE	0
#endif

#if IUTEST_HAS_STD_TUPLE || IUTEST_HAS_TR1_TUPLE
#  if !defined(IUTEST_HAS_TUPLE)
#    define IUTEST_HAS_TUPLE	1
#  endif
#else
#  if defined(IUTEST_HAS_TUPLE)
#    undef IUTEST_HAS_TUPLE
#  endif
#  define IUTEST_HAS_TUPLE		0
#endif

#if IUTEST_HAS_TUPLE

#if IUTEST_HAS_STD_TUPLE
#  if !IUTEST_USE_EXTERNAL_STD_TUPLE
#    include <tuple>
#  endif
#else
#  if IUTEST_HAS_TR1_TUPLE && !IUTEST_USE_EXTERNAL_TR1_TUPLE
#    if IUTEST_USE_OWN_TR1_TUPLE
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_tuple.hpp
 * @brief		iris unit test tuple
 *
 * @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_TUPLE_HPP_E5143287_CE8A_49A1_8EFB_A10CB2857C9B_
#define INCG_IRIS_IUTEST_TUPLE_HPP_E5143287_CE8A_49A1_8EFB_A10CB2857C9B_

//======================================================================
// include

namespace iutest
{
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_TUPLE_HPP_E5143287_CE8A_49A1_8EFB_A10CB2857C9B_
#    else
#      if (defined(__GNUC__) && (__GNUC__ >= 4))
#        include <tr1/tuple>
#      else
#        include <tuple>
#      endif
#    endif
#  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

// regex
#if !defined(IUTEST_HAS_CXX_HDR_REGEX)

#if   defined(__has_include)
#  if __has_include( <regex> ) && IUTEST_HAS_CXX11
#    if !defined(__GLIBCXX__) || (__GLIBCXX__ > 20120301)
#      define IUTEST_HAS_CXX_HDR_REGEX		1
#    endif
#  endif
#elif defined(__GLIBCXX__)
#  if defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_CXX_HDR_REGEX		1
#    endif
#  else
#  endif
#elif defined(_MSC_VER)
#  if _MSC_VER > 1600
#    define IUTEST_HAS_CXX_HDR_REGEX		1
#  endif
#endif

#endif

#if !defined(IUTEST_HAS_CXX_HDR_REGEX)
#  define IUTEST_HAS_CXX_HDR_REGEX			0
#endif

// chrono
#if !defined(IUTEST_HAS_CXX_HDR_CHRONO)

#if   defined(__has_include)
#  if __has_include( <chrono> )
#    if IUTEST_HAS_CXX11
#      define IUTEST_HAS_CXX_HDR_CHRONO		1
#    endif
#  endif
#elif defined(__GLIBCXX__)
#  if defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_CXX_HDR_CHRONO		1
#    endif
#  else
#  endif
#elif defined(_MSC_VER)
#  if _MSC_VER > 1600
#    define IUTEST_HAS_CXX_HDR_CHRONO		1
#  endif
#endif

#endif

#if !defined(IUTEST_HAS_CXX_HDR_CHRONO)
#  define IUTEST_HAS_CXX_HDR_CHRONO			0
#endif

// random
#if !defined(IUTEST_HAS_CXX_HDR_RANDOM)

#if   defined(__has_include)
#  if __has_include( <random> )
#    if IUTEST_HAS_CXX11
#      define IUTEST_HAS_CXX_HDR_RANDOM		1
#    endif
#  endif
#elif defined(__GLIBCXX__)
#  if defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_CXX_HDR_RANDOM		1
#    endif
#  else
#  endif
#elif defined(_LIBCPP_VERSION)
#  if IUTEST_HAS_CXX11
#    define IUTEST_HAS_CXX_HDR_RANDOM		1
#  endif
#elif defined(_MSC_VER)
#  if _MSC_VER > 1600
#    define IUTEST_HAS_CXX_HDR_RANDOM		1
#  endif
#endif

#endif

#if !defined(IUTEST_HAS_CXX_HDR_RANDOM)
#  define IUTEST_HAS_CXX_HDR_RANDOM		0
#endif

// codecvt
/*
#if !defined(IUTEST_HAS_CXX_HDR_CODECVT)

#if   defined(__has_include)
#  if __has_include( <codecvt> )
#    if IUTEST_HAS_CXX11
#      define IUTEST_HAS_CXX_HDR_CODECVT	1
#    endif
#  endif
#elif defined(__GLIBCXX__)
#elif defined(_MSC_VER)
#  if _MSC_VER > 1600
#    define IUTEST_HAS_CXX_HDR_CODECVT		1
#  endif
#endif

#endif
*/

#if !defined(IUTEST_HAS_CXX_HDR_CODECVT)
#  define IUTEST_HAS_CXX_HDR_CODECVT		0
#endif

// emplace
#if !defined(IUTEST_HAS_STD_EMPLACE)
#  if defined(__GNUC__)
#    if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#      define IUTEST_HAS_STD_EMPLACE		1
#    endif
#  elif defined(__clang__)
#    define IUTEST_HAS_STD_EMPLACE			1
#  elif defined(_MSC_VER)
#    if (_MSC_VER > 1700)
#      define IUTEST_HAS_STD_EMPLACE		1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_STD_EMPLACE)
#  define IUTEST_HAS_STD_EMPLACE			0
#endif

// abi
#if !defined(IUTEST_HAS_HDR_CXXABI)

#if   defined(__clang__) && defined(__has_include)
#  if __has_include( <cxxabi.h> )
#    define IUTEST_HAS_HDR_CXXABI		1
#  endif
#elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
#  define IUTEST_HAS_HDR_CXXABI			1
#else
#  define IUTEST_HAS_HDR_CXXABI			0
#endif

#endif

#if !defined(IUTEST_HAS_HDR_CXXABI)
#  define IUTEST_HAS_HDR_CXXABI			0
#endif

// sys/time.h
#if !defined(IUTEST_HAS_HDR_SYSTIME)
#  if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MINGW) && !defined(IUTEST_OS_WINDOWS_WINE)
#    define IUTEST_HAS_HDR_SYSTIME		0
#  endif
#endif

#if !defined(IUTEST_HAS_HDR_SYSTIME)
#  define IUTEST_HAS_HDR_SYSTIME		1
#endif

// socklen_t
#if defined(IUTEST_OS_WINDOWS_WINE)
#  define __socklen_t_defined
#endif

namespace iutest {
namespace detail
{

//======================================================================
// function
/**
 * @internal
 * @brief	mbtowc
*/
inline int iu_mbtowc(wchar_t* dst, const char* src, size_t size)
{
#if defined(IUTEST_OS_LINUX_ANDROID) || defined(IUTEST_OS_WINDOWS_MOBILE)
	// unimplimented
	IUTEST_UNUSED_VAR(dst);
	IUTEST_UNUSED_VAR(src);
	IUTEST_UNUSED_VAR(size);
	return 0;
#else
	return mbtowc(dst, src, size);
#endif
}

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_STDLIB_HPP_54D4BEEE_7B6B_4AF4_B1F6_138560480D55_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_config.hpp
 * @brief		iris unit test config
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CONFIG_HPP_F0151607_0D9D_4055_B94D_ED4A0FFA748B_
#define INCG_IRIS_IUTEST_CONFIG_HPP_F0151607_0D9D_4055_B94D_ED4A0FFA748B_

//======================================================================
// include

/**
 * @defgroup	IUTEST_CONFIG	IUTEST_CONFIG
 * @brief		設定マクロ
 * @note		ユーザーが事前定義することで変更可能
 * @{
*/

//! Library を使うかどうか
#if !defined(IUTEST_HAS_LIB)
#  if   defined(IUTEST_NO_LIB)
#    define IUTEST_HAS_LIB			0
#  elif defined(IUTEST_USE_LIB) || defined(IUTEST_AUTO_LINK)
#    define IUTEST_HAS_LIB			1
#  endif
#endif

#if !defined(IUTEST_HAS_LIB)
#  define IUTEST_HAS_LIB			0
#endif

/**
 * @defgroup	IUTEST_CONFIG_OUTPUT	OUTPUT
 * @brief		出力関係 CONFIG
 * @{
*/

#if !defined(IUTEST_VPRINTF)
#  define IUTEST_VPRINTF(f, a)	vprintf(f, a)	//!< vprintf 呼び出しマクロ
#endif

#if !defined(IUTEST_HAS_REPORT_SKIPPED)
#  define IUTEST_HAS_REPORT_SKIPPED		1		//!< xml 出力に skipped タグを含めるかどうか
#endif

/**
 * @}
*/


/**
 * @defgroup	IUTEST_CONFIG_TEST	TEST
 * @brief		テスト関係 CONFIG
 * @{
*/

#if !defined(IUTEST_HAS_PARAM_METHOD_TEST)
//! パラメタライズ関数コールテストが使用可能かどうか
#  if   !defined(IUTEST_NO_VARIADIC_MACROS)
#    define IUTEST_HAS_PARAM_METHOD_TEST	1
#  else
#    define IUTEST_HAS_PARAM_METHOD_TEST	0
#  endif
#endif

#if !defined(IUTEST_HAS_PARAM_TEST)
#  define IUTEST_HAS_PARAM_TEST			1	//!< 値をパラメータ化したテストが使用可能かどうか
#endif

#if !defined(IUTEST_HAS_TYPED_TEST)
//! 型付けテストが使用可能かどうか
#  if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#    define IUTEST_HAS_TYPED_TEST		1
#  else
#    define IUTEST_HAS_TYPED_TEST		0
#  endif
#endif

#if !defined(IUTEST_HAS_TYPED_TEST_P)
//! 型をパラメータ化したテストが使用可能かどうか
#  if IUTEST_HAS_TYPED_TEST && !defined(IUTEST_NO_VARIADIC_MACROS) && !defined(IUTEST_NO_TEMPLATE_TEMPLATES)
#    define IUTEST_HAS_TYPED_TEST_P	1
#  else
#    define IUTEST_HAS_TYPED_TEST_P	0
#  endif
#endif

#if !defined(IUTEST_TYPED_TEST_P_STRICT)
//! Typed Test のより厳しい構文チェックを行うかどうか
#  define IUTEST_TYPED_TEST_P_STRICT	1
#endif

#if !defined(IUTEST_HAS_IGNORE_TEST)
/**
 * @brief	コンパイルが通らなくてもよいテスト生成マクロが使用可能かどうか
*/
#  if defined(IUTEST_NO_TWO_PHASE_NAME_LOOKUP)
#    define IUTEST_HAS_IGNORE_TEST	1
#  else
#    define IUTEST_HAS_IGNORE_TEST	0
#  endif
#endif

#if !defined(IUTEST_HAS_MATCHERS)
/**
 * @brief	IUTEST_*_THAT が使用可能かどうか
*/
#  if !defined(IUTEST_NO_SFINAE) && !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING) && !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#    define IUTEST_HAS_MATCHERS		1
#  else
#    define IUTEST_HAS_MATCHERS		0
#  endif
#endif

#if !defined(IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE)
/**
 * @brief	式アサーションで算術演算子の展開をサポートするかどうか
*/
#  if 1	// IUTEST_HAS_DECLTYPE
#    define IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE	1
#  else
#    define IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE	0
#  endif
#endif

#if !defined(IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE)
/**
 * @brief	式アサーションでビット演算子の展開をサポートするかどうか
*/
#  if IUTEST_HAS_DECLTYPE
#    define IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE		1
#  else
#    define IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE		0
#  endif
#endif

#if !defined(IUTEST_HAS_VALUESGEN)
//! ::iutest::ValuesGen が使用可能かどうか
#  if IUTEST_HAS_PARAM_TEST
#    define IUTEST_HAS_VALUESGEN	1
#  else
#    define IUTEST_HAS_VALUESGEN	0
#  endif
#endif

#if !defined(IUTEST_HAS_RANDOMVALUES)
//! ::iutest::RandomValues が使用可能かどうか
#  if IUTEST_HAS_PARAM_TEST && IUTEST_HAS_VALUESGEN
#    define IUTEST_HAS_RANDOMVALUES	1
#  else
#    define IUTEST_HAS_RANDOMVALUES	0
#  endif
#endif

#if IUTEST_HAS_RANDOMVALUES
#  if !IUTEST_HAS_PARAM_TEST || !IUTEST_HAS_VALUESGEN
#    undef IUTEST_HAS_RANDOMVALUES
#    define IUTEST_HAS_RANDOMVALUES	0
#  endif
#endif

#if !defined(IUTEST_HAS_COMBINE)
//! ::iutest::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

#if !defined(IUTEST_HAS_COMBINE)
#  define IUTEST_HAS_COMBINE		0
#endif

#if !defined(IUTEST_HAS_PAIRWISE)
//! ::iutest::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

#if !defined(IUTEST_HAS_PAIRWISE)
#  define IUTEST_HAS_PAIRWISE		0
#endif

#if !defined(IUTEST_HAS_CONCAT)
//! ::iutest::Concat が使用可能かどうか
# define IUTEST_HAS_CONCAT			1
#endif

#if !defined(IUTEST_HAS_VARIADIC_VALUES)
//! 可変長引数に対応した ::iutest::Values が使用可能かどうか
#  if IUTEST_HAS_PARAM_TEST && IUTEST_HAS_VARIADIC_TEMPLATES && IUTEST_HAS_TUPLE
#    define IUTEST_HAS_VARIADIC_VALUES	1
#  else
#    define IUTEST_HAS_VARIADIC_VALUES	0
#  endif
#endif

#if !defined(IUTEST_HAS_VARIADIC_COMBINE)
//! 可変長引数に対応した ::iutest::Combine が使用可能かどうか
#  if IUTEST_HAS_COMBINE && IUTEST_HAS_VARIADIC_TEMPLATES && IUTEST_HAS_TUPLE
#    define IUTEST_HAS_VARIADIC_COMBINE	1
#  else
#    define IUTEST_HAS_VARIADIC_COMBINE	0
#  endif
#endif

#if !defined(IUTEST_HAS_VARIADIC_PAIRWISE)
//! 可変長引数に対応した ::iutest::Pairwise が使用可能かどうか
#  if IUTEST_HAS_PAIRWISE && IUTEST_HAS_VARIADIC_TEMPLATES && IUTEST_HAS_TUPLE
#    define IUTEST_HAS_VARIADIC_PAIRWISE	1
#  else
#    define IUTEST_HAS_VARIADIC_PAIRWISE	0
#  endif
#endif

#if !defined(IUTEST_HAS_MATCHER_ELEMENTSARE)
//! ::iutest::ElementsAre matcher が使用可能かどうか
#  if IUTEST_HAS_TUPLE && IUTEST_HAS_MATCHERS && !defined(IUTEST_NO_SFINAE)
#    define IUTEST_HAS_MATCHER_ELEMENTSARE		1
#  else
#    define IUTEST_HAS_MATCHER_ELEMENTSARE		0
#  endif
#endif

#if !defined(IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD)
//! ::iutest::ElementsAreArrayHead matcher が使用可能かどうか
#  if IUTEST_HAS_TUPLE && IUTEST_HAS_MATCHERS && !defined(IUTEST_NO_SFINAE)
#    define IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD	1
#  else
#    define IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD	0
#  endif
#endif

#if !defined(IUTEST_HAS_REGEX)
//! regex が使用可能かどうか
#  if IUTEST_HAS_CXX_HDR_REGEX
#    define IUTEST_HAS_REGEX	1
#  else
#    define IUTEST_HAS_REGEX	0
#  endif
#endif

#if !defined(IUTEST_HAS_MATCHER_REGEX)
//! ::iutest::MatchesRegex, ::iutest::ContainsRegex matcher が使用可能かどうか
#  if IUTEST_HAS_CXX_HDR_REGEX && IUTEST_HAS_MATCHERS && IUTEST_HAS_REGEX
#    define IUTEST_HAS_MATCHER_REGEX	1
#  else
#    define IUTEST_HAS_MATCHER_REGEX	0
#  endif
#endif

#if !defined(IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF)
//! ::iutest::AllOf, ::iutest::AnyOf matcher が使用可能かどうか
#  if IUTEST_HAS_TUPLE && IUTEST_HAS_MATCHERS
#    define IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF	1
#  else
#    define IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF	0
#  endif
#endif

#if !defined(IUTEST_USE_THROW_ON_ASSERTION_FAILURE)
/**
 * @brief	失敗時に例外を throw します。
 * @note	サブ関数にアサーションを記述しても、その時点でテストが中断されるようになります
*/
#  if defined(IUTEST_USE_THROW_ON_ASSERT_FAILURE)
#    define IUTEST_USE_THROW_ON_ASSERTION_FAILURE		IUTEST_USE_THROW_ON_ASSERT_FAILURE
#  else
#    if !defined(IUTEST_NO_VOID_RETURNS)
#      define IUTEST_USE_THROW_ON_ASSERTION_FAILURE		0
#    else
#      define IUTEST_USE_THROW_ON_ASSERTION_FAILURE		1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_LAMBDA_STATEMENTS)
//! lambda を使った statements 展開が可能かどうか
#  if IUTEST_HAS_LAMBDA && !defined(IUTEST_NO_LAMBDA_SCOPE_RESOLUTION)
#    define IUTEST_HAS_LAMBDA_STATEMENTS		1
#  else
#    define IUTEST_HAS_LAMBDA_STATEMENTS		0
#  endif
#endif

#if !defined(IUTEST_HAS_SPI_LAMBDA_SUPPORT)
//! spi マクロで lambda を使って変数にアクセス可能かどうか
#  if IUTEST_HAS_LAMBDA_STATEMENTS
#    define IUTEST_HAS_SPI_LAMBDA_SUPPORT		1
#  else
#    define IUTEST_HAS_SPI_LAMBDA_SUPPORT		0
#  endif
#endif

#if !defined(IUTEST_HAS_GENRAND)
#  define IUTEST_HAS_GENRAND		1	//!< テストごとの genrand 関数が使用可能かどうか
#endif

#if !defined(IUTEST_HAS_PACKAGE)
//! パッケージ機能があるかどうか
#  if !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)
#    define IUTEST_HAS_PACKAGE		1
#  else
#    define IUTEST_HAS_PACKAGE		0
#  endif
#endif

// peep
#if !defined(IUTEST_HAS_PEEP)
//! private メンバーへのアクセスマクロが使用可能かどうか
#  define IUTEST_HAS_PEEP			1
#endif

#if !defined(IUTEST_HAS_PEEP_FUNC)
//! private メンバー関数へのアクセスが可能かどうか
#  if IUTEST_HAS_PEEP && IUTEST_EXPLICIT_INSTANTIATION_ACCESS_PRIVATE_MEMBER_FUNCTION
#    define IUTEST_HAS_PEEP_FUNC	1
#  else
#    define IUTEST_HAS_PEEP_FUNC	0
#  endif
#endif

#if !defined(IUTEST_HAS_PEEP_STATIC_FUNC)
//! private static メンバー関数へのアクセスが可能かどうか
#  if IUTEST_HAS_PEEP && IUTEST_EXPLICIT_INSTANTIATION_ACCESS_PRIVATE_STATIC_MEMBER_FUNCTION
#    define IUTEST_HAS_PEEP_STATIC_FUNC	1
#  else
#    define IUTEST_HAS_PEEP_STATIC_FUNC	0
#  endif
#endif

#if !defined(IUTEST_HAS_PEEP_CLASS)
//! private メンバー関数へのアクセスが可能かどうか
#  if IUTEST_HAS_PEEP && !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#    define IUTEST_HAS_PEEP_CLASS	1
#  else
#    define IUTEST_HAS_PEEP_CLASS	0
#  endif
#endif

#if !defined(IUTEST_HAS_STATIC_ASSERT_TYPEEQ)
//! StaticAssertTypeEq が使用可能かどうか
#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#    define IUTEST_HAS_STATIC_ASSERT_TYPEEQ		1
#  else
#    define IUTEST_HAS_STATIC_ASSERT_TYPEEQ		0
#  endif
#endif

#if !defined(IUTEST_HAS_PRINT_TO)
//! PrintTo が使用可能かどうか
#  if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING) && !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)
#    define IUTEST_HAS_PRINT_TO		1
#  else
#    define IUTEST_HAS_PRINT_TO		0
#  endif
#endif

#if !defined(IUTEST_HAS_VARIADIC_PRED)
//! 可変長述語アサーションが使用可能かどうか
#  if IUTEST_HAS_VARIADIC_TEMPLATES && !defined(IUTEST_NO_VARIADIC_MACROS)
#    define IUTEST_HAS_VARIADIC_PRED		1
#  else
#    define IUTEST_HAS_VARIADIC_PRED		0
#  endif
#endif

#if !defined(IUTEST_HAS_ASSERTION_RETURN)
//! ::iutest::AssertionReturn が使用可能かどうか
#  if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
#    define IUTEST_HAS_ASSERTION_RETURN		1
#  else
#    define IUTEST_HAS_ASSERTION_RETURN		0
#  endif
#endif

#if !defined(IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT)
//! IUTEST_*_EQ で operator == がないオブジェクトの検証が可能かどうか
#  if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING) && !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)
#    define IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT	1
#  else
#    define IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT	0
#  endif
#endif

#if !defined(IUTEST_HAS_TESTNAME_ALIAS)
//! テスト名の別名指定記法が使用できるかどうか
#  if !defined(IUTEST_NO_VARIADIC_MACROS)
#    define IUTEST_HAS_TESTNAME_ALIAS		1
#  else
#    define IUTEST_HAS_TESTNAME_ALIAS		0
#  endif
#endif

#if !defined(IUTEST_HAS_TESTNAME_ALIAS_JP)
//! テスト名の別名に日本語が使用できるかどうか
#  if IUTEST_HAS_TESTNAME_ALIAS && !defined(__CUDACC__) && !defined(IUTEST_OS_NACL)
#    define IUTEST_HAS_TESTNAME_ALIAS_JP	1
#  else
#    define IUTEST_HAS_TESTNAME_ALIAS_JP	0
#  endif
#endif

#if !defined(IUTEST_HAS_AUTOFIXTURE_PARAM_TEST)
//! fixture の自動定義に対応したパラメータ化テストが使用可能かどうか
#  if IUTEST_HAS_PARAM_TEST && (IUTEST_HAS_IF_EXISTS || !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION))
#    define IUTEST_HAS_AUTOFIXTURE_PARAM_TEST	1
#  else
#    define IUTEST_HAS_AUTOFIXTURE_PARAM_TEST	0
#  endif
#endif

#if !defined(IUTEST_HAS_ANY_PARAM_TEST)
//! any を利用した値のパラメータ化テストが使用可能かどうか
#  if IUTEST_HAS_PARAM_TEST && IUTEST_HAS_TESTNAME_ALIAS
#    define IUTEST_HAS_ANY_PARAM_TEST		1
#  else
#    define IUTEST_HAS_ANY_PARAM_TEST		0
#  endif
#endif

#if !defined(IUTEST_TYPED_TEST_APPEND_TYPENAME)
//! 型付けテスト名に型名を付けるかどうか
#  define IUTEST_TYPED_TEST_APPEND_TYPENAME	0
#endif

/**
 * @}
*/


/**
 * @defgroup	IUTEST_CONFIG_FILE	FILE
 * @brief		ファイル関係 CONFIG
 * @{
*/

#if !defined(IUTEST_HAS_FOPEN)
#  define IUTEST_HAS_FOPEN			1	//!< fopen が使用可能かどうか
#endif

#if !defined(IUTEST_HAS_FILE_STAT)
#  define IUTEST_HAS_FILE_STAT		0	//!< stat が使用可能かどうか
#endif

/**
 * @}
*/


/**
 * @defgroup	IUTEST_CONFIG_TIME	TIME
 * @brief		TIME関係 CONFIG
 * @{
*/

//! time 関数が使用可能かどうか
#if !defined(IUTEST_HAS_CTIME)
#  if defined(IUTEST_OS_WINDOWS_MOBILE)
#    define IUTEST_HAS_CTIME		0
#  else
#    define IUTEST_HAS_CTIME		1
#  endif
#endif

//! gettimeofday 関数が使用可能かどうか
#if !defined(IUTEST_HAS_GETTIMEOFDAY)
#  if IUTEST_HAS_HDR_SYSTIME
#    define IUTEST_HAS_GETTIMEOFDAY	1
#  endif
#endif

#if !defined(IUTEST_HAS_GETTIMEOFDAY)
#  define IUTEST_HAS_GETTIMEOFDAY	0
#endif

//! clock 関数が使用可能かどうか
#if !defined(IUTEST_HAS_CLOCK)
#  if defined(CLOCKS_PER_SEC)
#    define IUTEST_HAS_CLOCK		1
#  endif
#endif

#if !defined(IUTEST_HAS_CLOCK)
#  define IUTEST_HAS_CLOCK			0
#endif

/**
 * @}
*/


/**
 * @defgroup	IUTEST_CONFIG_OTHER	OTHER
 * @brief		その他の CONFIG
 * @{
*/

//! テストのチェック機能の有無
#if !defined(IUTEST_CHECK_STRICT)
#  define IUTEST_CHECK_STRICT		1
#endif

#if !defined(IUTEST_HAS_MINIDUMP)
//! MiniDump 出力が有効かどうか
#  if defined(_MSC_VER) && _MSC_VER >= 1310
#    if IUTEST_HAS_EXCEPTIONS && IUTEST_HAS_SEH && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
#      define IUTEST_HAS_MINIDUMP	1
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_MINIDUMP)
#  define IUTEST_HAS_MINIDUMP		0
#endif

#if !defined(IUTEST_HAS_SOCKET)
//! ソケット通信可能かどうか
#  if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_RT)
#    if !defined(_MSC_VER) || _MSC_VER >= 1310
#      define IUTEST_HAS_SOCKET	1
#    endif
#  elif defined(IUTEST_OS_CYGWIN) || defined(IUTEST_OS_LINUX)
#    define IUTEST_HAS_SOCKET	1
#  else
#    define IUTEST_HAS_SOCKET	0
#  endif
#endif

#if !defined(IUTEST_HAS_STRINGSTREAM)
//! std::stringstream が使用可能かどうか
#  if !defined(_STLP_NO_IOSTREAMS)
#    define IUTEST_HAS_STRINGSTREAM	1	
#  else
#    define IUTEST_HAS_STRINGSTREAM	0
#  endif
#endif

/**
 * @brief	std::strstream が使用可能かどうか
 * @note	IUTEST_HAS_STRINGSTREAM が優先されます
*/
#if !defined(IUTEST_HAS_STRSTREAM)
#  define IUTEST_HAS_STRSTREAM		0
#endif

/**
 * @brief	stdout/stderr の StreamCapture が使用可能かどうか
*/
#if !defined(IUTEST_HAS_STREAMCAPTURE)
#  define IUTEST_HAS_STREAMCAPTURE	1
#endif


/**
 * @}
*/

/**
 * @defgroup	IUTEST_CONFIG_LISTENER	LISTENER
 * @brief		Listener 関係の CONFIG
 * @{
*/

#if !defined(IUTEST_HAS_STREAM_RESULT)
//! stream result が使用可能かどうか
#  if IUTEST_HAS_SOCKET
#    define IUTEST_HAS_STREAM_RESULT	1
#  else
#    define IUTEST_HAS_STREAM_RESULT	0
#  endif
#endif

/**
 * @}
*/

// Doxygen 用
#ifdef IUTEST_BUILD_DOXYGEN

/**
 * @ingroup	IUTEST_CONFIG_TIME	TIME
 * @{
*/

#define IUTEST_GetMillisec()	//!< 現在時刻のミリ秒取得関数を独自定義

/**
 * @}
*/


/**
 * @ingroup	IUTEST_CONFIG_OTHER	OTHER
 * @{
*/

/**
 * @brief	iutest で t1/tuple.h をインクルードするかどうか
 * @details	1: std::tr1 名前空間にある tuple を使用します。
 *			tuple.h はユーザーがインクルードします。
 *			0: 指定なし iutest が自動で判断します。
*/
#define IUTEST_USE_EXTERNAL_TR1_TUPLE	0

/**
 * @brief	iutest で tuple.h をインクルードするかどうか
 * @details	1: std 名前空間にある tuple を使用します。
 *			tuple.h はユーザーがインクルードします。
 *			0: 指定なし iutest が自動で判断します。
*/
#define IUTEST_USE_EXTERNAL_STD_TUPLE	0

/**
 * @brief	iutest で使用する乱数エンジンを指定します
 * @details	未定義の場合は iutest が実装しているエンジンを使用します(XorShift 128)
*/
#define IUTEST_USE_RANDOM_ENGINE_TYPENAME	::std::default_random_engine

#define IUTEST_NO_GETENV	//!< getenv 関数がない場合は定義
#define IUTEST_NO_PUTENV	//!< putenv 関数がない場合は定義
#define IUTEST_NO_GETCWD	//!< getcwd 関数がない場合は定義

/**
 * @}
*/

#define IUTEST_USE_LIB		//!< ライブラリ版を使用する
#define IUTEST_AUTO_LINK	//!< ライブラリ版を使用し、自動リンクする
#define IUTEST_USE_MAIN		//!< main 関数定義を iutest に任せる

#endif

/**
 * @}
*/

/**
 * @private
 * @{
*/

// include only
#if IUTEST_HAS_LIB
#  define IUTEST_IPP_INLINE
#else
#  define IUTEST_IPP_INLINE		inline
#endif

// auto link
#if IUTEST_HAS_LIB && defined(IUTEST_AUTO_LINK)

#if defined(_MSC_VER)

#if defined(_MT) || defined(__MT__)
#  if defined(_DLL)
#    define IUTEST_LIB_THREAD_OPT	"md"
#  else
#    define IUTEST_LIB_THREAD_OPT	"mt"
#  endif
#else
#  define IUTEST_LIB_THREAD_OPT	""
#endif

#if   _MSC_VER == 1400
#  define IUTEST_LIB_TOOLSET	"vc80"
#elif _MSC_VER == 1500
#  define IUTEST_LIB_TOOLSET	"vc90"
#elif _MSC_VER == 1600
#  define IUTEST_LIB_TOOLSET	"vc100"
#elif _MSC_VER == 1700
#  define IUTEST_LIB_TOOLSET	"vc110"
#elif _MSC_VER == 1800
#  define IUTEST_LIB_TOOLSET	"vc120"
#elif _MSC_VER == 1900
#  define IUTEST_LIB_TOOLSET	"vc140"
#else
#  error unknown _MSC_VER.
#endif

#if defined(_DEBUG)
#  define IUTEST_LIB_RT_OPT		"d"
#else
#  define IUTEST_LIB_RT_OPT		""
#endif

#define IUTEST_LIB_NAME(name)	#name "-" IUTEST_LIB_TOOLSET "-" IUTEST_LIB_THREAD_OPT IUTEST_LIB_RT_OPT ".lib"

#pragma comment(lib, IUTEST_LIB_NAME(libiutest) )

#endif

#endif

/**
 * @}
*/

#endif // INCG_IRIS_IUTEST_CONFIG_HPP_F0151607_0D9D_4055_B94D_ED4A0FFA748B_
#include <stdio.h>
#include <vector>
#include <algorithm>
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_debug.hpp
 * @brief		iris unit test debug 用定義 ファイル
 *
 * @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_DEBUG_HPP_A63366D4_2112_4269_9BAF_BD30A5F2C7F2_
#define INCG_IRIS_IUTEST_DEBUG_HPP_A63366D4_2112_4269_9BAF_BD30A5F2C7F2_

//======================================================================
// include

#ifdef _IUTEST_DEBUG
// iutest 自体のデバッグ用定義

#if defined(_MSC_VER) && !defined(IUTEST_OS_WINDOWS_MOBILE)
#  include <streambuf>
#  include <xlocnum>
#  include <xtree>
#  include <crtdbg.h>
#  ifndef _DEBUG_NEW_
#    define _DEBUG_NEW_		new ( _NORMAL_BLOCK , __FILE__, __LINE__)
#    pragma push_macro("new")
#    define new _DEBUG_NEW_
#  endif
#endif

#endif

namespace iutest {
namespace detail
{

//======================================================================
// function
static void IUTEST_ATTRIBUTE_UNUSED_ iuDebugInitialize(void)
{
#ifdef _IUTEST_DEBUG
#  if defined(_MSC_VER) && !defined(IUTEST_OS_WINDOWS_MOBILE)
	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#  endif
#endif
}

static void IUTEST_ATTRIBUTE_UNUSED_ iuDebugBreakAlloc(long n)
{
#ifdef _IUTEST_DEBUG
#  if defined(_MSC_VER) && !defined(IUTEST_OS_WINDOWS_MOBILE)
	_CrtSetBreakAlloc(n);
#  endif
#endif
	(void)n;
}

#if defined(_MSC_VER) && IUTEST_HAS_MINIDUMP

/**
 * @brief	minidump 作成クラス
*/
class MiniDump
{
private:
	MiniDump(void);
	~MiniDump(void);

	bool Dump(HANDLE hFile, EXCEPTION_POINTERS* ep);
public:
	/**
	 @brief	minidump 作成
	*/
	static bool Create(const char* filepath, EXCEPTION_POINTERS* ep);

private:
	HMODULE m_hModule;
	FARPROC m_pfnMiniDumpWriteDump;
};

#endif

}	// end of namespace detail
}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_debug.ipp
 * @brief		iris unit test debug help ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2013-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_DEBUG_IPP_1575CB44_189A_4248_B305_DB4882E3BFC2_
#define INCG_IRIS_IUTEST_DEBUG_IPP_1575CB44_189A_4248_B305_DB4882E3BFC2_

//======================================================================
// include

#if defined(_MSC_VER) && _MSC_VER >= 1310
#  if !defined(IUTEST_OS_WINDOWS_MOBILE) && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
#    if _MSC_VER >= 1900
IUTEST_PRAGMA_MSC_WARN_PUSH()
IUTEST_PRAGMA_MSC_WARN_DISABLE(4091)
#      include <DbgHelp.h>
IUTEST_PRAGMA_MSC_WARN_POP()
#    else
#      include <DbgHelp.h>
#    endif
//#  pragma comment (lib, "dbghelp.lib")
#  endif
#endif

namespace iutest {
namespace detail
{

#if defined(_MSC_VER) && IUTEST_HAS_MINIDUMP

IUTEST_IPP_INLINE MiniDump::MiniDump(void)
	: m_hModule(NULL), m_pfnMiniDumpWriteDump(NULL)
{
	m_hModule = ::LoadLibraryA("dbghelp.dll");
	if( m_hModule != NULL )
	{
		m_pfnMiniDumpWriteDump = ::GetProcAddress(m_hModule, "MiniDumpWriteDump");
	}
}

IUTEST_IPP_INLINE MiniDump::~MiniDump(void)
{
	FreeLibrary(m_hModule);
}

IUTEST_IPP_INLINE bool MiniDump::Dump(HANDLE hFile, EXCEPTION_POINTERS* ep)
{
	if( m_pfnMiniDumpWriteDump == NULL ) return false;
	MINIDUMP_EXCEPTION_INFORMATION mdei;
	mdei.ThreadId = ::GetCurrentThreadId();
	mdei.ExceptionPointers = ep;
	mdei.ClientPointers = FALSE;

	typedef BOOL (WINAPI *pfnMiniDumpWriteDump)(HANDLE hProcess, DWORD dwProcessId, HANDLE hFile
		, MINIDUMP_TYPE DumpType
		, PMINIDUMP_EXCEPTION_INFORMATION
		, PMINIDUMP_USER_STREAM_INFORMATION
		, PMINIDUMP_CALLBACK_INFORMATION
		);
	pfnMiniDumpWriteDump proc = reinterpret_cast<pfnMiniDumpWriteDump>(m_pfnMiniDumpWriteDump);
	return (*proc)( ::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpNormal
		, &mdei, NULL, NULL) ? true : false;
}
IUTEST_IPP_INLINE bool MiniDump::Create(const char* filepath, EXCEPTION_POINTERS* ep)
{
	HANDLE hFile = CreateFileA( filepath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ
		, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if( hFile == NULL || hFile == INVALID_HANDLE_VALUE ) return false;

	static MiniDump dump;
	const bool ret = dump.Dump(hFile, ep);

	CloseHandle(hFile);
	return ret;
}

#endif

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_DEBUG_IPP_1575CB44_189A_4248_B305_DB4882E3BFC2_
#endif

#endif // INCG_IRIS_IUTEST_DEBUG_HPP_A63366D4_2112_4269_9BAF_BD30A5F2C7F2_

#if IUTEST_HAS_TYPED_TEST_P
#  if IUTEST_TYPED_TEST_P_STRICT
#    include <set>
#  endif
#endif

namespace iutest
{

//======================================================================
// struct
namespace detail
{

/**
 * @brief	type_least_t
*/
template<int SIZE>
struct type_least_t {};


template<>
struct type_least_t<1>
{
	typedef char				Int;
	typedef unsigned char		UInt;
};


template<>
struct type_least_t<2>
{
	typedef short				Int;
	typedef unsigned short		UInt;
};


template<>
struct type_least_t<4>
{
	typedef int					Int;
	typedef unsigned int		UInt;
};


template<>
struct type_least_t<8>
{
#if defined(_MSC_VER)
	typedef __int64				Int;
	typedef unsigned __int64	UInt;
#else
	typedef long long			Int;
	typedef unsigned long long	UInt;
#endif
};

}

namespace internal
{

typedef void* TypeId;		//!< テスト識別型

namespace helper
{

//======================================================================
// struct
/**
 * @brief	TypeId Generator Implementation
*/
template<typename T>
struct TestTypeIdHelper { public: static bool _dummy; };

template<typename T>bool TestTypeIdHelper<T>::_dummy = false;

}

//======================================================================
// function
/**
 * @internal
 * @brief	TypeId Generator
*/
template<typename T>
inline TypeId GetTypeId(void)
{
	return &(helper::TestTypeIdHelper<T>::_dummy);
}

/**
 * @internal
 * @brief	TypeId Generator
*/
inline IUTEST_CXX_CONSTEXPR TypeId GetTestTypeId(void)
{
	return 0;
}

} // end of namespace internal

//======================================================================
// class
namespace detail
{

/**
 * @internal
 * @brief	IEEE754 floating point bits
*/
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
	};
};

}

/**
 * @brief	浮動小数点数
*/
template<typename RawType>
class floating_point
{
private:
	typedef floating_point<RawType> _Myt;

	typedef typename detail::type_least_t<sizeof(RawType)> type;
	typedef typename type::Int	Int;
	typedef typename type::UInt	UInt;
	union FInt
	{
		Int		iv;
		UInt	uv;
		RawType	fv;
	};

public:
	/**
	 * @brief	コンストラクタ
	*/
	floating_point(void)
	{
		m_v.uv = 0;
	}

	/**
	 * @brief	コンストラクタ
	 * @param [in]	f	= 浮動小数点数
	*/
	floating_point(RawType f)
	{
		m_v.fv = f;
	}

	/**
	 * @brief	コンストラクタ
	*/
	floating_point(const _Myt& rhs)
		: m_v(rhs.m_v)
	{
	}

public:
	/**
	 * @brief	浮動小数点数がほぼ一致するかどうか
	*/
	bool	AlmostEquals(const _Myt& rhs) const
	{
		if( is_nan() || rhs.is_nan() ) return false;
		return NanSensitiveAlmostEquals(rhs);
	}

	/**
	 * @brief	浮動小数点数がほぼ一致するかどうか
	 * @sa		http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
	*/
	bool	NanSensitiveAlmostEquals(const _Myt& rhs) const
	{
		const UInt v1 = norm(m_v.uv);
		const UInt v2 = norm(rhs.m_v.uv);
		const UInt diff = (v1 > v2) ? v1 - v2 : v2 - v1;
		if( diff <= kMaxUlps )
		{
			return true;
		}
		return false;
	}

public:
	/**
	 * @brief	ビット列の取得
	*/
	UInt	bits(void) const { return m_v.uv; }

	/**
	 * @brief	raw データの取得
	*/
	RawType	raw(void) const { return m_v.fv; }

	/**
	 * @brief	exponent
	*/
	UInt	exponent_bits(void) const { return m_v.uv & kExpMask; }

	/**
	 * @brief	fraction
	*/
	UInt	fraction_bits(void) const { return m_v.uv & kFracMask; }

	/**
	 * @brief	sign
	*/
	UInt	sign_bit(void) const { return m_v.uv & kSignMask; }

	/**
	 * @brief	is nan
	*/
	bool	is_nan(void) const { return exponent_bits() == kExpMask && fraction_bits() != 0; }

public:
	//! plus inf
	static _Myt PINF(void)
	{
		_Myt f;
		f.m_v.uv = kExpMask;
		return f;
	}
	//! minus inf
	static _Myt NINF(void)
	{
		_Myt f = PINF();
		f.m_v.uv |= kSignMask;
		return f;
	}
	//! plus nan
	static _Myt PNAN(void)
	{
		_Myt f;
		f.m_v.uv = kExpMask | 1;
		return f;
	}
	//! minus nan
	static _Myt NNAN(void)
	{
		_Myt f = PNAN();
		f.m_v.uv |= kSignMask;
		return f;
	}
	//! plus qnan
	static _Myt PQNAN(void)
	{
		_Myt f;
		f.m_v.uv = ((1 << (kEXP + 1)) - 1);
		f.m_v.uv <<= kFRAC - 1;
		return f;
	}
	//! minus qnan
	static _Myt NQNAN(void)
	{
		_Myt f = PQNAN();
		f.m_v.uv |= kSignMask;
		return f;
	}

public:
#if !defined(_MSC_VER) || _MSC_VER >= 1310
	operator RawType (void) const	{ return m_v.fv; }	//!< cast to RawType
#else
	operator float  (void) const	{ return m_v.fv; }
	operator double (void) const	{ return m_v.fv; }
#endif
	_Myt&	operator = (RawType f)	{ m_v.fv = f; 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; }

#if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
	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;
#else
	static const UInt kSignMask;
	static const UInt kExpMask;
	static const UInt kFracMask;
#endif

private:
	FInt m_v;
};

#if defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)

template<typename T>
const typename floating_point<T>::UInt floating_point<T>::kSignMask
	= static_cast<typename floating_point<T>::UInt>(1u) << (kEXP + kFRAC);
template<typename T>
const typename floating_point<T>::UInt floating_point<T>::kExpMask
	= ((static_cast<typename floating_point<T>::UInt>(1u) << floating_point<T>::kEXP) - 1) << floating_point<T>::kFRAC;
template<typename T>
const typename floating_point<T>::UInt floating_point<T>::kFracMask
	= ((static_cast<typename floating_point<T>::UInt>(1u) << floating_point<T>::kFRAC) - 1);

#endif

//======================================================================
// typedef
typedef detail::type_least_t<4>::Int	Int32;	//!< 32 bit 符号付き整数型
typedef detail::type_least_t<4>::UInt	UInt32;	//!< 32 bit 符号なし整数型
typedef detail::type_least_t<8>::Int	Int64;	//!< 64 bit 符号付き整数型
typedef detail::type_least_t<8>::UInt	UInt64;	//!< 64 bit 符号なし整数型

typedef internal::TypeId TestTypeId;	//!< テスト識別型

typedef void (*SetUpMethod)(void);		//!< SetUp 関数型
typedef void (*TearDownMethod)(void);	//!< TearDown 関数型

typedef detail::type_least_t<8>::UInt	TimeInMillisec;	//!< ミリ秒単位を扱う型
typedef detail::type_least_t<8>::Int	BiggestInt;		//!< Biggest Int

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_DEFS_HPP_839F06DB_E0B6_4E6A_84F2_D99C0A44E06C_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_string.hpp
 * @brief		iris unit test 文字列操作 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_STRING_HPP_E22B02D7_E9E7_412C_B609_DC3D9C66895D_
#define INCG_IRIS_IUTEST_STRING_HPP_E22B02D7_E9E7_412C_B609_DC3D9C66895D_

//======================================================================
// include
#if defined(__MWERKS__)
#  define _MBSTATE_T
#endif

#include <string>
#include <wchar.h>
#include <wctype.h>
#include <stdarg.h>
#include <string.h>
#if defined(IUTEST_OS_CYGWIN)
#include <strings.h>
#endif
#if   IUTEST_HAS_STRINGSTREAM
#  include <sstream>
#elif IUTEST_HAS_STRSTREAM
#  include <strstream>
#endif

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

namespace iutest {
namespace detail
{

/**
 * @internal
 * @brief	stricmp
*/
inline int iu_stricmp(const char* str1, const char* str2)
{
#if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_WINE)

#if defined(__BORLANDC__)
	return stricmp(str1, str2);
#else
	return _stricmp(str1, str2);
#endif

#elif !defined(__MWERKS__)
	return strcasecmp(str1, str2);

#else
	const char* l = str1;
	const char* r = str2;
	while(*l)
	{
		int ul = toupper(*l);
		int ur = toupper(*r);
		if( ul < ur ) return -1;
		if( ul > ur ) return 1;
		++l;
		++r;
	}
	if( *l < *r ) return -1;
	if( *l > *r ) return 1;
	return 0;
#endif
}

/**
 * @internal
 * @brief	wcsicmp
*/
inline int iu_wcsicmp(const wchar_t * str1, const wchar_t * str2)
{
#if   defined(_MSC_VER)
	return _wcsicmp(str1, str2);
#elif defined(IUTEST_OS_LINUX) && !defined(IUTEST_OS_LINUX_ANDROID)
	return wcscasecmp(str1, str2);
#else
	const wchar_t* l = str1;
	const wchar_t* r = str2;
	while(*l)
	{
		wchar_t ul = towupper(*l);
		wchar_t ur = towupper(*r);
		if( ul < ur ) return -1;
		if( ul > ur ) return 1;
		++l;
		++r;
	}
	if( *l < *r ) return -1;
	if( *l > *r ) return 1;
	return 0;
#endif
}

inline bool IsEmpty(const char* p) { return p == NULL || *p == '\0'; }
inline IUTEST_CXX_CONSTEXPR bool IsSpace(char ch) { return ch == ' ' || ch =='\t'; }
inline IUTEST_CXX_CONSTEXPR const char* SkipSpace(const char* p)
{
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
	return p == NULL ? NULL : (IsSpace(*p) ? SkipSpace(++p) : p);
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
}
inline IUTEST_CXX_CONSTEXPR const char* FindComma(const char* p)
{
	return (p == NULL || *p == '\0') ? NULL : ((*p == ',') ? p : FindComma(++p));
}
inline bool IsStringEqual(const char* str1, const char* str2) { return strcmp(str1, str2) == 0; }
inline bool IsStringCaseEqual(const char* str1, const char* str2) { return iu_stricmp(str1, str2) == 0; }
inline bool IsStringForwardMatching(const char* str1, const char* str2) { return strstr(str1, str2) == str1; }

inline void StringReplace(::std::string& str, char a, const char* to)
{
	::std::string::size_type pos = 0;
	while( pos = str.find(a, pos), pos != ::std::string::npos )
	{
		str.replace(pos, 1, to);
		++pos;
	}
}
inline void StripTrailingSpace(::std::string& str)
{
	::std::string::iterator it = str.end();
	while(it != str.begin() && IsSpace(*--it))
	{
		it = str.erase(it);
	}
}
inline void StringReplaceToLF(::std::string& str)
{
	::std::string::size_type pos = 0;
	while( pos = str.find("\r\n", pos), pos != ::std::string::npos )
	{
		str.replace(pos, 2, "\n");
		++pos;
	}
	StringReplace(str, '\r', "\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(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);
}

inline IUTEST_CXX_CONSTEXPR char ToHex(unsigned int n) { return (n&0xF) >= 0xA ? 'A'+((n&0xF)-0xA) : '0'+(n&0xF); }

template<typename T>
inline ::std::string ToHexString(T value)
{
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
	const size_t len = sizeof(T)*2;
	char buf[len+1];
	for( size_t i=0; i < len; ++i )
	{
		buf[i] = ToHex(static_cast<unsigned int>((value>>((len-i-1)*4))));
	}
	buf[len] = '\0';
	return buf;
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
}

inline ::std::string FormatIntWidth2(int value)
{
	char buf[3] = "00";
	buf[0] = (value/10)%10 + '0';
	buf[1] = (value   )%10 + '0';
	return buf;
}

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; }

//======================================================================
// declare
#if !IUTEST_HAS_STRINGSTREAM && !IUTEST_HAS_STRSTREAM
template<class _Elem, class _Traits>class iu_basic_stream;
#endif

#if   IUTEST_HAS_STRINGSTREAM

typedef ::std::stringstream stlstream;

#elif IUTEST_HAS_STRSTREAM

IUTEST_PRAGMA_MSC_WARN_PUSH()
IUTEST_PRAGMA_MSC_WARN_DISABLE(4250)
class stlstream : public ::std::strstream
{
	char buf[512];
public:
	stlstream(void)
		: ::std::strstream(buf, sizeof(buf)-2, ::std::ios::out)
	{}
	stlstream(const char* str)
		: ::std::strstream(buf, sizeof(buf)-2, ::std::ios::out)
	{
		*this << str;
	}
	stlstream(const ::std::string& str)
		: ::std::strstream(buf, sizeof(buf)-2, ::std::ios::out)
	{
		*this << str;
	}
public:
	::std::string str(void) const
	{
		return const_cast<stlstream*>(this)->str();
	}
	virtual ::std::string str(void)
	{
		*this << ::std::ends;
		::std::string str = ::std::strstream::str();
		return str;
	}
};

IUTEST_PRAGMA_MSC_WARN_POP()

#else
	typedef iu_basic_stream<char, ::std::char_traits<char> >		iu_stream;
	typedef iu_basic_stream<wchar_t, ::std::char_traits<wchar_t> >	iu_wstream;
#endif

//======================================================================
// class

#if !IUTEST_HAS_STRINGSTREAM && !IUTEST_HAS_STRSTREAM

template<class _Elem, class _Traits>
class iu_basic_stream
{
	typedef iu_basic_stream<_Elem, _Traits>			_Myt;
	//typedef ::std::basic_streambuf<_Elem, _Traits>	streambuf;
	//typedef ::std::basic_ostream<_Elem, _Traits>	ostream;
	typedef ::std::basic_string<_Elem, _Traits>		string;
	string s;

	template<typename T>
	struct xcs
	{
	private:
		template<typename TMP, typename TN>
		struct impl_select
		{
			template<typename TA, typename TB>
			static const TA constant(const TA a, const TB b)
			{
				(void)b;
				return a;
			}
		};
		template<typename TMP>
		struct impl_select<TMP, wchar_t>
		{
			template<typename TA, typename TB>
			static const TB constant(const TA a, const TB b)
			{
				(void)a;
				return b;
			}
		};

	public:
		typedef impl_select<void, T> select;
	};
#define IUTEST_PP_XCS(txt_)	xcs<_Elem>::select::constant(txt_, L##txt_)

	struct impl
	{
		template<typename E>
		static int vastring(E* dst, const E* fmt, va_list va);
		static int vastring(char* dst, size_t len, const char* fmt, va_list va)
		{
			(void)len;
			return vsprintf(dst, fmt, va);
		}
		static int vastring(wchar_t* dst, size_t len, const wchar_t* fmt, va_list va)
		{
#ifdef IUTEST_OS_WINDOWS_MINGW
			return _vsnwprintf(dst, len, fmt, va);
#else
			return vswprintf(dst, len, fmt, va);
#endif
		}

		template<typename E>
		static int tostring(E* dst, size_t len, const E* fmt, ...)
		{
			va_list va;
			va_start(va, fmt);
			int ret = vastring(dst, len, fmt, va);
			va_end(va);
			return ret;
		}
	};
public:
	iu_basic_stream(void) {}
	explicit iu_basic_stream(const char* str) : s(str) {}
	explicit iu_basic_stream(const ::std::string& str) : s(str) {}
public:

	inline _Myt& operator<< (char v)
	{
		s += v;
		return *this;
	}
	inline _Myt& operator<< (signed char v)
	{
		s += (char)v;
		return *this;
	}
	inline _Myt& operator<< (unsigned char v)
	{
		s += (char)v;
		return *this;
	}
	inline _Myt& operator<< (const _Elem* v)
	{
		s += v;
		return *this;
	}
	//inline _Myt& operator<< (const signed _Elem* v)
	//{
	//	s += v;
	//	return *this;
	//}
	//inline _Myt& operator<< (const unsigned _Elem* v)
	//{
	//	s += v;
	//	return *this;
	//}
	inline _Myt& operator<< (bool v)
	{
#if 0
		_Elem a[16];
		impl::tostring(a, 16, IUTEST_PP_XCS("%i"), v);
		s += a;
#else
		s += (v ? IUTEST_PP_XCS("true") : IUTEST_PP_XCS("false"));
#endif
		return *this;
	}
	inline _Myt& operator<< (short v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%i"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (unsigned short v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%u"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (int v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%i"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (unsigned int v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%u"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (long v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%i"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (unsigned long v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%u"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (long long int v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%lld"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (unsigned long long int v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%llu"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (float v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%f"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (double v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%l"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (long double v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%L"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (const void* v)
	{
		_Elem a[64];
		impl::tostring(a, 64, IUTEST_PP_XCS("%t"), v);
		s += a;
		return *this;
	}
	inline _Myt& operator<< (const ::std::string& v)
	{
		s += v;
		return *this;
	}
public:
	const string& str(void) const { return s; }
	void copyfmt(const _Myt&) {}
};

#undef IUTEST_PP_XCS

#endif

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

}	// end of namespace detail

#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM

typedef ::std::ostream iu_ostream;
typedef ::std::ostream& (*iu_basic_iomanip)(::std::ostream&);
typedef detail::stlstream iu_stringstream;

#else

typedef detail::iu_stream iu_ostream;
typedef detail::iu_stream iu_stringstream;

#endif

#if !defined(IUTEST_HAS_BIGGESTINT_OSTREAM)
#  if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
#    if (defined(_STLPORT_VERSION) && !defined(_STLP_LONG_LONG)) || (defined(_MSC_VER) && _MSC_VER < 1310)
#      define IUTEST_HAS_BIGGESTINT_OSTREAM		0
#    endif
#  endif
#endif

#if !defined(IUTEST_HAS_BIGGESTINT_OSTREAM)
#  define IUTEST_HAS_BIGGESTINT_OSTREAM			1
#endif

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_STRING_HPP_E22B02D7_E9E7_412C_B609_DC3D9C66895D_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_type_traits.hpp
 * @brief		iris unit test type traits
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_TYPE_TRAITS_HPP_6F091F15_784A_4F50_BD18_B8F67C5AF0CF_
#define INCG_IRIS_IUTEST_TYPE_TRAITS_HPP_6F091F15_784A_4F50_BD18_B8F67C5AF0CF_

//======================================================================
// include

//======================================================================
// define
#ifndef IUTEST_HAS_HDR_TYPETARITS
#  if defined(__clang__)
#    if __has_include( <type_traits> ) && IUTEST_HAS_CXX11
#      define IUTEST_HAS_HDR_TYPETARITS		1
#    endif
#  elif (defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)) && IUTEST_HAS_CXX11
#    define IUTEST_HAS_HDR_TYPETARITS		1
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1600
#      define IUTEST_HAS_HDR_TYPETARITS		1
#    endif
#  endif
#endif

#ifndef IUTEST_HAS_HDR_TYPETARITS
#  define IUTEST_HAS_HDR_TYPETARITS			0
#endif

#ifndef IUTEST_HAS_RVALUE_REFS
#  if   (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#    define IUTEST_HAS_RVALUE_REFS	1
#  elif defined(_MSC_VER) && (_MSC_VER >= 1700)
#    define IUTEST_HAS_RVALUE_REFS	1
#  endif
#endif

#ifndef IUTEST_HAS_RVALUE_REFS
#  define IUTEST_HAS_RVALUE_REFS	0
#endif

#if IUTEST_HAS_HDR_TYPETARITS
#  include <type_traits>
#endif


namespace iutest_type_traits
{

/**
 * @brief	identity
*/
template<typename T>struct identity { typedef T type; };

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

/**
* @brief	add const to pointer
*/
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;
};

#endif


#if IUTEST_HAS_HDR_TYPETARITS

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_pointer;
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::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;
using ::std::is_member_function_pointer;
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 > {};

template<bool B>
struct bool_constant : ::std::integral_constant<bool, B> {};

#else

//======================================================================
// struct

/**
 * @brief	bool constant
*/
template<bool B>
struct bool_constant
{
#if defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
	enum { value = B };
#else
	static const bool value = B;
#endif
};
#if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
template<bool B>const bool bool_constant<B>::value;
#endif

typedef bool_constant<true>  true_type;
typedef bool_constant<false> false_type;

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

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

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

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

/**
 * @brief	remove_cv
*/
template<typename T>
struct remove_cv
{
	typedef typename remove_const< typename remove_volatile<T>::type >::type type;
};

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

#endif

namespace is_pointer_helper
{


template<typename T>
class is_pointer
{
#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
	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;
#else
	typedef T rmcv_type;
	static T& make_t();
	static char IsPointerHelper(const volatile void*);
	static char (&IsPointerHelper(...))[2];

	enum { IsPointer = sizeof(IsPointerHelper(make_t())) == 1 ? true : false };
public:
	typedef bool_constant<IsPointer> type;
#endif
};

}

/**
 * @brief	is_pointer
*/
#if !defined(_MSC_VER) || _MSC_VER >= 1310
template<typename T>
struct is_pointer : public is_pointer_helper::is_pointer<T>::type {};
#else
template<typename T>
struct is_pointer_impl : public is_pointer_helper::is_pointer<T> {};

template<typename T>
struct is_pointer : public is_pointer_impl<T>::type {};
#endif

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

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;
};

}

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

}

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

}

/**
 * @brief	is_const
*/
template<typename T>
struct is_const : public is_const_helper::is_const<T>::type {};

#endif // #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

namespace is_same_helper
{

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)


template<typename T1, typename T2>
struct is_same { typedef false_type type; };

template<typename T>
struct is_same<T, T> { typedef true_type type; };

#elif IUTEST_HAS_CLASS_MEMBER_TEMPLATE_SPECIALIZATION


template<typename T1, typename T2>
class is_same
{
	template<typename T>
	struct impl { typedef false_type type; };
	template<>
	struct impl<T1> { typedef true_type type; };
public:
	typedef typename impl<T2>::type type;
};

#endif

}

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || IUTEST_HAS_CLASS_MEMBER_TEMPLATE_SPECIALIZATION

/**
 * @brief	is_same
*/
template<typename T1, typename T2>
struct is_same : public is_same_helper::is_same<T1, T2>::type {};

#endif

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;
};

}

/**
 * @brief	is class
*/
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(void);

	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;
};

}

/**
 * @brief	is convertible
*/
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
{
#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
	typedef typename remove_cv<Base>::type B;
	typedef typename remove_cv<Derived>::type D;
#else
	typedef Base B;
	typedef Derived D;
#endif
	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;
};

}

/**
 * @brief	is base of
*/
template<typename Base, typename Derived>
struct is_base_of : public is_base_of_helper::is_base_of<Base, Derived>::type
{
};


#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

/**
 * @brief	add lvalue reference
*/
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;
};

/**
 * @brief	add rvalue reference
*/
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;
};

#else

template<typename T>
struct add_rvalue_reference { typedef T type; };

#endif

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

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 IIUT_DECL_IS_FUNCTION_PTR_(n)	\
template<typename R, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (*)(IUTEST_PP_ENUM_PARAMS(n, T))> : public true_type {};	\
template<typename R, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (*)(IUTEST_PP_ENUM_PARAMS(n, T), ...)> : public true_type {}

	IIUT_DECL_IS_FUNCTION_PTR_(1);
	IIUT_DECL_IS_FUNCTION_PTR_(2);
	IIUT_DECL_IS_FUNCTION_PTR_(3);
	IIUT_DECL_IS_FUNCTION_PTR_(4);
	IIUT_DECL_IS_FUNCTION_PTR_(5);
	IIUT_DECL_IS_FUNCTION_PTR_(6);
	IIUT_DECL_IS_FUNCTION_PTR_(7);
	IIUT_DECL_IS_FUNCTION_PTR_(8);
	IIUT_DECL_IS_FUNCTION_PTR_(9);
	IIUT_DECL_IS_FUNCTION_PTR_(10);
	IIUT_DECL_IS_FUNCTION_PTR_(11);
	IIUT_DECL_IS_FUNCTION_PTR_(12);
	IIUT_DECL_IS_FUNCTION_PTR_(13);
	IIUT_DECL_IS_FUNCTION_PTR_(14);
	IIUT_DECL_IS_FUNCTION_PTR_(15);
	IIUT_DECL_IS_FUNCTION_PTR_(16);
	IIUT_DECL_IS_FUNCTION_PTR_(17);
	IIUT_DECL_IS_FUNCTION_PTR_(18);
	IIUT_DECL_IS_FUNCTION_PTR_(19);
	IIUT_DECL_IS_FUNCTION_PTR_(20);

#undef IIUT_DECL_IS_FUNCTION_PTR_

#endif

	enum { value = impl< typename remove_cv<T>::type >::value };
public:
	typedef bool_constant<value> type;
};

}

/**
 * @brief	is function pointer
*/
template<typename T>
struct is_function_pointer : public is_function_pointer_helper::is_function_pointer<T>::type
{
};

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 IIUT_DECL_IS_MEMBER_FUNCTION_PTR_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 {}

	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_(IUTEST_PP_EMPTY());
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_(const);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_(volatile);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_(const volatile);

#undef IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_

#else

#define IIUT_DECL_IS_MEMBER_FUNCTION_PTR_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 {};
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_VOID_CV_(const);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_VOID_CV_(volatile);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_VOID_CV_(const volatile);

#undef IIUT_DECL_IS_MEMBER_FUNCTION_PTR_VOID_CV_

#define IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(n)	\
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, IUTEST_PP_EMPTY());	\
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, const);	\
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, volatile);	\
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, const volatile)

#define IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, CV)	\
	template<typename R, typename U, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (U::*)(IUTEST_PP_ENUM_PARAMS(n, T)) CV> : public true_type {};	\
	template<typename R, typename U, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (U::*)(IUTEST_PP_ENUM_PARAMS(n, T), ...) CV> : public true_type {}

	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(1);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(2);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(3);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(4);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(5);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(6);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(7);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(8);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(9);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(10);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(11);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(12);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(13);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(14);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(15);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(16);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(17);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(18);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(19);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(20);

#undef IIUT_DECL_IS_MEMBER_FUNCTION_PTR_
#undef IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I

#endif

public:
	typedef bool_constant< impl< typename remove_cv<T>::type >::value > type;
};

}

/**
 * @brief	is member function pointer
*/
template<typename T>
struct is_member_function_pointer : public is_member_function_pointer_helper::is_member_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;
};

}

/**
 * @brief	is member pointer
*/
template<typename T>
struct is_member_pointer : public is_member_pointer_helper::is_member_pointer<T>::type
{
};

#endif // #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

#endif // #if IUTEST_HAS_HDR_TYPETRAITS

#if !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)

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
{
	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;
	};
}

/**
 * @brief	has equal to operator
*/
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;
	};
}

/**
 * @brief	has not equal to operator
*/
template<typename T>
struct has_not_equal_to : public has_not_equal_to_operator_impl::has_not_equal_to_operator<T>::type
{
};

#endif

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

/**
 * @brief	function return 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 IIUT_DECL_FUNCTION_RETURN_TYPE_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; }

	IIUT_DECL_FUNCTION_RETURN_TYPE_CV_(const);
	IIUT_DECL_FUNCTION_RETURN_TYPE_CV_(volatile);
	IIUT_DECL_FUNCTION_RETURN_TYPE_CV_(const volatile);
#undef IIUT_DECL_FUNCTION_RETURN_TYPE_CV_

#else

#define IIUT_DECL_FUNCTION_RETURN_TYPE_(n)	\
	template<typename R, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (*)(IUTEST_PP_ENUM_PARAMS(n, T))>	\
	{ typedef R type; };	\
	template<typename R, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (*)(IUTEST_PP_ENUM_PARAMS(n, T), ...)>	\
	{ typedef R type; };	\
	IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, IUTEST_PP_EMPTY());	\
	IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, const);	\
	IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, volatile);	\
	IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, const volatile)

#define IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, CV)	\
	template<typename R, typename U, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (U::*)(IUTEST_PP_ENUM_PARAMS(n, T)) CV>	\
	{ typedef R type; };	\
	template<typename R, typename U, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (U::*)(IUTEST_PP_ENUM_PARAMS(n, T), ...) CV>	\
	{ typedef R type; }

	template<typename R>struct impl<R (*)(void)>	{ typedef R type; };
	template<typename R, typename U>struct impl<R (U::*)(void)>	{ typedef R type; };

#define IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_(CV)	\
	template<typename R, typename U>struct impl<R (U::*)(void) CV>	{ typedef R type; }

	IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_(const);
	IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_(volatile);
	IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_(const volatile);

#undef IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_

	IIUT_DECL_FUNCTION_RETURN_TYPE_(1);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(2);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(3);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(4);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(5);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(6);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(7);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(8);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(9);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(10);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(11);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(12);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(13);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(14);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(15);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(16);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(17);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(18);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(19);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(20);

#undef IIUT_DECL_FUNCTION_RETURN_TYPE_
#undef IIUT_DECL_FUNCTION_RETURN_TYPE_I

#endif

public:
	typedef typename impl< typename remove_cv<T>::type >::type type;
};

#endif // #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

}	// end of namespace iutest_type_traits

#endif // INCG_IRIS_IUTEST_TYPE_TRAITS_HPP_6F091F15_784A_4F50_BD18_B8F67C5AF0CF_

#if IUTEST_HAS_HDR_CXXABI
#  include <cxxabi.h>
#endif

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

/**
 * @brief	曖昧な else 文の警告抑制
*/
#ifdef __INTEL_COMPILER
#  define IUTEST_AMBIGUOUS_ELSE_BLOCKER_
#else
#  define IUTEST_AMBIGUOUS_ELSE_BLOCKER_	switch(::iutest::detail::AlwaysZero()) case 0: default:
#endif

#define IUTEST_SUPPRESS_UNREACHABLE_CODE_WARNING(statement)	if( ::iutest::detail::AlwaysTrue() ) statement

// console
#define IUTEST_MBS_CODE_UNKNOWN		0
#define IUTEST_MBS_CODE_UTF8		1
#define IUTEST_MBS_CODE_WINDOWS31J	2
#ifndef IUTEST_MBS_CODE
#  if defined(IUTEST_OS_WINDOWS)
#    define IUTEST_MBS_CODE	IUTEST_MBS_CODE_WINDOWS31J
#  else
#    define IUTEST_MBS_CODE	IUTEST_MBS_CODE_UTF8
#  endif
#endif


#ifndef NULL
#  ifdef	__cplusplus
#    define NULL	0
#  else
#    define NULL	(void*)0
#  endif
#endif

#ifndef IUTEST_BREAK
#  if   defined(__MINGW32__)
#    define IUTEST_BREAK()	DebugBreak()
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1310
#      define IUTEST_BREAK()	__debugbreak()
#    else
#      define IUTEST_BREAK()	DebugBreak()
#    endif
#  elif defined(IUTEST_OS_MAC)
// http://www.cocoawithlove.com/2008/03/break-into-debugger.html
#    if defined(__ppc64__) || defined(__ppc__)
#    define IUTEST_BREAK()	__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" : : : "memory","r0","r3","r4" )
#    else
#    define IUTEST_BREAK()	__asm__("int $3\n" : : )
#    endif
#  elif 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()
#  elif defined(__ARMCC_VERSION)
#    define IUTEST_BREAK()	do { __breakpoint(0xF02C); } while(::iutest::detail::AlwaysFalse())
#  else
#    define IUTEST_BREAK()	*static_cast<volatile int*>(NULL) = 1
//#    define IUTEST_BREAK()	(void)0
#  endif
#endif


#if IUTEST_HAS_LIB && IUTEST_HAS_EXTERN_TEMPLATE

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template class ::std::vector< ::std::basic_string<char> >;
extern template class ::std::vector< ::std::basic_string<wchar_t> >;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#endif

namespace iutest
{

namespace type_traits = iutest_type_traits;

namespace detail
{

typedef void void_t;	// default template 引数用 (一部のコンパイラで = void だエラーになるため)

//======================================================================
// function

/**
 * @brief	true を返す(警告対策用)
*/
inline bool AlwaysTrue(void) { return true; }

/**
 * @brief	false を返す(警告対策用)
*/
inline bool AlwaysFalse(void) { return !AlwaysTrue(); }

/**
 * @brief	0 を返す(警告対策用)
*/
inline int  AlwaysZero(void) { return 0; }

/**
 * @brief	真偽値を返す(警告対策用)
*/
inline bool IsTrue(bool b) { return b; }

//======================================================================
// class

// detail から使えるようにする
using namespace iutest_type_traits;

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

/**
 * @brief	iterator traits
*/
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;
};

#endif

/**
 * @brief	delete
*/
template<typename T>
inline void Delete(T* ptr)
{
	delete ptr;
}

/**
 * @internal
 * @brief	空オブジェクト
*/
class None {};
template<typename T>
class NoneT1 {};

/**
 * @internal
 * @brief	MSVC 用ダミー型
*/
template<typename T>
struct explicit_type_t {};

#if defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
#  define IUTEST_EXPLICIT_TEMPLATE_TYPE_(t)			::iutest::detail::explicit_type_t<t>*
#  define IUTEST_APPEND_EXPLICIT_TEMPLATE_TYPE_(t)	, ::iutest::detail::explicit_type_t<t>*
#else
#  define IUTEST_EXPLICIT_TEMPLATE_TYPE_(t)	
#  define IUTEST_APPEND_EXPLICIT_TEMPLATE_TYPE_(t)	
#endif

template<typename T>
inline explicit_type_t<T>* explicit_type(void) { return NULL; }

/**
 * @brief	型に依存したユニークなカウンタ
*/
template<typename T>
class TypeUniqueCounter
{
	static int value;
public:
	static int count(void) { return value++; }
};
template<typename T>int TypeUniqueCounter<T>::value = 0;

template<typename T>
inline int GetTypeUniqueCounter(void) { return TypeUniqueCounter<T>::count(); }

/**
 * @internal
 * @brief	auto_ptr
*/
template<typename T>
class auto_ptr
{
	typedef auto_ptr<T> _Myt;
	mutable T* m_ptr;
public:
	auto_ptr(const _Myt& rhs) : m_ptr(rhs.m_ptr) { rhs.m_ptr = NULL; }
	auto_ptr(T* p=NULL) : m_ptr(p) {}
	~auto_ptr(void) { if( m_ptr != NULL ) delete m_ptr; }

	T& operator *  (void) const { return *m_ptr; }
	T* operator -> (void) const { return m_ptr; }

	T* get(void) { return m_ptr; }
};

/**
 * @internal
 * @brief	scoped_ptr
*/
template<typename T>
class scoped_ptr
{
	T* m_ptr;
public:
	scoped_ptr(T* p=NULL) : m_ptr(p) {}
	~scoped_ptr(void) { reset(); }

	T& operator *  (void) const { return *m_ptr; }
	T* operator -> (void) const { return m_ptr; }

	T* get(void) const { return m_ptr; }
	T* release(void)
	{
		T* const p = m_ptr;
		m_ptr = NULL;
		return p;
	}

	void reset(T* p=NULL)
	{
		if( m_ptr != p )
		{
			if( IsTrue(sizeof(T) > 0) ) delete m_ptr;
			m_ptr = p;
		}
	}
private:
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(scoped_ptr);
};

/**
 * @internal
 * @brief	NULL リテラルかどうか
*/
struct IsNullLiteralHelper
{
	class Object;

	static char IsNullLiteral(Object*);
	static char (&IsNullLiteral(...))[2];
};


#define IUTEST_IS_NULLLITERAL(x)	\
	(sizeof(::iutest::detail::IsNullLiteralHelper::IsNullLiteral(x)) == 1)

/**
 * @internal
 * @brief	stl コンテナかどうか
*/
struct IsContainerHelper
{
	typedef int  yes_t;
	typedef char no_t;

	template<typename T>
	static IUTEST_CXX_CONSTEXPR yes_t IsContainer(int IUTEST_APPEND_EXPLICIT_TEMPLATE_TYPE_(T), typename T::iterator* =NULL, typename T::const_iterator* =NULL) { return 0; }

	template<typename T>
	static IUTEST_CXX_CONSTEXPR no_t  IsContainer(long IUTEST_APPEND_EXPLICIT_TEMPLATE_TYPE_(T)) { return 0; }
};

/**
 * @brief	enable_if
*/
#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

template<bool B, typename T>
struct enable_if
{
	typedef T type;
};
template<typename T>
struct enable_if<false, T> {};

#else

namespace helper
{
	template<bool B>
	struct enable_if_impl_
	{
		template<typename T>struct inner { typedef T type; };
	};
	template<>
	struct enable_if_impl_<false>
	{
		template<typename T>struct inner {};
	};
}

template<bool B, typename T>
struct enable_if : public helper::enable_if_impl_<B>::template inner<T>
{
};

#endif

template<class COND, typename T = void_t>
struct enable_if_t : public enable_if<COND::value, T> {};

/**
 * @brief	disable_if
*/
template<bool B, typename T>
struct disable_if : public enable_if<!B, T> {};
template<class COND, typename T = void_t>
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 = NULL;

typedef enabler_t<void> enabler;

/**
 * @brief	identity
*/
template<typename T>struct identity { typedef T type; };

/**
 * @brief	型名の取得
*/
template<typename T>
inline ::std::string GetTypeName(void)
{
#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 GeTypeNameSpecialization(type)	\
	template<>inline ::std::string GetTypeName<type>(void) { return #type; }	\
	template<>inline ::std::string GetTypeName<type*>(void) { return #type "*"; }

GeTypeNameSpecialization(char)
GeTypeNameSpecialization(unsigned char)
GeTypeNameSpecialization(short)
GeTypeNameSpecialization(unsigned short)
GeTypeNameSpecialization(int)
GeTypeNameSpecialization(unsigned int)
GeTypeNameSpecialization(long)
GeTypeNameSpecialization(unsigned long)
GeTypeNameSpecialization(float)
GeTypeNameSpecialization(double)
GeTypeNameSpecialization(bool)

#undef GeTypeNameSpecialization

#endif

#if IUTEST_HAS_IF_EXISTS
#  define IUTEST_IF_EXISTS(identifier_, statement_)		__if_exists(identifier_) { statement_ }
#  define IUTEST_IF_NOT_EXISTS(identifier_, statement_)	__if_not_exists(identifier_) { statement_ }
#  define IUTEST_STATIC_EXISTS(identifier_)				IUTEST_IF_EXISTS(identifier_, true) IUTEST_IF_NOT_EXISTS(identifier_, false)
#else
#  define IUTEST_IF_EXISTS(identifier_, statement_)
#  define IUTEST_IF_NOT_EXISTS(identifier_, statement_)
#  define IUTEST_STATIC_EXISTS(identifier_)
#endif

}	// end of namespace detail
}	// end of namespace iutest


#endif // INCG_IRIS_IUTEST_INTERNAL_DEFS_HPP_4B0AF5C2_8E8D_43EF_BFC5_F385E68F18DB_

#if defined(IUTEST_OS_LINUX) || defined(IUTEST_OS_CYGWIN) || defined(IUTEST_OS_MAC)
#  include <unistd.h>
#  include <locale.h>
#endif

namespace iutest {

#ifdef IUTEST_OS_NACL
namespace nacl
{

/**
 * @brief	printf
*/
void vprint_message(const char *fmt, va_list va);
void print_message(const char *fmt, ...);

}
#endif

namespace internal {
namespace posix
{

const char* GetEnv(const char* name);
int PutEnv(const char* expr);

const char* GetCWD(char* buf, size_t length);
::std::string GetCWD(void);

void SleepMillisec(unsigned int millisec);

#if defined(IUTEST_OS_WINDOWS_MOBILE)
void Abort(void);
#else
IUTEST_ATTRIBUTE_NORETURN_ void Abort(void);
inline void Abort(void) { abort(); }
#endif

}	// end of namespace posix

inline void SleepMilliseconds(int n) { posix::SleepMillisec(static_cast<unsigned int>(n)); }

}	// end of namespace internal

namespace detail
{

namespace posix = internal::posix;

/**
 * @brief	パス区切り文字の取得
*/
char GetPathSeparator(void) IUTEST_CXX_NOEXCEPT_SPEC;

/**
 * @brief	パス区切り文字かどうか
*/
bool IsPathSeparator(char c) IUTEST_CXX_NOEXCEPT_SPEC;

/**
 * @brief	パス区切り文字かどうか
*/
bool IsAltPathSeparator(char c) IUTEST_CXX_NOEXCEPT_SPEC;

/**
 * @brief	環境変数の設定
*/
bool SetEnvironmentVariable(const char* name, const char* value);


/**
 * @brief	環境変数の取得
 * @param [in]	name	= 環境変数名
 * @param [out]	buf		= 出力バッファ
 * @return	成否
*/
bool GetEnvironmentVariable(const char* name, char* buf, size_t size);

#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)

template<size_t SIZE>
inline bool GetEnvironmentVariable(const char* name, char (&buf)[SIZE])
{
return GetEnvironmentVariable(name, buf, SIZE);
}

#endif

/**
 * @brief	環境変数の取得
 * @param [in]	name	= 環境変数名
 * @param [out]	var		= 出力文字列
 * @return	成否
 */
bool IUTEST_ATTRIBUTE_UNUSED_ GetEnvironmentVariable(const char* name, ::std::string& var);

/**
 * @brief	環境変数の取得
 * @param [in]	name	= 環境変数名
 * @param [out]	var		= 出力数値
 * @return	成否
 */
bool IUTEST_ATTRIBUTE_UNUSED_ GetEnvironmentInt(const char* name, int& var);

#if defined(IUTEST_OS_WINDOWS)
namespace win
{

	/**
	 * @brief	文字列変換
	 */
	::std::string IUTEST_ATTRIBUTE_UNUSED_ WideStringToMultiByteString(const wchar_t* wide_c_str);

	/**
	 * @brief	HRESULT のエラー文字列を取得
	 * @param [in]	hr	= エラー値
	 * @return	文字列
	 */
	::std::string IUTEST_ATTRIBUTE_UNUSED_ GetHResultString(HRESULT hr);

}	// end of namespace win
#endif

/**
 * @brief	ログ
 */
class IUTestLog
{
public:
	enum Level
	{
		LOG_INFO
		, LOG_WARNING
		, LOG_ERROR
		, LOG_FATAL
	};
public:
	IUTestLog(Level level, const char* file, int line);

	~IUTestLog(void);

public:
	iu_stringstream& GetStream(void) { return m_stream; }
private:
	const Level kLevel;
	iu_stringstream m_stream;

	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(IUTestLog);
};

#define IUTEST_LOG_(level)	::iutest::detail::IUTestLog(::iutest::detail::IUTestLog::LOG_##level, __FILE__, __LINE__).GetStream()
#define IUTEST_CHECK_(condition)	\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_	\
	if( ::iutest::detail::IsTrue(condition) )	\
		;										\
		else										\
		IUTEST_LOG_(FATAL) << "Condition " #condition " failed. "


#if IUTEST_HAS_STREAMCAPTURE

/**
 * @brief	stream capture
 */
template<int SIZE=BUFSIZ>
class IUStreamCapture
{
public:
	IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

	IUStreamCapture(FILE* fp)
		: m_fp(fp)
	{
		m_buf[0] = '\0';
		setvbuf(fp, m_buf, _IOFBF, SIZE);
	}

	~IUStreamCapture(void)
	{
		setbuf(m_fp, NULL);
	}

	IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

public:
	::std::string GetStreamString(void) { return m_buf; }

private:
	FILE* m_fp;
	char m_buf[SIZE];
};

#endif

}	// end of namespace detail
}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_port.ipp
 * @brief		iris unit test 依存関数 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PORT_IPP_7893F685_A1A9_477A_82E8_BF06237697FF_
#define INCG_IRIS_IUTEST_PORT_IPP_7893F685_A1A9_477A_82E8_BF06237697FF_

//======================================================================
// include

#ifdef IUTEST_OS_NACL
#  include <ppapi/cpp/var.h>
#  include <ppapi/cpp/instance.h>
#  include <ppapi/cpp/module.h>
#endif

namespace iutest {

#ifdef IUTEST_OS_NACL
namespace nacl
{

namespace detail
{

IUTEST_IPP_INLINE void PostMessage(const pp::Var& var)
{
	::pp::Module* module = ::pp::Module::Get();
	if( module != NULL )
	{
		if( module->current_instances().size() > 0 )
		{
			module->current_instances().begin()->second->PostMessage(var);
		}
	}
}

}	// end of namespace detail

IUTEST_IPP_INLINE void vprint_message(const char *fmt, va_list va)
{
	char msg[1024];
	vsnprintf(msg, sizeof(msg), fmt, va);
	char* tp = strtok(msg, "\n");
	while( tp != NULL )
	{
		detail::PostMessage(pp::Var(tp));
		tp = strtok(NULL, "\n");
	}
}
IUTEST_IPP_INLINE void print_message(const char *fmt, ...)
{
	va_list va;
	va_start(va, fmt);
	vprint_message(fmt, va);
	va_end(va);
}

}	// end of namespace nacl
#endif

namespace internal {
namespace posix
{

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

IUTEST_IPP_INLINE const char* GetEnv(const char* name)
{
#if defined(IUTEST_OS_WINDOWS_PHONE) || defined(IUTEST_OS_WINDOWS_RT) || defined(IUTEST_OS_WINDOWS_MOBILE) || defined(IUTEST_NO_GETENV)
	IUTEST_UNUSED_VAR(name);
	return NULL;
#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
	const char* env = getenv(name);
	return (env != NULL && env[0] != '\0') ? env : NULL;
#else
	return getenv(name);
#endif
}

IUTEST_IPP_INLINE int PutEnv(const char* expr)
{
#if defined(IUTEST_OS_WINDOWS_PHONE) || defined(IUTEST_OS_WINDOWS_RT) || defined(IUTEST_OS_WINDOWS_MOBILE) \
	|| defined(IUTEST_NO_PUTENV) || defined(__STRICT_ANSI__)
	IUTEST_UNUSED_VAR(expr);
	return -1;
#else
	return putenv(const_cast<char*>(expr));
#endif
}

IUTEST_IPP_INLINE const char* GetCWD(char* buf, size_t length)
{
#if   defined(IUTEST_OS_WINDOWS_PHONE) || defined(IUTEST_OS_WINDOWS_RT) || defined(IUTEST_OS_WINDOWS_MOBILE) \
		|| defined(IUTEST_OS_AVR32) || defined(IUTEST_OS_ARM) || defined(IUTEST_NO_GETCWD)
	if( buf == NULL || length < 3 )
	{
		return NULL;
	}
	buf[0] = '.';
	buf[1] = '/';
	buf[2] = '\0';
	return buf;
#elif defined(IUTEST_OS_WINDOWS)
	return ::GetCurrentDirectoryA(static_cast<DWORD>(length), buf) == 0 ? NULL : buf;
#else
	const char* result = getcwd(buf, length);
	if( result == NULL && buf != NULL && length >= 1 )
	{
#if defined(IUTEST_OS_NACL)
		if( length < 3 )
		{
			return NULL;
		}
		buf[0] = '.';
		buf[1] = '/';
		buf[2] = '\0';
		return buf;
#else
		buf[0] = '\0';
		return buf;
#endif
	}
	return result;
#endif
}

IUTEST_IPP_INLINE ::std::string GetCWD(void)
{
	char buf[260] = { 0 };
	return GetCWD(buf, sizeof(buf));
}

IUTEST_IPP_INLINE void SleepMillisec(unsigned int millisec)
{
#if   defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
	Sleep(millisec);
#elif defined(IUTEST_OS_LINUX) || defined(IUTEST_OS_CYGWIN)

#if   defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
	const timespec time = { 0, static_cast<long>(millisec) * 1000 * 1000 };
	nanosleep(&time, NULL);
#elif (defined(_BSD_SOURCE) && _BSD_SOURCE)
	|| (defined(_XOPEN_SOURCE)
		&& (_XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED)
		&& (!defined(_POSIX_C_SOURCE) || !(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)) )
	usleep(millisec*1000);
#else
	usleep(millisec*1000);
#endif

#else
	volatile int x=0;
	for( unsigned int i=0; i < millisec; ++i ) x += 1;
	IUTEST_UNUSED_VAR(x);
#endif
}

#if defined(IUTEST_OS_WINDOWS_MOBILE)
void Abort(void)
{
	DebugBreak();
	TerminateProcess(GetCurrentProcess(), 1);
}
#endif

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

}	// end of namespace posix
}	// end of namespace internal

namespace detail
{

IUTEST_IPP_INLINE char GetPathSeparator(void) IUTEST_CXX_NOEXCEPT_SPEC
{
#ifdef IUTEST_OS_WINDOWS
	return '\\';
#else
	return '/';
#endif
}

IUTEST_IPP_INLINE bool IsPathSeparator(char c) IUTEST_CXX_NOEXCEPT_SPEC
{
#ifdef IUTEST_OS_WINDOWS
	if( c == '\\' )
	{
		return true;
	}
#endif
	return c == '/';
}

IUTEST_IPP_INLINE bool IsAltPathSeparator(char c) IUTEST_CXX_NOEXCEPT_SPEC
{
#ifdef IUTEST_OS_WINDOWS
	if( c == '/' )
	{
		return true;
	}
#else
	IUTEST_UNUSED_VAR(c);
#endif
	return false;
}

IUTEST_IPP_INLINE bool SetEnvironmentVariable(const char* name, const char* value)
{
#if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MOBILE) && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
	return ::SetEnvironmentVariableA(name, value) ? true : false;
#else
	::std::string var = name;
	var += "=";
	var += value;
	return internal::posix::PutEnv(var.c_str()) == 0 ? true : false;
#endif
}

IUTEST_IPP_INLINE bool GetEnvironmentVariable(const char* name, char* buf, size_t size)
{
	if( buf == NULL ) return false;
#if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MOBILE) && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
	const DWORD ret = ::GetEnvironmentVariableA(name, buf, static_cast<DWORD>(size));
	if( ret == 0 )
	{
		return false;
	}
	if( ret > size )
	{
		return false;
	}
	return true;
#else
	const char* env = internal::posix::GetEnv(name);
	if( env == NULL )
	{
		return false;
	}
	if( size <= strlen(env) )
	{
		return false;
	}
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
	strcpy(buf, env);
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
	return true;
#endif
}

IUTEST_IPP_INLINE bool GetEnvironmentVariable(const char* name, ::std::string& var)
{
#if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MOBILE)
	char buf[2048];
	if( !GetEnvironmentVariable(name, buf, sizeof(buf)) )
	{
		return false;
	}
	var = buf;
	return true;
#else
	const char* env = internal::posix::GetEnv(name);
	if( env == NULL )
	{
		return false;
	}
	var = env;
	return true;
#endif
}

IUTEST_IPP_INLINE bool GetEnvironmentInt(const char* name, int& var)
{
#if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MOBILE)
	char buf[128] = {0};
	if( !GetEnvironmentVariable(name, buf, sizeof(buf)) )
	{
		return false;
	}
	char* end = NULL;
	var = static_cast<int>(strtol(buf, &end, 0));
	return true;
#else
	const char* env = internal::posix::GetEnv(name);
	if( env == NULL )
	{
		return false;
	}
	char* end = NULL;
	var = static_cast<int>(strtol(env, &end, 0));
	return true;
#endif
}

#if defined(IUTEST_OS_WINDOWS)
namespace win
{

IUTEST_IPP_INLINE ::std::string WideStringToMultiByteString(const wchar_t* wide_c_str)
{
	if( wide_c_str == NULL ) return "";
	::std::string str;
	const int length = static_cast<int>(wcslen(wide_c_str)) * 2 + 1;
	char* mbs = new char [length];
	WideCharToMultiByte(932, 0, wide_c_str, static_cast<int>(wcslen(wide_c_str))+1, mbs, length, NULL, NULL);
	str = mbs;
	delete [] mbs;
	return str;
}

IUTEST_IPP_INLINE ::std::string GetHResultString(HRESULT hr)
{
#if !defined(IUTEST_OS_WINDOWS_MOBILE)

#if defined(FORMAT_MESSAGE_ALLOCATE_BUFFER)
	LPSTR buf = NULL;
#else
	CHAR buf[4096];
#endif
	if( FormatMessageA(
#if defined(FORMAT_MESSAGE_ALLOCATE_BUFFER)
		FORMAT_MESSAGE_ALLOCATE_BUFFER |
#endif
		FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS
		, NULL
		, hr
		, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) // デフォルト ユーザー言語
#if defined(FORMAT_MESSAGE_ALLOCATE_BUFFER)
		, (LPSTR)&buf
		, 0
#else
		, buf
		, IUTEST_PP_COUNTOF(buf)
#endif
		, NULL ) == 0 )
	{
		return "";
	}

	::std::string str = (buf == NULL) ? "" : buf;
#if defined(FORMAT_MESSAGE_ALLOCATE_BUFFER)
	LocalFree(buf);
#endif
#else
	LPWSTR buf = NULL;
	if( FormatMessageW(
		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS
		, NULL
		, hr
		, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) // デフォルト ユーザー言語
		, (LPWSTR)&buf
		, 0
		, NULL ) == 0 )
	{
		return "";
	}

	::std::string str = (buf == NULL) ? "" : WideStringToMultiByteString(buf);
	LocalFree(buf);
#endif
	return str;
}

}	// end of namespace win
#endif

// declare
::std::string FormatFileLocation(const char* file, int line);

IUTEST_IPP_INLINE IUTestLog::IUTestLog(Level level, const char* file, int line)
	: kLevel(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() << ": ";
}

IUTEST_IPP_INLINE IUTestLog::~IUTestLog(void)
{
	GetStream() << "\r\n";
	fprintf(stderr, "%s", m_stream.str().c_str());
	if( kLevel == LOG_FATAL )
	{
		fflush(stderr);
		posix::Abort();
	}
}

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_PORT_IPP_7893F685_A1A9_477A_82E8_BF06237697FF_
#endif

#endif // INCG_IRIS_IUTEST_PORT_HPP_7893F685_A1A9_477A_82E8_BF06237697FF_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_constant.hpp
 * @brief		iris unit test 定数 定義 ファイル
 *
 * @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_CONSTANT_HPP_37DDDC13_3259_42E0_A648_47B064DED4BA_
#define INCG_IRIS_IUTEST_CONSTANT_HPP_37DDDC13_3259_42E0_A648_47B064DED4BA_

//======================================================================
// include

namespace iutest {
namespace detail
{

namespace helper
{

/**
 * @brief	文字列定数
*/
template<typename DMY>
struct kStringsT
{
	static const char* const DefaultXmlReportFileName;	//!< デフォルト xml 出力ファイル名
	static const char* const UnknownFile;				//!< unknown file
	static const char* const Null;						//!< NULL
};

#if IUTEST_HAS_LIB && IUTEST_HAS_EXTERN_TEMPLATE

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template struct kStringsT<void>;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#else

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>;

#endif

}	// end of namespace helper


typedef helper::kStringsT<void> kStrings;

/**
 * @brief	定数群
*/
struct kValues
{
#if defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
	enum
	{
		MaxPrintContainerCount = 32
		, PrintArrayThreshold = 16
		, PrintArrayChunksize = PrintArrayThreshold/2
	};
#else
	static const size_t MaxPrintContainerCount = 32;
	static const size_t PrintArrayThreshold = 18;
	static const size_t PrintArrayChunksize = PrintArrayThreshold/2;
#endif
};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_CONSTANT_HPP_37DDDC13_3259_42E0_A648_47B064DED4BA_

#if IUTEST_HAS_CXX_HDR_CODECVT
#  include <codecvt>
#endif

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

namespace iutest {
namespace detail
{

//======================================================================
// declare
/**
 * @brief	ワイド文字列からUTF8へ変換
 * @param [in]	str	= 入力
 * @param [in]	num = 入力バッファサイズ
 * @return	UTF8 文字列
*/
::std::string WideStringToUTF8(const wchar_t* str, int num=-1);

/**
 * @brief	ワイド文字列からマルチバイトへ変換
 * @param [in]	str	= 入力
 * @param [in]	num = 入力バッファサイズ
 * @return	マルチバイト文字列
*/
::std::string WideStringToMultiByteString(const wchar_t* str, int num=-1);

/**
 * @brief	文字列から ::std::wstring へ変換
 * @param [in]	c_str	= 入力
 * @return	wstring
*/
::std::wstring MultiByteStringToWideString(const char* str);

/**
 * @brief	マルチバイト文字からUTF8へ変換
 * @param [in]	str	= 入力
 * @param [in]	num = 入力バッファサイズ
 * @return	UTF8 文字列
*/
::std::string MultiByteStringToUTF8(const char* src, int num=-1);

/**
 * @brief	ワイド文字列から ::std::string へ変換
 * @param [in]	wide_c_str	= 入力
 * @return	string
*/
::std::string ShowWideCString(const wchar_t* wide_c_str);


#if IUTEST_HAS_CXX_HDR_CODECVT
/**
 * @brief	UTF16文字列からUTF8へ変換
 * @param [in]	str	= 入力
 * @param [in]	num = 入力バッファサイズ
 * @return	UTF8 文字列
*/
#if IUTEST_HAS_CHAR16_T
::std::string UTF16ToUTF8(const char16_t* str, int num=-1);
#else
::std::string UTF16ToUTF8(const wchar_t* str, int num=-1);
#endif

#endif

//======================================================================
// function

inline ::std::string ShowWideCString(const wchar_t* wide_c_str)
{
	if( wide_c_str == NULL )
	{
		return kStrings::Null;
	}
#if IUTEST_MBS_CODE == IUTEST_MBS_CODE_UTF8
	return WideStringToUTF8(wide_c_str);
#elif defined(IUTEST_OS_WINDOWS) && IUTEST_MBS_CODE == IUTEST_MBS_CODE_WINDOWS31J
	return win::WideStringToMultiByteString(wide_c_str);
#else
	return WideStringToMultiByteString(wide_c_str);
#endif
}

#if IUTEST_HAS_CHAR16_T
inline ::std::string ShowWideCString(const char16_t* wide_c_str)
{
	if(wide_c_str == NULL)
	{
		return kStrings::Null;
	}
#if IUTEST_HAS_CXX_HDR_CODECVT
#if IUTEST_MBS_CODE == IUTEST_MBS_CODE_UTF8
	return UTF16ToUTF8(wide_c_str);
#else
	return ShowWideCString(reinterpret_cast<const wchar_t*>(wide_c_str));
	//return UTF16ToMultiByteString(wide_c_str);
#endif
#else
	return ShowWideCString(reinterpret_cast<const wchar_t*>(wide_c_str));
#endif
}
#endif

//======================================================================
// struct
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 = ShowWideCString(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 {};
}	// end of namespace mbs_ptr_impl

/**
 * @brief	mbs_ptr
*/
template<typename CharType>
struct mbs_ptr : public mbs_ptr_impl::to_mbs_ptr<CharType>
{
};

#if IUTEST_HAS_LIB

#if IUTEST_HAS_EXTERN_TEMPLATE

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template struct mbs_ptr<char>;
extern template struct mbs_ptr<wchar_t>;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#else

template struct mbs_ptr<char>;
template struct mbs_ptr<wchar_t>;

#endif
#endif

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

}	// end of namespace detail
}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_charcode.ipp
 * @brief		iris unit test 文字コード対応 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CHARCODE_IPP_D444FB3E_3AFA_46D0_AD69_33FAAF5615E3_
#define INCG_IRIS_IUTEST_CHARCODE_IPP_D444FB3E_3AFA_46D0_AD69_33FAAF5615E3_

//======================================================================
// include

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

namespace iutest {
namespace detail
{

//======================================================================
// variable
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;

//======================================================================
// function
/**
 * @brief	サロゲートペアかどうか
*/
IUTEST_IPP_INLINE IUTEST_CXX_CONSTEXPR bool IsUtf16SurrogatePair(wchar_t first, wchar_t second)
{
	return (sizeof(wchar_t) == 2)
		&& ((first & 0xFC00) == 0xD800) && ((second & 0xFC00) == 0xDC00);
}
/**
 * @brief	サロゲートペアからコードポイントへ変換
*/
IUTEST_IPP_INLINE IUTEST_CXX_CONSTEXPR UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, wchar_t second)
{
	//const UInt32 mask = (1<<10) -1;	// 0x3FF
	return (sizeof(wchar_t)==2) ?
		(((first & 0x3FF) << 10) | (second & 0x3FF)) + 0x10000 :
		static_cast<UInt32>(first);	// こっちは未対応
}
/**
 * @brief	下位から指定ビット数のビットを取得してシフトする
*/
IUTEST_IPP_INLINE UInt32 ChopLowBits(UInt32* bits, int n)
{
	const UInt32 lowbits = *bits & ((static_cast<UInt32>(1) << n) - 1);
	*bits >>= n;
	return lowbits;
}

/**
 * @brief	コードポイントからUTF8へ変換
 * @param [in]	code_point	= コードポイント
 * @param [out]	buf			= 出力バッファ(32バイト以上を要求)
 * @return	出力バッファ
*/
IUTEST_IPP_INLINE char* CodePointToUtf8(UInt32 code_point, char* buf)
{
	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
	{
		sprintf(buf, "(Invalid UTF16 0x%X)", code_point);
	}
	return buf;
}

IUTEST_IPP_INLINE ::std::string IUTEST_ATTRIBUTE_UNUSED_ WideStringToUTF8(const wchar_t* str, int num)
{
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
	if(num == -1)
	{
		num = static_cast<int>(wcslen(str));
	}
#if IUTEST_HAS_CXX_HDR_CODECVT && 0
	typedef ::std::codecvt_utf8<wchar_t> convert;
	::std::locale loc("japanese");
	const convert& conv = ::std::use_facet<convert>(loc);
	::std::mbstate_t state=0;
	const size_t utf8_length = num * 2 + 1;
	char* utf8 = new char[utf8_length];
	const wchar_t* src_next = NULL;
	char* utf8_next = NULL;
	convert::result res = conv.out(state, str, str + num, src_next, utf8, utf8 + utf8_length, utf8_next);
	::std::string ret;
	if( res == convert::ok )
	{
		ret = utf8;
	}
	delete[] utf8;
	return ret;
#else
	iu_stringstream ss;
	for(int i=0; i < num; ++i )
	{
		UInt32 code_point;
		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];
		ss << CodePointToUtf8(code_point, buf);
	}
	return ss.str();
#endif
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
}

IUTEST_IPP_INLINE ::std::string IUTEST_ATTRIBUTE_UNUSED_ WideStringToMultiByteString(const wchar_t* str, int num)
{
	IUTEST_UNUSED_VAR(num);
#if defined(IUTEST_OS_WINDOWS) && IUTEST_MBS_CODE == IUTEST_MBS_CODE_WINDOWS31J
	return win::WideStringToMultiByteString(str);
#else
	const size_t length = wcslen(str) * MB_CUR_MAX + 1;
	char* mbs = new char [length];
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
	if( wcstombs(mbs, str, length) == static_cast<size_t>(-1))
	{
		delete [] mbs;
		return "(convert error)";
	}
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
	::std::string ret = mbs;
	delete [] mbs;
	return ret;
#endif
}

IUTEST_IPP_INLINE ::std::wstring IUTEST_ATTRIBUTE_UNUSED_ MultiByteStringToWideString(const char* str)
{
	if(str == NULL)
	{
		return L"";
	}
	const size_t length = strlen(str) + 1;
	wchar_t* wcs = new wchar_t[length];
	IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
	if(mbstowcs(wcs, str, length) == static_cast<size_t>(-1))
	{
		delete[] wcs;
		return L"(convert error)";
	}
	IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
	::std::wstring ret = wcs;
	delete[] wcs;
	return ret;
}

IUTEST_IPP_INLINE ::std::string IUTEST_ATTRIBUTE_UNUSED_ MultiByteStringToUTF8(const char* src, int num)
{
#if (defined(__STDC_ISO_10646__) || defined(_MSC_VER)) && !defined(IUTEST_OS_WINDOWS_MOBILE)
	if( num == -1 )
	{
		num = static_cast<int>(strlen(src));
	}
	::std::string str;
	const char* p = src;
	//char* locale = setlocale(LC_CTYPE, "JPN");
	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 += WideStringToUTF8(&wc, 1);
			p += len;
		}
		else
		{
			str += *p;
			++p;
		}
	}
	//setlocale(LC_CTYPE, locale);
	return str;
#else
	IUTEST_UNUSED_VAR(num);
	return src;
#endif
}

#if IUTEST_HAS_CXX_HDR_CODECVT

#if IUTEST_HAS_CHAR16_T
IUTEST_IPP_INLINE ::std::string UTF16ToUTF8(const char16_t* str, int num)
#else
IUTEST_IPP_INLINE ::std::string UTF16ToUTF8(const wchar_t* str, int num)
#endif
{
	if(num == -1)
	{
		num = static_cast<int>(wcslen(str));
	}
#if IUTEST_HAS_CHAR16_T
	typedef ::std::codecvt_utf8<char16_t> convert;
#else
	typedef ::std::codecvt_utf8<wchar_t> convert;
#endif
	::std::locale loc("japanese");
	const convert& conv = ::std::use_facet<convert>(loc);
	::std::mbstate_t state=0;
	const size_t utf8_length = num * 2 + 1;
	char* utf8 = new char[utf8_length];
	const convert::_Elem* src_next = NULL;
	char* utf8_next = NULL;
	convert::result res = conv.out(state, str, str + num, src_next, utf8, utf8 + utf8_length, utf8_next);
	::std::string ret;
	if(res == convert::ok)
	{
		ret = utf8;
	}
	delete[] utf8;
	return ret;
}

#endif

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_CHARCODE_IPP_D444FB3E_3AFA_46D0_AD69_33FAAF5615E3_
#endif

#endif // INCG_IRIS_IUTEST_CHARCODE_HPP_D444FB3E_3AFA_46D0_AD69_33FAAF5615E3_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_random.hpp
 * @brief		iris unit test 乱数生成器 定義 ファイル
 *
 * @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_RANDOM_HPP_89F260D7_9145_4B50_A8F0_B7A2696121B6_
#define INCG_IRIS_IUTEST_RANDOM_HPP_89F260D7_9145_4B50_A8F0_B7A2696121B6_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_time.hpp
 * @brief		iris unit test time utility ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_TIME_HPP_C6B9E65B_4059_4175_A6DB_397DBF338AA8_
#define INCG_IRIS_IUTEST_TIME_HPP_C6B9E65B_4059_4175_A6DB_397DBF338AA8_

//======================================================================
// include
#include <time.h>

#if IUTEST_HAS_CXX_HDR_CHRONO
#  include <chrono>
#endif

#if   IUTEST_HAS_HDR_SYSTIME
#  include <sys/time.h>
#elif defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MOBILE)
#  include <sys/timeb.h>
#endif

namespace iutest {
namespace detail
{

//======================================================================
// declare
/**
 * @internal
 * @brief	localtime
 * @param	[in]	sec	= 秒
 * @param	[out]	dst	= 時刻
 * @return	成否
*/
bool Localtime(time_t sec, struct tm* dst);

/**
 * @internal
 * @brief	TimeInMillisec to string
 * @param	[in]	msec	= ミリ秒
 * @return	秒数の文字列
*/
::std::string FormatTimeInMillisecAsSecond(TimeInMillisec msec);

/**
 * @internal
 * @brief	TimeInMillisec to string
 * @param	[in]	msec	= ミリ秒
 * @return	時刻の文字列
*/
::std::string FormatTimeInMillisecAsIso8601(TimeInMillisec msec);

/**
 * @brief	現在時刻の取得
*/
time_t GetTime(void);

/**
 * @brief	現在時刻のミリ秒取得
*/
TimeInMillisec GetTimeInMillis(void);

/**
 * @brief	不定な値の取得
*/
unsigned int GetIndefiniteValue(void);

//======================================================================
// class
/**
 * @internal
 * @brief	ストップウォッチクラス
*/
class iuStopWatch
{
private:
	TimeInMillisec m_begin;
public:
	iuStopWatch(void) : m_begin(0) {}

public:
	// 現在の時間をミリ秒単位で取得
	static TimeInMillisec get_millisec(void)
	{
#if defined(IUTEST_NOT_SUPPORT_STOPWATCH)
		return 0;
#else
		return GetTimeInMillis();
#endif
	}
public:
	void start(void)
	{
		m_begin = get_millisec();
	}
	TimeInMillisec stop(void) const
	{
		return get_millisec() - m_begin;
	}
};

}	// end of namespace detail
}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_time.ipp
 * @brief		iris unit test time utility
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_TIME_IPP_C6B9E65B_4059_4175_A6DB_397DBF338AA8_
#define INCG_IRIS_IUTEST_TIME_IPP_C6B9E65B_4059_4175_A6DB_397DBF338AA8_

//======================================================================
// include

namespace iutest {
namespace detail
{

//======================================================================
// function
IUTEST_IPP_INLINE bool Localtime(time_t sec, struct tm* dst)
{
#if IUTEST_HAS_CTIME

#if defined(_MSC_VER)
#  if defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__
	return localtime_s(dst, &sec) == 0;
#  else
	struct tm* t = localtime(&sec);
	if( t == NULL ) return false;
	if( dst != NULL ) *dst = *t;
	return true;
#  endif
#elif defined(__MINGW32__) || defined(__MINGW64__)
	const struct tm* const t = localtime(&sec);
	if( t == NULL || dst == NULL ) return false;
	*dst = *t;
	return true;
#else
	return localtime_r(&sec, dst) != NULL;
#endif

#else
	IUTEST_UNUSED_VAR(sec);
	IUTEST_UNUSED_VAR(dst);
	return false;
#endif
}

IUTEST_IPP_INLINE ::std::string FormatTimeInMillisecAsSecond(TimeInMillisec msec)
{
	iu_stringstream ss;
#if defined(_MSC_VER) && _MSC_VER < 1300
	ss << static_cast<unsigned int>(msec)/1000.0;
#else
	ss << static_cast<double>(msec)*1e-3;
#endif
	return ss.str();
}

IUTEST_IPP_INLINE ::std::string FormatTimeInMillisecAsIso8601(TimeInMillisec msec)
{
#if IUTEST_HAS_CTIME
	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);
#else
	return FormatTimeInMillisecAsSecond(msec);
#endif
}

IUTEST_IPP_INLINE time_t GetTime(void)
{
#if IUTEST_HAS_CTIME
	return time(NULL);
#else
	return 0;
#endif
}

IUTEST_IPP_INLINE TimeInMillisec GetTimeInMillis(void)
{
#if   defined(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 IUTEST_HAS_GETTIMEOFDAY
	timeval tv;
	gettimeofday(&tv, NULL);
	return static_cast<TimeInMillisec>(tv.tv_sec) * 1000 + static_cast<TimeInMillisec>(tv.tv_usec) / 1000;

#elif defined(IUTEST_OS_WINDOWS)

#if defined(IUTEST_OS_WINDOWS_MOBILE)
	return static_cast<TimeInMillisec>(GetTickCount());
#else

	_timeb tb;

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
	_ftime(&tb);
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

	return static_cast<TimeInMillisec>(tb.time * 1000 + tb.millitm);

#endif

#elif IUTEST_HAS_CLOCK
	return clock() * 1000 / CLOCKS_PER_SEC;

#else

#define IUTEST_NO_GETTIMEINMILLIS
	return GetTime()*1000;
#endif
}

IUTEST_IPP_INLINE unsigned int GetIndefiniteValue(void)
{
#if !defined(IUTEST_NO_GETTIMEINMILLIS)
	return static_cast<unsigned int>(GetTimeInMillis());
#else
	// なるべく同じにならないようにする
	static unsigned int s = 20120206;
	s = s*1664525 + 1013904223;
	return s;
#endif
}

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_TIME_IPP_C6B9E65B_4059_4175_A6DB_397DBF338AA8_
#endif

#endif // INCG_IRIS_IUTEST_TIME_HPP_C6B9E65B_4059_4175_A6DB_397DBF338AA8_

#if IUTEST_HAS_CXX_HDR_RANDOM
#  include <random>
#endif

namespace iutest {
namespace detail
{

//======================================================================
// class
/**
 * @brief	乱数生成器クラス
*/
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) IUTEST_CXX_NOEXCEPT_SPEC
		{
			seed(s);
		}
		result_type operator ()(void)
		{
			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:
#if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
		static IUTEST_CXX_CONSTEXPR_OR_CONST result_type _Min = 0;
		static IUTEST_CXX_CONSTEXPR_OR_CONST result_type _Max = static_cast<result_type>(-1);
#endif

		static IUTEST_CXX_CONSTEXPR result_type (min)(void) { return 0; }
		static IUTEST_CXX_CONSTEXPR result_type (max)(void) { return static_cast<result_type>(-1); }

	private:
		result_type gen(void)
		{
			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 IUTEST_CXX_CONSTEXPR result_type (min)(void) { return (Engine::min)(); }
	static IUTEST_CXX_CONSTEXPR result_type (max)(void) { return (Engine::max)(); }

#if defined(__clang__) && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3))
	static IUTEST_CXX_CONSTEXPR_OR_CONST result_type _Min = Engine::_Min;
	static IUTEST_CXX_CONSTEXPR_OR_CONST result_type _Max = Engine::_Max;
#endif

public:
	iuRandom(void)
	{
		init();
	}

	iuRandom(unsigned int seed)
	{
		init(seed);
	}

public:
	/**
	 * @brief	初期化
	 * @details	時間でシードを決定
	*/
	void init(void)
	{
		init(GetIndefiniteValue());
	}
	/**
	 * @brief	初期化
	 * @param [in]	seed	= シード
	*/
	void init(unsigned int seed)
	{
		m_engine = Engine(seed);
	}

public:
	/**
	 * @brief	乱数の生成
	 * @return	乱数
	*/
	result_type genrand(void)
	{
		return m_engine();
	}

	/**
	 * @brief	乱数の生成
	 * @details	[0,max) の乱数を生成
	 * @param [in]	max	= 上限値
	 * @return	乱数
	*/
	result_type genrand(unsigned int max)
	{
#if IUTEST_HAS_CXX_HDR_RANDOM
		return ::std::uniform_int_distribution<unsigned int>(0, max-1)(m_engine);
#else
		return genrand()%max;
#endif
	}

	/**
	 * @brief	乱数の生成
	 * @details	[0,1] の乱数を生成
	 * @return	乱数
	*/
	float genrandf(void)
	{
#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
	}

	/**
	 * @brief	乱数の生成
	 * @return	乱数
	*/
	template<typename T>
	T genrand(IUTEST_EXPLICIT_TEMPLATE_TYPE_(T))
	{
		return static_cast<T>(genrand( static_cast<unsigned int>( static_cast<T>(-1) ) ));
	}

#if IUTEST_HAS_CLASS_MEMBER_TEMPLATE_SPECIALIZATION && (defined(_MSC_VER) && _MSC_VER < 1300)
	template<>float  genrand<float>(IUTEST_EXPLICIT_TEMPLATE_TYPE_(float)) { return genrandf(); }
	template<>double genrand<double>(IUTEST_EXPLICIT_TEMPLATE_TYPE_(double)) { return static_cast<double>(genrandf()); }
#endif

public:
	result_type operator ()(void)
	{
		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
	}
};

#if !(defined(_MSC_VER) && _MSC_VER < 1300)

template<> inline Int64  iuRandom::genrand<Int64>(IUTEST_EXPLICIT_TEMPLATE_TYPE_(Int64))   { return (static_cast<Int64>(genrand()) << 32) | genrand(); }
template<> inline UInt64 iuRandom::genrand<UInt64>(IUTEST_EXPLICIT_TEMPLATE_TYPE_(UInt64)) { return (static_cast<UInt64>(genrand()) << 32) | genrand(); }
template<> inline float  iuRandom::genrand<float>(IUTEST_EXPLICIT_TEMPLATE_TYPE_(float))   { return genrandf(); }
template<> inline double iuRandom::genrand<double>(IUTEST_EXPLICIT_TEMPLATE_TYPE_(double)) { return static_cast<double>(genrandf()); }

#endif

/**
 * @brief	型指定乱数生成器
*/
template<typename T>
class iuTypedRandom
{
	typedef T result_type;
public:
	iuTypedRandom(void) {}
	iuTypedRandom(unsigned int seed)
		: m_rnd(seed) {}

	result_type operator ()(void)
	{
		return genrand();
	}

	result_type genrand(void)
	{
#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
#if defined(__MWERKS__)
		return m_rnd.template genrand<result_type>();
#else
		return m_rnd.genrand<result_type>();
#endif
#else
		return m_rnd.genrand(detail::explicit_type<result_type>());
#endif
	}
private:
	iuRandom m_rnd;
};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_RANDOM_HPP_89F260D7_9145_4B50_A8F0_B7A2696121B6_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_regex.hpp
 * @brief		regex
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_REGEX_HPP_1575CB44_189A_4248_B305_DB4882E3BFC2_
#define INCG_IRIS_IUTEST_REGEX_HPP_1575CB44_189A_4248_B305_DB4882E3BFC2_

//======================================================================
// include
#if IUTEST_HAS_CXX_HDR_REGEX
#  include <regex>
#endif

namespace iutest {
namespace detail
{

/**
 * @brief	filter regex クラス
*/
class iuFilterRegex
{
	static bool match_impl(const char* begin, const char* end, const char* src);
	static bool match_impl_group(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

/**
* @brief	regex クラス
*/
class iuRegex
{
public:
	iuRegex(const char* pattern) { Init(pattern); }
	iuRegex(const ::std::string& pattern) { Init(pattern.c_str()); }
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;

	IUTEST_PP_DISALLOW_ASSIGN(iuRegex);
};

#endif

}	// end of namespace detail

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

}

}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_regex.ipp
 * @brief		regex
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_REGEX_IPP_1575CB44_189A_4248_B305_DB4882E3BFC2_
#define INCG_IRIS_IUTEST_REGEX_IPP_1575CB44_189A_4248_B305_DB4882E3BFC2_

//======================================================================
// include

namespace iutest {
namespace detail
{

IUTEST_IPP_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;
}

IUTEST_IPP_INLINE bool iuFilterRegex::match_impl_group(const char* begin, const char* end, const char* src)
{
	bool match = true;
	const char* tp = begin;
	const char* end2 = tp;
	while( end2 != end )
	{
		++end2;
		while( *end2 != '-' && end2 != end ) ++end2;
		if( *tp == '-' )
		{
			if( match_impl(tp + 1, end2, src) ) match = false;
		}
		else
		{
			if( !match_impl(tp, end2, src) ) match = false;
		}
		tp = end2;
	}
	return match;
}

IUTEST_IPP_INLINE bool iuFilterRegex::match(const char* regex, const char* src)
{
	const char* tp = regex;
	bool positive = false;
	bool positive_checked = false;
	bool negative = true;

	while( *tp != '\0' )
	{
		const char* end = tp;
		while( *end != '\0' && *end != ':' ) ++end;

		if( tp != end )
		{
			if( *tp == '-' )
			{
				if( match_impl(tp + 1, end, src) )
				{
					return false;
				}
				negative = false;
			}
			else
			{
				positive_checked = true;
				if( match_impl_group(tp, end, src) )
				{
					positive = true;
				}
			}
			tp = end;
		}
		if( *tp == ':' ) ++tp;
	}
	if( !negative && !positive_checked )
	{
		positive = true;
	}
	return positive;
}

#if IUTEST_HAS_CXX_HDR_REGEX

IUTEST_IPP_INLINE bool iuRegex::FullMatch(const char* str) const
{
	if( str == NULL ) return false;
	return ::std::regex_match(str, m_re);
}

IUTEST_IPP_INLINE bool iuRegex::PartialMatch(const char* str) const
{
	if( str == NULL ) return false;
	return ::std::regex_search(str, m_re);
}

IUTEST_IPP_INLINE void iuRegex::Init(const char* str)
{
	m_re.assign(str);
	m_pattern = str;
}

#endif

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_REGEX_IPP_1575CB44_189A_4248_B305_DB4882E3BFC2_
#endif

#endif // INCG_IRIS_IUTEST_REGEX_HPP_1575CB44_189A_4248_B305_DB4882E3BFC2_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_listener.hpp
 * @brief		iris unit test イベントリスナー 定義 ファイル
 *
 * @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_LISTENER_HPP_C94B8142_F8B3_413F_B479_8AA2B78604CE_
#define INCG_IRIS_IUTEST_LISTENER_HPP_C94B8142_F8B3_413F_B479_8AA2B78604CE_

//======================================================================
// include
#include <vector>
#include <algorithm>

namespace iutest
{

//======================================================================
// declare
class UnitTest;
class TestInfo;
class TestCase;
class TestPartResult;
class TestProperty;
class TestEventListener;

namespace detail
{
	class DefaultGlobalTestPartResultReporter;
}

}

#if IUTEST_HAS_LIB && IUTEST_HAS_EXTERN_TEMPLATE

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template class ::std::vector< ::iutest::TestEventListener* >;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#endif

namespace iutest
{

/**
 * @brief	イベントリスナー
*/
class TestEventListener
{
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TestEventListener);
public:
	TestEventListener(void) {}
	virtual ~TestEventListener(void)	{}
public:
	virtual void OnTestProgramStart(const UnitTest& test)			= 0;	//!< テストプログラム開始時に呼ばれます
	virtual void OnTestIterationStart(const UnitTest& test
									, int iteration)				= 0;	//!< 単体テスト開始時に毎回呼ばれます
	virtual void OnEnvironmentsSetUpStart(const UnitTest& test)		= 0;	//!< グローバル環境設定 SetUp 前に呼ばれます
	virtual void OnEnvironmentsSetUpEnd(const UnitTest& test)		= 0;	//!< グローバル環境設定 SetUp 後に呼ばれます
	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& ) {}	//!< RecordProperty 時に呼ばれます
	virtual void OnTestEnd(const TestInfo& test_info)				= 0;	//!< テストケース終了時にに呼ばれます
	virtual void OnTestCaseEnd(const TestCase& test_case)			= 0;	//!< テスト終了時にに呼ばれます
	virtual void OnEnvironmentsTearDownStart(const UnitTest& test)	= 0;	//!< グローバル環境設定 TearDown 前に呼ばれます
	virtual void OnEnvironmentsTearDownEnd(const UnitTest& test)	= 0;	//!< グローバル環境設定 TearDown 前に呼ばれます
	virtual void OnTestIterationEnd(const UnitTest& test
									, int iteration)				= 0;	//!< 単体テスト終了時に毎回呼ばれます
	virtual void OnTestProgramEnd(const UnitTest& test)				= 0;	//!< テストプログラム終了時に呼ばれます
};

/**
 * @brief	空のイベントリスナー
*/
class EmptyTestEventListener : public TestEventListener
{
public:
	virtual void OnTestProgramStart(const UnitTest& )			IUTEST_CXX_OVERRIDE	{}
	virtual void OnTestIterationStart(const UnitTest& 
									, int )				IUTEST_CXX_OVERRIDE	{}
	virtual void OnEnvironmentsSetUpStart(const UnitTest& )		IUTEST_CXX_OVERRIDE	{}
	virtual void OnEnvironmentsSetUpEnd(const UnitTest& )		IUTEST_CXX_OVERRIDE	{}
	virtual void OnTestCaseStart(const TestCase& )			IUTEST_CXX_OVERRIDE	{}
	virtual void OnTestStart(const TestInfo& )				IUTEST_CXX_OVERRIDE	{}
	virtual void OnTestPartResult(const TestPartResult& ) IUTEST_CXX_OVERRIDE	{}
	virtual void OnTestRecordProperty(const TestProperty& ) IUTEST_CXX_OVERRIDE	{}
	virtual void OnTestEnd(const TestInfo& )				IUTEST_CXX_OVERRIDE	{}
	virtual void OnTestCaseEnd(const TestCase& )			IUTEST_CXX_OVERRIDE	{}
	virtual void OnEnvironmentsTearDownStart(const UnitTest& )	IUTEST_CXX_OVERRIDE	{}
	virtual void OnEnvironmentsTearDownEnd(const UnitTest& )	IUTEST_CXX_OVERRIDE	{}
	virtual void OnTestIterationEnd(const UnitTest& 
									, int )				IUTEST_CXX_OVERRIDE	{}
	virtual void OnTestProgramEnd(const UnitTest& )				IUTEST_CXX_OVERRIDE	{}
};

/**
 * @brief	イベント実行イベントリスナー
*/
class TestEventRepeater : public TestEventListener
{
	typedef ::std::vector<TestEventListener*> ListenerContainer;
public:
	/**
	 * @brief	リスナーの追加
	*/
	void Append(TestEventListener* listener)
	{
		m_listeners.push_back(listener);
	};

	/**
	 * @brief	リスナーの解放
	*/
	TestEventListener* Release(TestEventListener* listener);

public:
	// On*End は後ろから実行
	virtual void OnTestProgramStart(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnTestIterationStart(const UnitTest& test
									, int iteration) IUTEST_CXX_OVERRIDE;
	virtual void OnEnvironmentsSetUpStart(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnEnvironmentsSetUpEnd(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnTestCaseStart(const TestCase& test_case) IUTEST_CXX_OVERRIDE;
	virtual void OnTestStart(const TestInfo& test_info) IUTEST_CXX_OVERRIDE;
	virtual void OnTestPartResult(const TestPartResult& test_part_result) IUTEST_CXX_OVERRIDE;
	virtual void OnTestRecordProperty(const TestProperty& test_property) IUTEST_CXX_OVERRIDE;
	virtual void OnTestEnd(const TestInfo& test_info) IUTEST_CXX_OVERRIDE;
	virtual void OnTestCaseEnd(const TestCase& test_case) IUTEST_CXX_OVERRIDE;
	virtual void OnEnvironmentsTearDownStart(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnEnvironmentsTearDownEnd(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnTestIterationEnd(const UnitTest& test
									, int iteration) IUTEST_CXX_OVERRIDE;
	virtual void OnTestProgramEnd(const UnitTest& test) IUTEST_CXX_OVERRIDE;

private:
	ListenerContainer m_listeners;
};

/**
 * @brief	イベントリスナーの管理クラス
*/
class TestEventListeners
{
	typedef ::std::vector<TestEventListener*> ListenerContainer;

public:
	TestEventListeners(void) : m_default_result_printer(NULL), m_default_xml_generator(NULL) {}

public:
	/**
	 * @brief	リスナーの追加
	*/
	void Append(TestEventListener* listener) { m_repeater.Append(listener); };

	/**
	 * @brief	リスナーの解放
	*/
	TestEventListener* Release(TestEventListener* listener) { return m_repeater.Release(listener); }

public:
	/**
	 * @brief	デフォルト出力リスナーの取得
	*/
	TestEventListener* default_result_printer(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_default_result_printer; }
	/**
	 * @brief	デフォルトxml出力リスナー取得
	*/
	TestEventListener* default_xml_generator(void)  const IUTEST_CXX_NOEXCEPT_SPEC { return m_default_xml_generator; }

private:
	TestEventListener* repeater(void) { 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 DefalutResultPrintListener;

	TestEventRepeater	m_repeater;
	TestEventListener*	m_default_result_printer;
	TestEventListener*	m_default_xml_generator;
};

}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_listener.ipp
 * @brief		iris unit test イベントリスナー 定義 ファイル
 *
 * @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_LISTENER_IPP_C94B8142_F8B3_413F_B479_8AA2B78604CE_
#define INCG_IRIS_IUTEST_LISTENER_IPP_C94B8142_F8B3_413F_B479_8AA2B78604CE_

//======================================================================
// include

namespace iutest
{

IUTEST_IPP_INLINE TestEventListener* TestEventRepeater::Release(TestEventListener* listener)
{
	ListenerContainer::iterator it = ::std::find(m_listeners.begin(), m_listeners.end(), listener);
	if( it == m_listeners.end() ) return NULL;
	m_listeners.erase(it);
	return listener;
}

IUTEST_IPP_INLINE void TestEventRepeater::OnTestProgramStart(const UnitTest& test)
{
	for( ListenerContainer::iterator it=m_listeners.begin(), end=m_listeners.end(); it != end; ++it )
	{
		(*it)->OnTestProgramStart(test);
	}
}
IUTEST_IPP_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);
	}
}
IUTEST_IPP_INLINE void TestEventRepeater::OnEnvironmentsSetUpStart(const UnitTest& test)
{
	for( ListenerContainer::iterator it=m_listeners.begin(), end=m_listeners.end(); it != end; ++it )
	{
		(*it)->OnEnvironmentsSetUpStart(test);
	}
}
IUTEST_IPP_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);
	}
}

IUTEST_IPP_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);
	}
}
IUTEST_IPP_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);
	}
}
IUTEST_IPP_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);
	}
}
IUTEST_IPP_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);
	}
}
IUTEST_IPP_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);
	}
}
IUTEST_IPP_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);
	}
}

IUTEST_IPP_INLINE void TestEventRepeater::OnEnvironmentsTearDownStart(const UnitTest& test)
{
	for( ListenerContainer::iterator it=m_listeners.begin(), end=m_listeners.end(); it != end; ++it )
	{
		(*it)->OnEnvironmentsTearDownStart(test);
	}
}
IUTEST_IPP_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);
	}
}
IUTEST_IPP_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);
	}
}
IUTEST_IPP_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);
	}
}

IUTEST_IPP_INLINE void TestEventListeners::set_default_result_printer(TestEventListener* listener)
{
	delete Release(m_default_result_printer);
	if( listener != NULL )
	{
		Append(listener);
	}
	m_default_result_printer = listener;
}
IUTEST_IPP_INLINE void TestEventListeners::set_default_xml_generator(TestEventListener* listener)
{
	delete Release(m_default_xml_generator);
	if( listener != NULL )
	{
		Append(listener);
	}
	m_default_xml_generator = listener;
}

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_LISTENER_IPP_C94B8142_F8B3_413F_B479_8AA2B78604CE_
#endif

#endif // INCG_IRIS_IUTEST_LISTENER_HPP_C94B8142_F8B3_413F_B479_8AA2B78604CE_

//======================================================================
// define
/**
 * @ingroup	IUTEST_UTIL
 * @brief	フラグセット
 * @details	指定可能なフラグ\n
 *			shuffle (bool)\n
 *			also_run_disabled_tests (bool)\n
 *			break_on_failure (bool)\n
 *			throw_on_failure (bool)\n
 *			catch_exceptions (bool)\n
 *			catch_exceptions_each   (bool)\n
 *			catch_exceptions_global (bool)\n
 *			random_seed (unsigned int)\n
 *			print_time (bool)\n
 *          color (string)\n
 *          filter (string)\n
 *          flagfile (string)\n
 *          output (string)\n
 *          repeat (int)\n
 *			list_tests (bool)\n
 *			list_tests_with_where (bool)\n
 *			verbose (bool)\n
 *			file_location_style_msvc (bool)\n
 *			default_package_name (string)\n
 *			ostream_formatter (ostream)\n
*/
#define IUTEST_FLAG(name)	IIUT_FLAG(name)

/**
 * @private
 * @{
*/
#define IIUT_FLAG(name)		TestEnv::name()

/**
 * @}
*/

#if IUTEST_HAS_LIB && IUTEST_HAS_EXTERN_TEMPLATE

namespace iutest { class Environment; }

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template class ::std::vector< ::iutest::Environment* >;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#endif

namespace iutest
{

//======================================================================
// function
/**
 * @brief	環境変数の取得
*/
inline ::std::string EnvironmentString(const char* name)
{
	::std::string var;
	detail::GetEnvironmentVariable(name, var);
	return var;
}

//======================================================================
// class
/**
 * @brief	環境セットクラス
*/
class Environment
{
public:
	virtual ~Environment(void)	{ Release(); }
	virtual void SetUp(void)	{}	//!< 事前処理
	virtual void TearDown(void)	{}	//!< 事後処理
private:
	void Release(void);
private:
	struct should_be_SetUp {};
	virtual should_be_SetUp* Setup(void) IUTEST_CXX_FINAL { return NULL; }
};

/**
 * @brief	テストフラグ
*/
class TestFlag
{
public:
	/**
	 * @brief	テストフラグ保存/復元クラス
	 * @private
	*/
	class ScopedGuard
	{
		IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(ScopedGuard);

		int m_test_flags;
	public:
		ScopedGuard(void)
		{
			m_test_flags = TestFlag::GetInstance().m_test_flags;
		}
		~ScopedGuard(void)
		{
			TestFlag::GetInstance().m_test_flags = m_test_flags;
		}
	};
public:
	/**
	 * @brief	フラグ
	*/
	enum Kind
#if IUTEST_HAS_STRONG_ENUMS
		: unsigned int
#endif
	{
		SHUFFLE_TESTS			= 0x00000001,	//!< シャッフルテスト
		RUN_DISABLED_TESTS		= 0x00000002,	//!< DISABLED テストも実行
		FILTERING_TESTS			= 0x00000004,	//!< テストのフィルタリング

		BREAK_ON_FAILURE		= 0x00000010,	//!< テスト失敗時にブレーク
		THROW_ON_FAILURE		= 0x00000040,	//!< 致命的な失敗時に throw する

		CONSOLE_COLOR_ON		= 0x00000100,	//!< 色つき出力ON
		CONSOLE_COLOR_OFF		= 0x00000200,	//!< 色つき出力OFF
		CONSOLE_COLOR_ANSI		= 0x00000400,	//!< エスケープシーケンスで出力

		PRINT_TIME				= 0x00001000,	//!< 経過時間の出力
		FILELOCATION_STYLE_MSVC	= 0x00002000,	//!< ファイル/行出力スタイルを Visual Studio スタイルにする
		VERBOSE					= 0x00004000,	//!< verbose

		CATCH_EXCEPTION_EACH	= 0x00010000,	//!< 例外を catch する(TestInfo)
		CATCH_EXCEPTION_GLOBAL	= 0x00020000,	//!< 例外を catch する(UnitTest)
		CATCH_EXCEPTION			= 0x00030000,	//!< 例外を catch する

		SHOW_TESTS_LIST			= 0x02000000,	//!< テストのリスト表示
		SHOW_TESTS_LIST_WITH_WHERE
								= 0x04000000,	//!< テストのリスト表示(with where)

		SHOW_HELP				= 0x10000000,	//!< ヘルプ表示
		SHOW_VERSION			= 0x20000000,	//!< バージョン表示
		SHOW_FEATURE			= 0x40000000,	//!< 機能の出力
		SHOW_SPEC				= 0x80000000,	//!< Specの出力
		SHOW_MASK				= 0xFF000000,	//!< 機能表示系マスク
		MASK					= 0xFFFFFFFF,	//!< マスク

		//! デフォルト
#if defined(_MSC_VER)
		DEFAULT = CATCH_EXCEPTION|PRINT_TIME|FILELOCATION_STYLE_MSVC
#else
		DEFAULT = CATCH_EXCEPTION|PRINT_TIME
#endif
	};

private:
	TestFlag(void) IUTEST_CXX_NOEXCEPT_SPEC
		: m_test_flags(DEFAULT) {}

public:
	
	static TestFlag& GetInstance(void) { static TestFlag flag; return flag; }
public:
	/**
	 * @brief	フラグのビット操作
	 * @details	flag = (flag | enable) & mask;
	 * @param [in]	enable	= 論理和
	 * @param [in]	mask	= マスク値
	*/
	static void SetFlag(int enable, int mask=-1) { GetInstance().m_test_flags |= enable; GetInstance().m_test_flags &= mask; }
	/**
	 * @brief	フラグが立っているかどうか
	 * @param [in]	flag	= 検査対象フラグ
	 * @return	真偽値
	*/
	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(void) IUTEST_CXX_NOEXCEPT_SPEC {}
		Fragment(bool f) { SetFlag(KIND, f ? -1 : ~KIND); }
		_Myt& operator = (bool f) { SetFlag(KIND, f ? -1 : ~KIND); return *this; }
		operator bool (void) const { return IsEnableFlag(KIND); }
	};

private:
	friend class TestEnv;
#if defined(IUTEST_NO_PRIVATE_IN_AGGREGATE)
	friend class ScopedGuard;
#endif

	int m_test_flags;
};

// declare
class TestPartResultReporterInterface;

/**
 * @brief	テスト環境
*/
class TestEnv
{
	typedef ::std::vector<Environment*> iuEnvironmentList;

public:
	/**
	 * @private
	 * @{
	*/
	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_failure;
	typedef TestFlag::Fragment<TestFlag::CATCH_EXCEPTION>		catch_exceptions;
	typedef TestFlag::Fragment<TestFlag::THROW_ON_FAILURE>		throw_on_failure;
	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;

	/**
	 * @}
	*/

	/**
	 * @private
	 * @brief	乱数シード設定用オブジェクト
	*/
	typedef class RandomSeedSet
	{
	public:
		RandomSeedSet(void) IUTEST_CXX_NOEXCEPT_SPEC {}
		RandomSeedSet(unsigned int seed) { init_random(seed); }
		RandomSeedSet& operator = (unsigned int seed) { init_random(seed); return *this; }
		operator unsigned int (void) const { return get_random_seed(); }
	} random_seed;

	/**
	 * @private
	 * @brief	リピート回数設定用オブジェクト
	*/
	typedef class RepeatCountSet
	{
	public:
		RepeatCountSet(void) IUTEST_CXX_NOEXCEPT_SPEC {}
		RepeatCountSet(int count) { set_repeat_count(count); }
		RepeatCountSet& operator = (int count) { set_repeat_count(count); return *this; }
		operator int (void) const { return get_repeat_count(); }
	} repeat;

#if defined(IUTEST_NO_PRIVATE_IN_AGGREGATE)
	friend class RandomSeedSet;
	friend class RepeatCountSet;
#endif

private:
	struct Variable
	{
		Variable(void)
			: m_random_seed(0)
			, m_current_random_seed(0)
			, m_before_origin_random_seed(0)
			, m_repeat_count(1)
			, m_testpartresult_reporter(NULL)
		{}
		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;
#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
		iu_stringstream		m_ostream_formatter;
#endif
	};

	static Variable& get_vars(void) { static Variable v; return v; }

public:

	static detail::iuRandom&	genrand(void)				{ return get_vars().m_genrand; }				//!< 乱数生成器
	static unsigned int			get_random_seed(void)		{ return get_vars().m_random_seed; }			//!< 乱数シード
	static unsigned int			current_random_seed(void)	{ return get_vars().m_current_random_seed; }	//!< 乱数シード
	static int					get_repeat_count(void)		{ return get_vars().m_repeat_count; }			//!< 繰り返し回数
	static const char*			get_output_option(void)		{ return get_vars().m_output_option.c_str(); }	//!< 出力オプション
	static const char*			get_default_package_name(void) { return get_vars().m_default_package_name.c_str(); }	//!< root package オプション
	static const char*			test_filter(void)			{ return get_vars().m_test_filter.c_str(); }	//!< フィルター文字列
	static const char*			get_flagfile(void)			{ return get_vars().m_flagfile.c_str(); }		//!< flag file
#if IUTEST_HAS_STREAM_RESULT
	static const char*			get_stream_result_to(void)	{ return get_vars().m_stream_result_to.c_str(); }
#endif
#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
	static void					global_ostream_copyfmt(iu_ostream& os) { os.copyfmt(get_vars().m_ostream_formatter); }
#endif

	/**
	 * @brief	xml 出力パスを取得
	*/
	static ::std::string get_report_xml_filepath(void);
	/**
	 * @brief	junit xml 出力パスを取得
	*/
	static ::std::string get_report_junit_xml_filepath(void);

	
	static TestEventListeners& event_listeners(void) { return get_vars().m_event_listeners; }
	
	static TestPartResultReporterInterface* GetGlobalTestPartResultReporter(void) { return get_vars().m_testpartresult_reporter; }
	
	static void SetGlobalTestPartResultReporter(TestPartResultReporterInterface* ptr) { get_vars().m_testpartresult_reporter = ptr; }

private:
	/**
	 * @brief	乱数シードの設定
	*/
	static void init_random(unsigned int seed)
	{
		get_vars().m_random_seed = seed;
	}

	/**
	 * @brief	繰り返し回数の設定
	*/
	static void set_repeat_count(int count)
	{
		get_vars().m_repeat_count = count;
	}

	/**
	 * @brief	フィルター文字列の設定
	*/
	static void set_test_filter(const char* str)
	{
		get_vars().m_test_filter = str == NULL ? "*" : str;
		TestFlag::SetFlag(TestFlag::FILTERING_TESTS);
	}

	/**
	 * @brief	flagfile の設定
	*/
	static void set_flagfile_path(const char* str)
	{
		get_vars().m_flagfile = str;
	}

	/**
	 * @brief	flagfile の設定
	*/
	static void set_flagfile(const char* str)
	{
		ParseFlagFileOption(str);
		LoadFlagFile();
	}

#if IUTEST_HAS_STREAM_RESULT
	/**
	 * @brief	stream result の設定
	*/
	static void set_stream_result_to(const char* str)
	{
		get_vars().m_stream_result_to = str == NULL ? "" : str;
	}
#endif

	/**
	 * @brief	color オプション文字列を取得
	*/
	static const char* get_color_option(void)
	{
		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";
	}
	/**
	 * @brief	color オプションを設定
	*/
	static void set_color_option(const char* str)
	{
		ParseColorOption(str);
	}

	/**
	 * @brief	output オプションを設定
	*/
	static void set_output_option(const char* str)
	{
		get_vars().m_output_option = str == NULL ? "" : str;
	}

	/**
	* @brief	default_package_name オプションを設定
	*/
	static void set_default_package_name(const char* str)
	{
		get_vars().m_default_package_name = str == NULL ? "" : str;
	}

private:
	typedef const char* (*pfnOptionStringGet)();
	typedef void(*pfnOptionStringSet)(const char*);
	template<pfnOptionStringGet G, pfnOptionStringSet S>
	class OptionString
	{
		typedef OptionString<G, S> _Myt;
	protected:
		::std::string m_option;
	public:
		friend bool operator == (const char* c_str_, const _Myt& rhs)		{ return rhs.m_option == c_str_; }
		friend bool operator == (const ::std::string& str, const _Myt& rhs)	{ return rhs.m_option == str; }
		friend bool operator == (const _Myt& lhs, const char* c_str_)		{ return lhs.m_option == c_str_; }
		friend bool operator == (const _Myt& lhs, const::std::string& str)	{ return lhs.m_option == str; }
		friend bool operator != (const char* c_str_, const _Myt& rhs)		{ return rhs.m_option != c_str_; }
		friend bool operator != (const ::std::string& str, const _Myt& rhs)	{ return rhs.m_option != str; }
		friend bool operator != (const _Myt& lhs, const char* c_str_)		{ return lhs.m_option != c_str_; }
		friend bool operator != (const _Myt& lhs, const ::std::string& str)	{ return lhs.m_option != str; }

		operator ::std::string (void) const { return m_option; }
	public:
		bool empty(void) const			{ return m_option.empty(); }
		const char* c_str(void) const	{ return m_option.c_str(); }
		size_t length(void) const		{ return m_option.length(); }
	public:
		OptionString(void)
			: m_option(G())
		{
		}
		const _Myt& operator = (const char* c_str_)
		{
			m_option = c_str_ == NULL ? "" : c_str_;
			S(c_str_);
			return *this;
		}
		const _Myt& operator = (const ::std::string& str)
		{
			m_option = str;
			S(str.c_str());
			return *this;
		}
	};

public:
	/**
	 * @private
	 * @brief	色付き出力オプション設定用オブジェクト
	*/
	typedef OptionString<get_color_option, set_color_option> color;

	/**
	 * @private
	 * @brief	フィルターオプション設定用オブジェクト
	*/
	typedef OptionString<test_filter, set_test_filter> filter;

	/**
	 * @private
	 * @brief	フィルターオプション設定用オブジェクト
	*/
	typedef OptionString<get_flagfile, set_flagfile> flagfile;

	/**
	 * @private
	 * @brief	出力オプション設定用オブジェクト
	*/
	typedef OptionString<get_output_option, set_output_option> output;

#if IUTEST_HAS_STREAM_RESULT
	/**
	 * @private
	 * @brief	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;

#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
	typedef class OStreamFormatter : public iu_stringstream
	{
		IUTEST_WORKAROUND_MSC_STLSTREAM_C4250()
	public:
		OStreamFormatter(void)
		{
			copyfmt(get_vars().m_ostream_formatter);
		}
		virtual ~OStreamFormatter(void)
		{
			get_vars().m_ostream_formatter.copyfmt(*this);
		}
	} ostream_formatter;

#if defined(IUTEST_NO_PRIVATE_IN_AGGREGATE)
	friend class OStreamFormatter;
#endif

#endif

private:
	static iuEnvironmentList& environments(void) { return get_vars().m_environment_list; }

public:
	/**
	 * @brief	グローバル環境セットクラスの追加
	 * @param [in]	env	= 環境セットクラスアドレス
	 * @return	登録されたクラスアドレス
	*/
	static Environment* AddGlobalTestEnvironment(Environment* env)
	{
		if( env == NULL )
		{
			return NULL;
		}
		environments().push_back(env);
		return env;
	}
	
	/**
	 * @brief	グローバル環境セットクラスの削除
	 * @param [in]	env	= 環境セットクラスアドレス
	 * @return	削除されたクラスアドレス
	*/
	static Environment* ReleaseGlobalTestEnvironment(Environment* env)
	{
		if( env == NULL )
		{
			return NULL;
		}
		iuEnvironmentList& list = environments();
		iuEnvironmentList::iterator it = ::std::find(list.begin(), list.end(), env);
		if( it == list.end() ) return NULL;
		list.erase(it);
		return env;
	}

	/**
	 * @brief	default package name を追加
	*/
	static ::std::string AddDefaultPackageName(const char* testcase_name);

private:
	/**
	 * @brief	環境セットクラスの解放
	*/
	static void ReleaseGlobalTestEnvironment(void)
	{
		// すべて解放する
		for( iuEnvironmentList::iterator it=environments().begin(); it != environments().end(); )
		{
			Environment* p = *it;
			it = environments().erase(it);
			delete p;
		}
	}

public:
	/**
	 * @private
	 * @brief	コマンドライン引数の解析
	*/
	template<typename CharType>
	static void ParseCommandLine(int* pargc, CharType** argv)
	{
		if( argv == NULL ) 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;
	}

	/**
	 * @private
	 * @brief	コマンドライン引数の解析(vector)
	*/
	template<typename CharType>
	static void ParseCommandLine(::std::vector< ::std::basic_string<CharType> >& argv)
	{
		for( typename ::std::vector< ::std::basic_string<CharType> >::iterator it = argv.begin(); it != argv.end(); )
		{
			if( ParseCommandLineElem(it->c_str()) )
			{
				it = argv.erase(it);
			}
			else
			{
				++it;
			}
		}
	}

	
	static bool LoadFlagFile(void);

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);

private:
	/**
	 * @brief	環境変数から設定構築
	*/
	static void LoadEnviromentVariable(void);

	/**
	 * @brief	セットアップ
	*/
	static void SetUp(void);

private:
	/**
	 * @brief	オプション文字列から設定文字列の先頭アドレスを取得
	*/
	static inline const char* ParseOptionSettingStr(const char* opt)
	{
		const char* eq = strchr(opt, '=');
		if( eq == NULL )
		{
			return NULL;
		}
		return eq+1;
	}
	/**
	 * @brief	IUTEST_COLOR オプションの判定
	*/
	static bool ParseColorOption(const char* option);

	/**
	 * @brief	IUTEST_OUTPUT オプションの判定
	*/
	static bool ParseOutputOption(const char* option);

	/**
	 * @brief	IUTEST_FILE_LOCATION オプションの判定
	*/
	static bool ParseFileLocationOption(const char* option);

	/**
	 * @brief	IUTEST_FILTER オプションの判定
	*/
	static bool ParseFilterOption(const char* option);

	/**
	 * @brief	IUTEST_FLAGFILE オプションの判定
	*/
	static bool ParseFlagFileOption(const char* option);

	/**
	 * @brief	yes オプションか no オプションかの判定
	 * @param [in]	str		= コマンドライン文字列（関数ないでオプション文字列部分を取得する）
	 * @param [in]	flag	= フラグ
	 * @param [in]	def		= 引数なしの場合のオペレーション
	 * @return	成否
	*/
	static bool ParseYesNoFlagCommandLine(const char* str, TestFlag::Kind flag, int def);

	/**
	 * @brief	yes オプションか no オプションかの判定
	 * @param [in]	option	= オプション文字列
	 * @retval	< 0	= 該当なし
	 * @retval	0	= NO
	 * @retval	> 0 = YES
	*/
	static int ParseYesNoOption(const char* option);

	/**
	 * @brief	yes オプションか判定
	*/
	static bool IsYes(const char* option);
	/**
	 * @brief	no オプションか判定
	*/
	static bool IsNo(const char* option);

private:
	friend class UnitTest;
};

class iu_global_format_stringstream : public iu_stringstream
{
	IUTEST_WORKAROUND_MSC_STLSTREAM_C4250()
public:
	iu_global_format_stringstream()
	{
#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
		TestEnv::global_ostream_copyfmt(*this);
#endif
	}
	iu_global_format_stringstream(const char* str)
		: iu_stringstream(str)
	{
#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
		TestEnv::global_ostream_copyfmt(*this);
#endif
	}
	iu_global_format_stringstream(const ::std::string& str)
		: iu_stringstream(str)
	{
#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
		TestEnv::global_ostream_copyfmt(*this);
#endif
	}
};

}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_env.ipp
 * @brief		iris unit test 環境 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_ENV_IPP_F4017EAB_6CA3_4E6E_8983_059393DADD04_
#define INCG_IRIS_IUTEST_ENV_IPP_F4017EAB_6CA3_4E6E_8983_059393DADD04_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_file.hpp
 * @brief		iris unit test ファイルクラス ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_FILE_HPP_77D2C2B9_F504_4BB5_BA56_D97A2EB37DC6_
#define INCG_IRIS_IUTEST_FILE_HPP_77D2C2B9_F504_4BB5_BA56_D97A2EB37DC6_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_stream.hpp
 * @brief		iris unit test io stream
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_STREAM_HPP_3A4AF139_9F24_4730_81D0_DADFCE6DCF99_
#define INCG_IRIS_IUTEST_STREAM_HPP_3A4AF139_9F24_4730_81D0_DADFCE6DCF99_

namespace iutest {
namespace detail
{

//======================================================================
// class
/**
 * @brief	出力ストリームインターフェイス
*/
class IOutStream
{
public:
	virtual ~IOutStream(void) {}
public:
	//! 書き込み
	virtual bool Write(const void* buf, size_t size, size_t cnt) = 0;
public:
	virtual void Printf(const char* fmt, ...)
	{
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

		// TODO : Fixed buffer...
		char buf[1024] = {0};
		va_list va;
		va_start(va, fmt);
#if defined(_MSC_VER)
#  if IUTEST_HAS_WANT_SECURE_LIB
		const int len = _vsnprintf_s(buf, _TRUNCATE, fmt, va);
#  else
		const int len = _vsnprintf(buf, sizeof(buf)-1, fmt, va);
#  endif
#else
#if defined(__STRICT_ANSI__)
		const int len = vsprintf(buf, fmt, va);
#else
		const int len = vsnprintf(buf, sizeof(buf), fmt, va);
#endif
#endif
		va_end(va);

		if( len > 0 )
		{
			Write(buf, static_cast<size_t>(len), 1);
		}

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
	}
};

/**
 * @brief	入力ストリームインターフェイス
*/
class IInStream
{
public:
	virtual ~IInStream(void) {}
public:
	//! 読み込み
	virtual bool Read(void* buf, size_t size, size_t cnt) = 0;

	//! サイズ取得
	virtual size_t GetSize(void) = 0;

public:
	//! 全読み込み
	virtual ::std::string ReadAll(void)
	{
		::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;
	}
};

/**
 * @brief	ファイルIO出力ストリームインターフェイス
*/
class FileOutStream : public IOutStream
{
protected:
	FILE* m_fp;
public:
	FileOutStream(FILE* fp) IUTEST_CXX_NOEXCEPT_SPEC
		: m_fp(fp)
	{}
public:
	/**
	 * @brief	書き込み
	 * @param [in]	buf		= 書き込みバッファ
	 * @param [in]	size	= バッファサイズ
	 * @param [in]	cnt		= 書き込み回数
	*/
	virtual bool Write(const void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
	{
		if( fwrite(buf, size, cnt, m_fp) < cnt ) return false;
		return true;
	}
};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_STREAM_HPP_3A4AF139_9F24_4730_81D0_DADFCE6DCF99_

namespace iutest
{

//======================================================================
// class
/**
 * @brief	ファイルクラスインターフェイス
*/
class IFile : public detail::IOutStream, public detail::IInStream
{
public:
	//! ファイルオープンモードフラグ
	enum OpenFlag
	{
		OpenRead		= 0x00000001,	//!< 読み込み
		OpenWrite		= 0x00000002,	//!< 書き込み
		OpenReadWrite	= 0x00000003	//!< 読み書き
	};
public:
	virtual ~IFile(void) {}
public:
	//! 開く
	virtual bool Open(const char* filename, int mode) = 0;
	//! 閉じる
	virtual void Close(void) = 0;
};

namespace detail
{

/**
 * @brief	ファイル処理クラスインターフェイス
*/
class IFileSystem
{
	template<typename T>
	struct Variable
	{
		static IFileSystem* m_pInstance;
	};

	typedef Variable<void> var;
public:
	IFileSystem(void)
	{
		var::m_pInstance = this;
	}
	virtual ~IFileSystem(void)
	{
		var::m_pInstance = NULL;
	}

public:
	virtual void Initialize(void) {}

public:
	static IFileSystem* GetInstance(void) { return var::m_pInstance; }

public:
	static IFile* New(void)
	{
		IFileSystem* fs = GetInstance();
		if( fs == NULL )
		{
			return NULL;
		}
		IFile* p = fs->Create();
		return p;
	}
	static void Free(IFile* ptr)
	{
		IFileSystem* fs = GetInstance();
		if( fs == NULL )
		{
			return;
		}
		fs->Delete(ptr);
	}

	static bool ReadAll(const char* filename, ::std::string& dst)
	{
		IFile* fp = detail::IFileSystem::New();
		if(fp == NULL)
		{
			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(void) = 0;
	virtual void	Delete(IFile*) = 0;
};

}	// end of namespace detail
}	// end of namespace iutest

template<typename T>
::iutest::detail::IFileSystem* ::iutest::detail::IFileSystem::Variable<T>::m_pInstance = NULL;

namespace iutest
{

/**
 * @brief	ファイル処理クラスインターフェイス
*/
template<typename FILE>
class FileSystem : public detail::IFileSystem
{
private:
	virtual IFile*	Create(void) IUTEST_CXX_OVERRIDE		{ return new FILE; }
	virtual void	Delete(IFile* ptr) IUTEST_CXX_OVERRIDE	{ detail::Delete<FILE>(static_cast<FILE*>(ptr)); }
};


#if IUTEST_HAS_FOPEN

/**
 * @brief	標準ファイルクラス
*/
class StdioFile : public IFile
{
	FILE* m_fp;
public:
	StdioFile(void) IUTEST_CXX_NOEXCEPT_SPEC : m_fp(NULL) {}
	virtual ~StdioFile(void) { Close(); }
public:
	/**
	 * @brief	開く
	 * @param [in]	filename	= ファイルパス
	 * @param [in]	mode		= モード
	 * @return	成否
	*/
	virtual bool Open(const char* filename, int mode) IUTEST_CXX_OVERRIDE
	{
		Close();
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
		switch( mode )
		{
		case IFile::OpenRead:
			m_fp = fopen(filename, "rb");
			break;
		case IFile::OpenWrite:
			m_fp = fopen(filename, "wb");
			break;
		case IFile::OpenReadWrite:
			m_fp = fopen(filename, "ab");
			break;
		default:
			break;
		}
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
		return m_fp != NULL;
	}
	/**
	 * @brief	閉じる
	*/
	virtual void Close(void) IUTEST_CXX_OVERRIDE
	{
		if( m_fp != NULL )
		{
			fclose(m_fp);
			m_fp = NULL;
		}
	}
	/**
	 * @brief	書き込み
	 * @param [in]	buf		= 書き込みバッファ
	 * @param [in]	size	= バッファサイズ
	 * @param [in]	cnt		= 書き込み回数
	*/
	virtual bool Write(const void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
	{
		if( fwrite(buf, size, cnt, m_fp) < cnt )
		{
			return false;
		}
		return true;
	}

	/**
	 * @brief	読み込み
	 * @param [in]	buf		= 読み込みバッファ
	 * @param [in]	size	= 読み込みデータサイズ
	 * @param [in]	cnt		= 読み込み回数
	*/
	virtual bool Read(void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
	{
		if( fread(buf, size, cnt, m_fp) < cnt ) return false;
		return true;
	}

	//! サイズ取得
	virtual size_t GetSize(void) IUTEST_CXX_OVERRIDE
	{
		if(m_fp == NULL) return 0;
		const long pre = ftell(m_fp);
		if(pre == -1) return 0;
		if(fseek(m_fp, 0, SEEK_END) != 0) return 0;
		const size_t size = static_cast<size_t>(ftell(m_fp));
		fseek(m_fp, pre, SEEK_SET);
		return size;
	}
};

#endif

#if IUTEST_HAS_STRINGSTREAM

/**
 * @brief	文字列バッファ書き込み IFile インターフェースクラス
*/
class StringStreamFile : public IFile
{
public:
	virtual ~StringStreamFile(void) { Close(); }
public:
	/**
	 * @brief	開く
	 * @return	成否
	*/
	virtual bool Open(const char* , int ) IUTEST_CXX_OVERRIDE
	{
		ss.clear();
		return true;
	}

	/**
	 * @brief	閉じる
	*/
	virtual void Close(void) IUTEST_CXX_OVERRIDE
	{
	}

	/**
	 * @brief	書き込み
	 * @param [in]	buf		= 書き込みバッファ
	 * @param [in]	size	= バッファサイズ
	 * @param [in]	cnt		= 書き込み回数
	*/
	virtual bool Write(const void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
	{
		for( size_t i=0; i < cnt; ++i )
		{
			ss.write(static_cast<const char*>(buf), size);
		}
		return true;
	}

	/**
	 * @brief	読み込み
	 * @param [in]	buf		= 読み込みバッファ
	 * @param [in]	size	= 読み込みデータサイズ
	 * @param [in]	cnt		= 読み込み回数
	*/
	virtual bool Read(void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
	{
		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(void) IUTEST_CXX_OVERRIDE
	{
		::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(void) IUTEST_CXX_OVERRIDE
	{
		return ss.str();
	}
protected:
	::std::stringstream ss;
};

#endif

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_FILE_HPP_77D2C2B9_F504_4BB5_BA56_D97A2EB37DC6_

namespace iutest
{

IUTEST_IPP_INLINE void Environment::Release()
{
	TestEnv::ReleaseGlobalTestEnvironment(this);
}

IUTEST_IPP_INLINE ::std::string TestEnv::get_report_xml_filepath(void)
{
	const ::std::string& option = get_vars().m_output_option;
	if(option.find("xml") != ::std::string::npos)
	{
		const ::std::string::size_type pos = option.find("xml:");
		if(pos != ::std::string::npos
			&& option.length() > pos + 4)
		{
			return option.substr(pos + 4);
		}
		return detail::kStrings::DefaultXmlReportFileName;
	}
	return "";
}

IUTEST_IPP_INLINE::std::string TestEnv::get_report_junit_xml_filepath(void)
{
	const ::std::string& option = get_vars().m_output_option;
	if( option.find("junit") != ::std::string::npos )
	{
		const ::std::string::size_type pos = option.find("junit:");
		if( pos != ::std::string::npos )
		{
			return option.substr(pos + 6);
		}
		return detail::kStrings::DefaultXmlReportFileName;
	}
	return "";
}

IUTEST_IPP_INLINE::std::string TestEnv::AddDefaultPackageName(const char* testcase_name)
{
	::std::string str = TestEnv::get_default_package_name();
	if( str.empty() ) return testcase_name;
	if( strchr(testcase_name, '.') != NULL ) return testcase_name;

	str += ".";
	str += testcase_name;
	return str;
}

IUTEST_IPP_INLINE bool TestEnv::ParseCommandLineElemA(const char* str)
{
	bool find = false;
	if( *str == '-' )
	{
		find = true;
		++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 )
			{
				// --iutest_*
				if( detail::IsStringForwardMatching(str, "output") )
				{
					find = ParseOutputOption(ParseOptionSettingStr(str));
				}
				else if( detail::IsStringEqual(str, "list_tests") )
				{
					TestFlag::SetFlag(TestFlag::SHOW_TESTS_LIST);
				}
				else if( detail::IsStringEqual(str, "list_tests_with_where") )
				{
					TestFlag::SetFlag(TestFlag::SHOW_TESTS_LIST_WITH_WHERE);
				}
				else if( detail::IsStringForwardMatching(str, "color") )
				{
					find = ParseColorOption(ParseOptionSettingStr(str));
				}
				else if( detail::IsStringEqual(str, "shuffle") )
				{
					TestFlag::SetFlag(TestFlag::SHUFFLE_TESTS);
				}
				else if( detail::IsStringForwardMatching(str, "random_seed") )
				{
					const char* opt = ParseOptionSettingStr(str);
					if( opt != NULL )
					{
						char* end = NULL;
						long seed = strtol(opt, &end, 0);
						init_random(static_cast<unsigned int>(seed));
					}
					else
					{
						find = false;
					}
				}
				else if( detail::IsStringEqual(str, "also_run_disabled_tests") )
				{
					TestFlag::SetFlag(TestFlag::RUN_DISABLED_TESTS);
				}
				else if( detail::IsStringForwardMatching(str, "break_on_failure") )
				{
					find = ParseYesNoFlagCommandLine(str, TestFlag::BREAK_ON_FAILURE, 1);
				}
				else if( detail::IsStringForwardMatching(str, "catch_exceptions") )
				{
					find = ParseYesNoFlagCommandLine(str, TestFlag::CATCH_EXCEPTION, -1);
				}
				else if( detail::IsStringForwardMatching(str, "throw_on_failure") )
				{
					find = ParseYesNoFlagCommandLine(str, TestFlag::THROW_ON_FAILURE, 1);
				}
				else if( detail::IsStringForwardMatching(str, "print_time") )
				{
					find = ParseYesNoFlagCommandLine(str, TestFlag::PRINT_TIME, -1);
				}
				else if( detail::IsStringForwardMatching(str, "repeat") )
				{
					const char* opt = ParseOptionSettingStr(str);
					if( opt != NULL )
					{
						char* end = NULL;
						long count = strtol(opt, &end, 0);
						set_repeat_count(static_cast<int>(count));
					}
					else
					{
						find = false;
					}
				}
				else if(detail::IsStringForwardMatching(str, "filter"))
				{
					ParseFilterOption(ParseOptionSettingStr(str));
				}
				else if(detail::IsStringForwardMatching(str, "flagfile"))
				{
					ParseFlagFileOption(ParseOptionSettingStr(str));
				}
#if IUTEST_HAS_STREAM_RESULT
				else if( detail::IsStringForwardMatching(str, "stream_result_to") )
				{
					const char* opt = ParseOptionSettingStr(str);
					if( opt != NULL )
					{
						set_stream_result_to(opt);
					}
					else
					{
						find = false;
					}
				}
#endif
				else if( detail::IsStringForwardMatching(str, "file_location") )
				{
					find = ParseFileLocationOption(ParseOptionSettingStr(str));
				}
				else if( detail::IsStringForwardMatching(str, "default_package_name") )
				{
					set_default_package_name(ParseOptionSettingStr(str));
				}
				else
				{
					find = false;
				}
				if( !find )
				{
					// 該当するオプションがない場合はヘルプ表示
					TestFlag::SetFlag(TestFlag::SHOW_HELP);
				}
			}
			else if( detail::IsStringEqual(str, "help") )
			{
				TestFlag::SetFlag(TestFlag::SHOW_HELP);
			}
			else if( detail::IsStringEqual(str, "version") )
			{
				TestFlag::SetFlag(TestFlag::SHOW_VERSION);
			}
			else if( detail::IsStringEqual(str, "feature") )
			{
				TestFlag::SetFlag(TestFlag::SHOW_FEATURE);
			}
			else if( detail::IsStringEqual(str, "spec") )
			{
				TestFlag::SetFlag(TestFlag::SHOW_SPEC);
			}
			else if( detail::IsStringEqual(str, "verbose") )
			{
				TestFlag::SetFlag(TestFlag::VERBOSE);
			}
			else
			{
				find = false;
			}
		}
		else
		{
			if( detail::IsStringEqual(str, "v") )
			{
				TestFlag::SetFlag(TestFlag::SHOW_VERSION);
			}
			else if( detail::IsStringEqual(str, "h")
				|| detail::IsStringEqual(str, "?") )
			{
				TestFlag::SetFlag(TestFlag::SHOW_HELP);
			}
			else
			{
				find = false;
			}
		}
	}
	return find;
}

IUTEST_IPP_INLINE void TestEnv::LoadEnviromentVariable(void)
{
	{
		int var = 0;
		if( detail::GetEnvironmentInt("IUTEST_ALSO_RUN_DISABLED_TESTS", var)
		||  detail::GetEnvironmentInt("GTEST_ALSO_RUN_DISABLED_TESTS", var) )
		{
			TestFlag::SetFlag(TestFlag::RUN_DISABLED_TESTS
				, var ? TestFlag::MASK : ~(TestFlag::RUN_DISABLED_TESTS) );
		}
		if( detail::GetEnvironmentInt("IUTEST_SHUFFLE", var)
		||  detail::GetEnvironmentInt("GTEST_SHUFFLE", var) )
		{
			TestFlag::SetFlag(TestFlag::SHUFFLE_TESTS
				, var ? TestFlag::MASK : ~(TestFlag::SHUFFLE_TESTS) );
		}
		if( detail::GetEnvironmentInt("IUTEST_RANDOM_SEED", var)
		||  detail::GetEnvironmentInt("GTEST_RANDOM_SEED", var) )
		{
			init_random((unsigned int)var);
		}
		if( detail::GetEnvironmentInt("IUTEST_CATCH_EXCEPTIONS", var)
		||  detail::GetEnvironmentInt("GTEST_CATCH_EXCEPTIONS", var) )
		{
			TestFlag::SetFlag(TestFlag::CATCH_EXCEPTION
				, var ? TestFlag::MASK : ~(TestFlag::CATCH_EXCEPTION) );
		}
		if( detail::GetEnvironmentInt("IUTEST_BREAK_ON_FAILURE", var)
		||  detail::GetEnvironmentInt("GTEST_BREAK_ON_FAILURE", var) )
		{
			TestFlag::SetFlag(TestFlag::BREAK_ON_FAILURE
				, var ? TestFlag::MASK : ~(TestFlag::BREAK_ON_FAILURE) );
		}
		if( detail::GetEnvironmentInt("IUTEST_THROW_ON_FAILURE", var)
		||  detail::GetEnvironmentInt("GTEST_THROW_ON_FAILURE", var) )
		{
			TestFlag::SetFlag(TestFlag::THROW_ON_FAILURE
				, var ? TestFlag::MASK : ~(TestFlag::THROW_ON_FAILURE) );
		}
		if( detail::GetEnvironmentInt("IUTEST_PRINT_TIME", var)
		||  detail::GetEnvironmentInt("GTEST_PRINT_TIME", var) )
		{
			TestFlag::SetFlag(TestFlag::PRINT_TIME
				, var ? TestFlag::MASK : ~(TestFlag::PRINT_TIME) );
		}
		if( detail::GetEnvironmentInt("IUTEST_REPEAT", var)
		||  detail::GetEnvironmentInt("GTEST_REPEAT", var) )
		{
			set_repeat_count(var);
		}
	}
	{
		char var[128] = {0};
		if( detail::GetEnvironmentVariable("IUTEST_COLOR", var, sizeof(var))
		||  detail::GetEnvironmentVariable("GTEST_COLOR", var, sizeof(var)) )
		{
			ParseColorOption(var);
		}
		if( detail::GetEnvironmentVariable("IUTEST_FILE_LOCATION", var, sizeof(var)) )
		{
			ParseFileLocationOption(var);
		}
	}
	{
		char str[260+32] = {0};
		if( detail::GetEnvironmentVariable("IUTEST_OUTPUT", str, sizeof(str))
		||  detail::GetEnvironmentVariable("GTEST_OUTPUT", str, sizeof(str)) )
		{
			ParseOutputOption(str);
		}
		if( detail::GetEnvironmentVariable("IUTEST_FILTER", str, sizeof(str))
		||  detail::GetEnvironmentVariable("GTEST_FILTER", str, sizeof(str)) )
		{
			ParseFilterOption(str);
		}
		if(detail::GetEnvironmentVariable("IUTEST_DEFAULT_PACKAGE_NAME", str, sizeof(str)))
		{
			set_default_package_name(str);
		}
#if IUTEST_HAS_STREAM_RESULT
		if( detail::GetEnvironmentVariable("IUTEST_STREAM_RESULT_TO", str, sizeof(str))
		||  detail::GetEnvironmentVariable("GTEST_STREAM_RESULT_TO", str, sizeof(str)) )
		{
			set_stream_result_to(str);
		}
#endif
		if(detail::GetEnvironmentVariable("IUTEST_FLAGFILE", str, sizeof(str))
			|| detail::GetEnvironmentVariable("GTEST_FLAGFILE", str, sizeof(str)))
		{
			ParseFlagFileOption(str);
		}
	}
}

IUTEST_IPP_INLINE void TestEnv::SetUp(void)
{
	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);
}

IUTEST_IPP_INLINE bool TestEnv::ParseColorOption(const char* option)
{
	if( option == NULL )
	{
		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") )
	{
		// auto
		TestFlag::SetFlag(0, ~(TestFlag::CONSOLE_COLOR_ON|TestFlag::CONSOLE_COLOR_OFF|TestFlag::CONSOLE_COLOR_ANSI));
	}
	else if( detail::IsStringCaseEqual(option, "ansi") )
	{
		// ansi
		TestFlag::SetFlag(TestFlag::CONSOLE_COLOR_ON|TestFlag::CONSOLE_COLOR_ANSI, ~TestFlag::CONSOLE_COLOR_OFF);
	}
	else
	{
		return false;
	}
	return true;
}

IUTEST_IPP_INLINE bool TestEnv::ParseOutputOption(const char* option)
{
	if(option == NULL)
	{
		get_vars().m_output_option = "";
		return false;
	}
	get_vars().m_output_option = option;
	return true;
}

IUTEST_IPP_INLINE bool TestEnv::ParseFileLocationOption(const char* option)
{
	if( option == NULL )
	{
		return false;
	}

	if( detail::IsStringCaseEqual(option, "auto") )
	{
#if defined(_MSC_VER)
		TestFlag::SetFlag(TestFlag::FILELOCATION_STYLE_MSVC);
#else
		TestFlag::SetFlag(0, ~TestFlag::FILELOCATION_STYLE_MSVC);
#endif
	}
	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;
}

IUTEST_IPP_INLINE bool TestEnv::ParseFilterOption(const char* option)
{
	if( option != NULL && *option == '@' )
	{
		// file
		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;
}

IUTEST_IPP_INLINE bool TestEnv::ParseFlagFileOption(const char* option)
{
	if(option == NULL || option[0] == '\0' ) return false;
	set_flagfile_path(option);
	return true;
}

IUTEST_IPP_INLINE bool TestEnv::LoadFlagFile()
{
	const char* path = get_flagfile();
	if(path == NULL || 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;
}

IUTEST_IPP_INLINE bool TestEnv::ParseYesNoFlagCommandLine(const char* str, TestFlag::Kind flag, int def)
{
	const char* option = ParseOptionSettingStr(str);
	const int yesno = option != NULL ? ParseYesNoOption(option) : def;
	if( yesno < 0 )
	{
		return false;
	}
	TestFlag::SetFlag(flag, yesno ? TestFlag::MASK : ~(flag) );
	return true;
}

IUTEST_IPP_INLINE int TestEnv::ParseYesNoOption(const char* option)
{
	if( option != NULL )
	{
		if( IsYes(option) )
		{
			return 1;
		}
		if( IsNo(option) )
		{
			return 0;
		}
	}

	return -1;
}

IUTEST_IPP_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;
}

IUTEST_IPP_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;
}

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_ENV_IPP_F4017EAB_6CA3_4E6E_8983_059393DADD04_
#endif

#endif // INCG_IRIS_IUTEST_ENV_HPP_F4017EAB_6CA3_4E6E_8983_059393DADD04_

namespace iutest {
namespace detail
{

//======================================================================
// declare
/**
 * @brief	ファイル名と行番号を連結した文字列を生成(コンパイラを考慮する)
*/
::std::string FormatFileLocation(const char* file, int line);
/**
 * @brief	ファイル名と行番号を連結した文字列を生成
*/
::std::string FormatCompilerIndependentFileLocation(const char* file, int line);

//======================================================================
// class
/**
 * @brief	メッセージクラス
*/
class iuStreamMessage
{
public:
	iuStreamMessage(void) {}
	explicit iuStreamMessage(const char* message) : m_stream(message) {}
	iuStreamMessage(const iuStreamMessage& rhs) : m_stream(rhs.GetString()) {}

public:
	::std::string GetString(void) const { return m_stream.str(); }
public:
	template<typename T>
	iuStreamMessage& operator << (const T& value)
	{
		m_stream << value;
		return *this;
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename T>
	iuStreamMessage& operator << (T* const& value)
	{
		if( value == NULL )
		{
			m_stream << kStrings::Null;
		}
		else
		{
			m_stream << value;
		}
		return *this;
	}
#endif
	iuStreamMessage& operator << (bool b)
	{
		m_stream << (b ? "true" : "false");
		return *this;
	}
	iuStreamMessage& operator << (char* str)
	{
		append(str);
		return *this;
	}
	iuStreamMessage& operator << (const char* str)
	{
		append(str);
		return *this;
	}
	iuStreamMessage& operator << (wchar_t* str)
	{
		m_stream << ShowWideCString(str);
		return *this;
	}
	iuStreamMessage& operator << (const wchar_t* str)
	{
		m_stream << ShowWideCString(str);
		return *this;
	}
	iuStreamMessage& operator << (const iuStreamMessage& message)
	{
		m_stream << message.GetString();
		return *this;
	}
#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
	iuStreamMessage& operator << (iu_basic_iomanip val)
	{
		m_stream << val;
		return *this;
	}
#endif

public:
	/**
	 * @brief	メッセージの追記
	*/
	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();
}

/**
 * @brief	ファイル/ライン/メッセージクラス
*/
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(void) const { return m_message.c_str(); }		//!< メッセージの取得
	const char*		file_name(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_file; }	//!< ファイル名の取得
	int				line_number(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_line; }	//!< ライン番号の取得


public:
	template<typename T>
	iuCodeMessage& operator << (const T& value)
	{
		m_message += (iuStreamMessage() << value).GetString();
		return *this;
	}

public:
	/**
	 * @brief	メッセージの追記
	*/
	void add_message(const ::std::string& str);

public:
	
	::std::string make_message(void) const;
	::std::string make_newline_message(void) const
	{
		return make_message() + "\n";
	}
};

}	// end of namespace detail
}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_message.ipp
 * @brief		iris unit test メッセージ ファイル
 *
 * @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_MESSAGE_IPP_0A05C876_F204_41F5_895F_F8454AB283B1_
#define INCG_IRIS_IUTEST_MESSAGE_IPP_0A05C876_F204_41F5_895F_F8454AB283B1_

//======================================================================
// include

namespace iutest {
namespace detail
{

IUTEST_IPP_INLINE void iuStreamMessage::append(const char* str)
{
	if( str == NULL )
	{
		m_stream << kStrings::Null;
	}
	else
	{
		m_stream << str;
	}
}

IUTEST_IPP_INLINE ::std::string iuCodeMessage::make_message(void) const
{
	::std::string str = FormatFileLocation(m_file, m_line);
	str += ": ";
	str += message();
	return str;
}

IUTEST_IPP_INLINE ::std::string FormatFileLocation(const char* file, int line)
{
	const char* const file_name = file == NULL ? 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();
}

IUTEST_IPP_INLINE ::std::string FormatCompilerIndependentFileLocation(const char* file, int line)
{
	const char* const file_name = file == NULL ? kStrings::UnknownFile : file;
	if( line < 0 )
	{
		return file_name;
	}
	iu_stringstream strm;
	strm << file_name << ":" << line;
	return strm.str();
}

IUTEST_IPP_INLINE void iuCodeMessage::add_message(const ::std::string& str)
{
	m_message += str;
}

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_MESSAGE_IPP_0A05C876_F204_41F5_895F_F8454AB283B1_
#endif

#endif // INCG_IRIS_IUTEST_MESSAGE_HPP_0A05C876_F204_41F5_895F_F8454AB283B1_

namespace iutest
{

//======================================================================
// declare
namespace detail
{
	class DefaultGlobalTestPartResultReporter;
}

//======================================================================
// class
/**
 * @brief	テスト結果の通知処理インターフェイス
*/
class TestPartResultReporterInterface
{
public:
	virtual ~TestPartResultReporterInterface(void) {}
	/**
	 * @brief	テスト結果通知受け取り関数
	 * @param [in] result	= テスト結果
	*/
	virtual void ReportTestPartResult(const TestPartResult& result) = 0;
};

/**
 * @brief	テスト結果を示すクラス
*/
class TestPartResult : public detail::iuCodeMessage
{
public:
	/**
	 * @brief	結果のタイプ
	*/
	enum Type
	{
		kAssumeFailure = -3,	//!< 前提条件エラー
		kSkip = -2,				//!< スキップ
		kWarning = -1,			//!< 警告
		kSuccess,				//!< 成功
		kNonFatalFailure,		//!< 致命的ではない失敗
		kFatalFailure			//!< 致命的な失敗
	};
public:
	/**
	 * @brief	コンストラクタ
	 * @param [in]	file	= ファイル名
	 * @param [in]	line	= 行番号
	 * @param [in]	message	= メッセージ
	 * @param [in]	type	= 結果のタイプ
	*/
	TestPartResult(const char* file, int line, const char* message, Type type)
		: detail::iuCodeMessage(file, line, message), m_type(type) {}
	//! コピーコンストラクタ
	TestPartResult(const TestPartResult& rhs) : detail::iuCodeMessage(rhs)
		, m_type(rhs.m_type) {}

public:
	/**
	* @brief	失敗かどうか
	*/
	static bool type_is_failed(Type type) IUTEST_CXX_NOEXCEPT_SPEC { return type > kSuccess; }

public:
	/**
	 * @brief	失敗かどうか
	*/
	bool		failed(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_type > kSuccess; }
	/**
	 * @brief	成功かどうか
	*/
	bool		passed(void) const IUTEST_CXX_NOEXCEPT_SPEC { return !failed(); }
	/**
	 * @brief	警告かどうか
	*/
	bool		warning(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_type == kWarning; }
	/**
	 * @brief	スキップかどうか
	*/
	bool		skipped(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_type == kSkip; }
	/**
	 * @brief	前提条件エラーかどうか
	*/
	bool		assume_failed(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_type == kAssumeFailure; }
	/**
	 * @brief	成功かどうか（警告を除く）
	*/
	bool		succeeded(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_type == kSuccess; }

	/**
	 * @brief	致命的ではない失敗かどうか
	*/
	bool		nonfatally_failed(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_type == kNonFatalFailure; }

	/**
	 * @brief	致命的な失敗かどうか
	*/
	bool		fatally_failed(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_type == kFatalFailure; }

	/**
	 * @brief	理由
	*/
	const char*	summary(void) const { return message(); }

	/**
	 * @brief	結果のタイプ取得
	*/
	Type		type(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_type; }

private:
	Type m_type;
};

//! TestPartResult print 出力
inline iu_ostream& operator << (iu_ostream& os, const TestPartResult& result)
{
	return os << result.make_message();
}

/**
 * @brief	テストプロパティ
 * @note	XML 属性
*/
class TestProperty
{
public:
	/**
	 * @brief	コンストラクタ
	 * @param [in]	key		= キー
	 * @param [in]	value	= 値
	*/
	TestProperty(const ::std::string& key, const ::std::string& value)
		: m_key(key), m_value(value) {}

public:
	/**
	 * @brief	値の設定
	*/
	void SetValue(const ::std::string& value) { m_value = value; }
	const char*	key(void)	const { return m_key.c_str(); }		//!< キーの取得
	const char*	value(void)	const { return m_value.c_str(); }	//!< 値の取得

public:
	/**
	 * @brief	有効なキーかどうかチェック
	 * @retval	true=有効
	 * @retval	false=無効
	*/
	bool Validate(const char** ban_list, size_t size) const
	{
		return ValidateName(m_key, ban_list, ban_list+size);
	}
	/**
	 * @brief	有効なキーかどうかチェック
	 * @retval	true=有効
	 * @retval	false=無効
	*/
	template<typename Ite>
	static bool ValidateName(const ::std::string& name, Ite begin, Ite end)
	{
		return ::std::find(begin, end, name) == end;
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	
	template<typename T, size_t N>
	static bool ValidateName(const ::std::string& name, T (&ar)[N])
	{
		return ValidateName(name, ar, ar + N);
	}
#endif

private:
	friend class TestResult;
	::std::string m_key;
	::std::string m_value;
};

/**
 * @brief	テスト結果を示すクラス
*/
class TestResult
{
	typedef ::std::vector<TestPartResult>	TestPartResults;
	typedef ::std::vector<TestProperty>		TestPropertys;
public:
	TestResult(void)
		: m_elapsedmsec(0) {}

public:
	/**
	 * @brief	成功したかどうか
	 * @return	真偽値
	*/
	bool		Passed(void) const { return !Failed(); }
	/**
	 * @brief	失敗したかどうか
	 * @return	真偽値
	*/
	bool		Failed(void) 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;
	}
	/**
	 * @brief	スキップしたかどうか
	 * @return	真偽値
	*/
	bool		Skipped(void) 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;
	}

	/**
	 * @brief	致命的なエラーがあるかどうか
	 * @return	真偽値
	*/
	bool		HasFatalFailure(void) const { return HasResult(TestPartResult::kFatalFailure); }

	/**
	 * @brief	致命的でないエラーがあるかどうか
	 * @return	真偽値
	*/
	bool		HasNonfatalFailure(void) const { return HasResult(TestPartResult::kNonFatalFailure); }

	/**
	 * @brief	前提条件エラーがあるかどうか
	 * @return	真偽値
	*/
	bool		HasAssumeFailure(void) const { return HasResult(TestPartResult::kAssumeFailure); }

	/**
	 * @brief	テストの実行時間の取得
	 * @return	テストの実行時間
	*/
	TimeInMillisec	elapsed_time(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_elapsedmsec; }

	/**
	 * @brief	結果の数を取得
	 * @return	結果の数
	*/
	int			total_part_count(void) const { return static_cast<int>(m_test_part_results.size()); }

	/**
	 * @brief	プロパティ総数の取得
	 * @return	総数
	*/
	int			test_property_count(void) const { return static_cast<int>(m_test_propertys.size()); }

	/**
	 * @brief	テスト結果の取得
	 * @param [in]	index	= インデックス
	 * @return	テスト結果
	*/
	const TestPartResult&	GetTestPartResult(int index) const { return m_test_part_results[index]; }

	/**
	 * @brief	プロパティの取得
	 * @param [in]	index	= インデックス
	 * @return	プロパティの
	*/
	const TestProperty&		GetTestProperty(int index) const { return m_test_propertys[index]; }

public:
	/**
	 * @brief	失敗の数を取得
	 * @return	失敗の数
	*/
	int total_error_count(void) 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) IUTEST_CXX_NOEXCEPT_SPEC { 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(void)
	{
		m_test_part_results.clear();
	}
	void Clear(void)
	{
		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;

	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TestResult);
};

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_RESULT_HPP_D27B1599_F42F_4E2D_B3EB_FACE24C2B921_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_printers.hpp
 * @brief		iris unit test print 出力ヘルパー ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PRINTERS_HPP_A6A321C9_9279_4336_8167_058C59EC0FD0_
#define INCG_IRIS_IUTEST_PRINTERS_HPP_A6A321C9_9279_4336_8167_058C59EC0FD0_

//======================================================================
// include

namespace iutest
{

//======================================================================
// declare
template<typename T>
std::string PrintToString(const T& v);

namespace detail
{

inline void PrintBytesInObjectTo(const unsigned char* buf, size_t size, iu_ostream* os)
{
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
	const size_t kMaxCount = detail::kValues::MaxPrintContainerCount;
	*os << size << "-Byte object < ";
	for( size_t i=0; i < size; ++i )
	{
		*os << detail::ToHex(buf[i]>>4) << ToHex(buf[i]&0xF) << " ";
		if( i == kMaxCount )
		{
			*os << "... ";
			break;
		}
	}
	*os << ">";
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
}

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)
	{
#if IUTEST_HAS_BIGGESTINT_OSTREAM
		const BiggestInt v = value;
#else
		const Int32 v = value;
#endif
		*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);
	}
};

#if !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)

#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
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;
}
#else
template<typename T>
iu_ostream& operator << (iu_ostream& os, const T& value)
{
	TypeWithoutFormatter::PrintValue(value, &os);
	return os;
}
#endif

#endif

}	// end of printer_internal

namespace printer_internal2
{

// 解決順序
// foo::operator <<
// ::operator <<
// ::iutest::detail::printer_internal::operator <<
template<typename T>
void DefaultPrintNonContainerTo(const T& value, iu_ostream* os)
{
	using namespace ::iutest::detail::printer_internal;
	*os << value;
}

}	// end of printer_internal2

//======================================================================
// declare
template<typename T>
void UniversalPrint(const T& value, iu_ostream* os);

//======================================================================
// function
/**
 * @brief	デフォルト文字列変換関数
*/
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 DefaultPrintTo(IsContainerHelper::no_t
						, iutest_type_traits::false_type
						, const T& value, iu_ostream* os)
{
#if !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)
	printer_internal2::DefaultPrintNonContainerTo(value, os);
#else
	printer_internal::formatter::Printer<false>::Print(value, os);
#endif
}

#if !defined(IUTEST_NO_SFINAE) && !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

template<typename T>
inline void DefaultPtrPrintTo(T* ptr, iu_ostream* os, typename enable_if_t< is_convertible<T*, const void*> >::type*& = enabler::value)
{
	*os << ptr;
}
template<typename T>
inline void DefaultPtrPrintTo(T* ptr, iu_ostream* os, typename disable_if_t< is_convertible<T*, const void*> >::type*& = enabler::value)
{
	*os << reinterpret_cast<const void*>(reinterpret_cast<type_least_t<8>::UInt>(ptr));
}

#else

template<typename T>
inline void DefaultPtrPrintTo(T* ptr, iu_ostream* os)
{
	*os << reinterpret_cast<const void*>(reinterpret_cast<type_least_t<8>::UInt>(ptr));
}

#endif

template<typename T>
inline void DefaultPrintTo(IsContainerHelper::no_t
						, iutest_type_traits::true_type
						, T* ptr, iu_ostream* os)
{
	if( ptr == NULL )
	{
		*os << kStrings::Null;
	}
	else
	{
		DefaultPtrPrintTo<T>(ptr, os);
	}
}

/**
 * @brief	文字列変換関数
*/
template<typename T>
inline void PrintTo(const T& value, iu_ostream* os)	{
	DefaultPrintTo(
#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
		IsContainerHelper::IsContainer<T>(0)
#else
		IsContainerHelper::IsContainer(0, detail::explicit_type<T>())
#endif
		, 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(char* c, iu_ostream* os)		{ *os << c; }
inline void PrintTo(const ::std::string& str, iu_ostream* os)	{ *os << str.c_str(); }
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
template<typename T>
inline void PrintTo(const floating_point<T>& f, iu_ostream* os)	{ *os << f.raw() << "(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 << ")";
}
#endif
// char or unsigned char の時に、 0 が NULL 文字にならないように修正
inline void PrintTo(const char value, iu_ostream* os)
{
	if( value == 0 )
	{
		*os << "\\0";
	}
	else if( value < 0x20 )
	{
		*os << static_cast<int>(value);
	}
	else
	{
		*os << "\'" << value << "\'";
	}
}
inline void PrintTo(const wchar_t value, iu_ostream* os)
{
	if( value == 0 )
	{
		*os << "\\0";
	}
	else if( value < 0x20 )
	{
		*os << static_cast<int>(value);
	}
	else
	{
		*os << "\'" << value << "\'";
	}
}
inline void PrintTo(const unsigned char value, iu_ostream* os)
{
	*os << static_cast<unsigned int>(value);
}

#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 detail::enable_if<I == 0, void>::type*& = detail::enabler::value)
{
	IUTEST_UNUSED_VAR(t);
	IUTEST_UNUSED_VAR(os);
}
template<typename T, int I, int SIZE>
inline void PrintTupleElemTo(const T& t, iu_ostream* os, typename detail::enable_if<I == 1, void>::type*& = detail::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 detail::enable_if<(I&(~1)) != 0, void>::type*& = detail::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

inline void PrintTo(const tuples::tuple<>& t, iu_ostream* os) { PrintTupleTo(t, os); }
template<typename A1>
inline void PrintTo(const tuples::tuple<A1>& t, iu_ostream* os) { PrintTupleTo(t, os); }
template<typename A1, typename A2>
inline void PrintTo(const tuples::tuple<A1, A2>& t, iu_ostream* os) { PrintTupleTo(t, os); }
template<typename A1, typename A2, typename A3>
inline void PrintTo(const tuples::tuple<A1, A2, A3>& t, iu_ostream* os) { PrintTupleTo(t, os); }
template<typename A1, typename A2, typename A3, typename A4>
inline void PrintTo(const tuples::tuple<A1, A2, A3, A4>& t, iu_ostream* os) { PrintTupleTo(t, os); }
template<typename A1, typename A2, typename A3, typename A4, typename A5>
inline void PrintTo(const tuples::tuple<A1, A2, A3, A4, A5>& t, iu_ostream* os) { PrintTupleTo(t, os); }
template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
inline void PrintTo(const tuples::tuple<A1, A2, A3, A4, A5, A6>& t, iu_ostream* os) { PrintTupleTo(t, os); }
template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
inline void PrintTo(const tuples::tuple<A1, A2, A3, A4, A5, A6, A7>& t, iu_ostream* os) { PrintTupleTo(t, os); }
template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
inline void PrintTo(const tuples::tuple<A1, A2, A3, A4, A5, A6, A7, A8>& t, iu_ostream* os) { PrintTupleTo(t, os); }
template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
inline void PrintTo(const tuples::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9>& t, iu_ostream* os) { PrintTupleTo(t, os); }

#endif

#endif


template<typename T>
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalTersePrint(const T& value, iu_ostream* os)
{
	UniversalPrint(value, os);
}

inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalTersePrint(const char* str, iu_ostream* os)
{
	if( str == NULL )
	{
		*os << kStrings::Null;
	}
	else
	{
		UniversalPrint(::std::string(str), os);
	}
}
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalTersePrint(char* str, iu_ostream* os)
{
	UniversalTersePrint(static_cast<const char*>(str), os);
}
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalTersePrint(const wchar_t* str, iu_ostream* os)
{
	if( str == NULL )
	{
		*os << kStrings::Null;
	}
	else
	{
		UniversalPrint(detail::ShowWideCString(str), os);
	}
}
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalTersePrint(wchar_t* str, iu_ostream* os)
{
	UniversalTersePrint(static_cast<const wchar_t*>(str), os);
}
#if IUTEST_HAS_CHAR16_T
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalTersePrint(const char16_t* str, iu_ostream* os)
{
	if( str == NULL )
	{
		*os << kStrings::Null;
	}
	else
	{
		UniversalPrint(detail::ShowWideCString(str), os);
	}
}
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalTersePrint(char16_t* str, iu_ostream* os)
{
	UniversalTersePrint(static_cast<const char16_t*>(str), os);
}
#endif

/**
 * @brief	配列の出力
*/
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);
	}
}

/**
 * @brief	配列の出力
*/
template<typename T>
inline void IUTEST_ATTRIBUTE_UNUSED_ 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 << "}";
	}
}
/**
 * @brief	配列の出力
*/
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalPrintArray(const char* begin, size_t N, iu_ostream* os)
{
	IUTEST_UNUSED_VAR(N);
	UniversalTersePrint(begin, os);
}
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalPrintArray(const wchar_t* begin, size_t N, iu_ostream* os)
{
	IUTEST_UNUSED_VAR(N);
	UniversalTersePrint(begin, os);
}


template<typename T>
inline void IUTEST_ATTRIBUTE_UNUSED_ UniversalPrintTo(const T& value, iu_ostream* os)
{
	PrintTo(value, os);
}

//======================================================================
// class

template<typename T>
class iuUniversalPrinter
{
public:
	static void Print(const T& value, iu_ostream* os)
	{
		UniversalPrintTo(value, os);
	}
};

#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)


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);
	}
};

#endif

//======================================================================
// function

template<typename T>
inline void UniversalPrint(const T& value, iu_ostream* os)
{
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	iuUniversalPrinter<T>::Print(value, os);
#else
	UniversalPrintTo(value, os);
#endif
}

}	// end of namespace detail

//======================================================================
// function

/**
 * @brief	文字列化
*/
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
/**
 * @brief	文字列化
*/
template<typename T>
inline ::std::string PrintToStrings(const char* separate, const T& v)
{
	IUTEST_UNUSED_VAR(separate);
	return PrintToString(v);
}
/**
 * @brief	文字列化
*/
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

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_PRINTERS_HPP_A6A321C9_9279_4336_8167_058C59EC0FD0_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_list.hpp
 * @brief		iris unit test list 構造 ファイル
 *
 * @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_LIST_HPP_CB5AECEA_6147_4A89_BB97_236338CA177E_
#define INCG_IRIS_IUTEST_LIST_HPP_CB5AECEA_6147_4A89_BB97_236338CA177E_

//======================================================================
// include
#ifdef _IUTEST_DEBUG
#include <assert.h>
#endif

namespace iutest {
namespace detail
{

//======================================================================
// class
/**
 * @internal
 * @brief	リストノード
*/
template<typename TN>
class iu_list_node
{
	typedef TN *value_ptr;
	typedef iu_list_node<TN> _Myt;
public:
	value_ptr next;
	value_ptr prev;

protected:
	iu_list_node(void) IUTEST_CXX_NOEXCEPT_SPEC : next(NULL)
		, prev(NULL)
	{}
};

/**
 * @internal
 * @brief	リストイテレータ
*/
template<typename NODE, typename NODE_PTR, typename NODE_REF>
class iu_list_iterator
{
	typedef iu_list_iterator<NODE, NODE_PTR, NODE_REF> _Myt;
public:
	typedef NODE		value_type;
	typedef NODE_PTR	value_ptr;
	typedef NODE_REF	value_ref;
	typedef value_ptr	pointer;
	typedef value_ref	reference;
	typedef int			distance_type;
	typedef int			difference_type;
public:
	value_ptr m_node;
public:
	iu_list_iterator(value_ptr p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : m_node(p) {}
	iu_list_iterator(const _Myt& rhs) IUTEST_CXX_NOEXCEPT_SPEC : m_node(rhs.m_node) {}

public:
	bool operator == (const _Myt& it) const { return this->m_node == it.m_node; }
	bool operator != (const _Myt& it) const { return this->m_node != it.m_node; }

	_Myt&		operator ++ (void) { m_node = m_node->next; return *this; }
	_Myt&		operator -- (void) { m_node = m_node->prev; return *this; }
	value_ptr	operator -> (void) IUTEST_CXX_NOEXCEPT_SPEC { return ptr(); }
	value_ref	operator *  (void) IUTEST_CXX_NOEXCEPT_SPEC { return *m_node; }
	value_ptr	ptr(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_node; }

	operator	value_ptr (void)	{ return ptr(); }

	_Myt operator + (int n)
	{
		if( n == 0 )
		{
			return *this;
		}
		if( n > 0 )
		{
			return this->operator +(static_cast<unsigned int>(n));
		}
		_Myt ret(*this);
		n = -n;
		for( int i=0; i < n && ret.m_node != NULL; ++i )
		{
			ret.m_node = ret.m_node->prev;
		}
		return ret;
	}

	_Myt operator + (unsigned int n)
	{
		_Myt ret(*this);
		for( unsigned int i=0; i < n && ret.m_node != NULL; ++i )
		{
			ret.m_node = ret.m_node->next;
		}
		return ret;
	}
};

/**
 * @internal
 * @brief	リストクラス
 * @deprecated stl に変えたほうがいいかも、保守するのがメンドイ
*/
template<typename NODE>
class iu_list
{
	typedef NODE *node_ptr;
	typedef iu_list<NODE> _Myt;
protected:
	node_ptr m_node;

public:
	typedef iu_list_iterator<NODE, NODE*, NODE&> iterator;
	typedef iu_list_iterator<NODE, const NODE*, const NODE&> const_iterator;
public:
	iu_list(node_ptr p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : m_node(p) {}

public:
	// リストの総数取得
	unsigned int count(void) const IUTEST_CXX_NOEXCEPT_SPEC
	{
		unsigned int cnt = 0;
		node_ptr cur = m_node;
		while(cur != NULL)
		{
			++cnt;
			cur = cur->next;
		}
		return cnt;
	}
	unsigned int size(void) const IUTEST_CXX_NOEXCEPT_SPEC
	{
		return count();
	}
public:
	// ソートして挿入
	void sort_insert(node_ptr p)
	{
		if( p == NULL )
		{
			return;
		}

		if( m_node == NULL )
		{
			m_node = p;
			return;
		}

		if( *p < *m_node )
		{
			// 入れ替え
			node_ptr next = m_node;
			m_node = p;
			p->next = next;
			next->prev = p;
		}
		else
		{
			node_ptr prev = m_node;
			node_ptr cur = m_node->next;
			while(cur != NULL)
			{
				if( *p < *cur )
				{
					break;
				}
				prev = cur;
				cur = prev->next;
			}
			prev->next = p;
			p->prev = prev;
			p->next = cur;
			if( cur != NULL )
			{
				cur->prev = p;
			}
		}
	}
	// 追加
	void push_back(node_ptr p)
	{
		if( p == NULL )
		{
			return;
		}

		if( m_node == NULL )
		{
			m_node = p;
			return;
		}

		node_ptr prev = m_node;
		node_ptr cur = m_node->next;
		while(cur != NULL)
		{
			if( prev == p )
			{
				return;
			}
			prev = cur;
			cur = prev->next;
		}
		prev->next = p;
		p->prev = prev;
	}
	// 削除
	void erase(node_ptr p)
	{
		if( p == NULL )
		{
			return;
		}
		if( m_node == NULL )
		{
			return;
		}
		if( p->prev == NULL )
		{
			m_node = p->next;
			if( m_node != NULL )
			{
				m_node->prev = NULL;
			}
		}
		else
		{
			p->prev->next = p->next;
			if( p->next != NULL )
			{
				p->next->prev = p->prev;
			}
		}
		p->prev = p->next = NULL;
	}
	void erase(iterator it)
	{
		erase(it.ptr());
	}
public:
	/**
	 * @brief	シャッフル
	 * @tparam	F = 比較オブジェクト
	*/
	template<typename F>
	void shuffle(F& r)
	{
		for( unsigned int i=2, n=count(); i<n; ++i )
		{
			swap(begin() + (i-2), begin() + r(i) % i );
		}
	}

public:
	void swap(iterator a, iterator b)
	{
		if( a == b )
		{
			return;
		}
		if( a.ptr() == m_node )
		{
			m_node = b.ptr();
		}
		else if( b.ptr() == m_node )
		{
			m_node = a.ptr();
		}

		if( a->next == b.ptr() )
		{
			a->next = b->next;
			b->next = a.ptr();
			b->prev = a->prev;
			a->prev = b.ptr();
			if( a->next != NULL )
			{
				a->next->prev = a.ptr();
			}
			if( b->prev != NULL )
			{
				b->prev->next = b.ptr();
			}
		}
		else if( a->prev == b.ptr() )
		{
			b->next = a->next;
			a->next = b.ptr();
			a->prev = b->prev;
			b->prev = a.ptr();
			if( b->next != NULL )
			{
				b->next->prev = b.ptr();
			}
			if( a->prev != NULL )
			{
				a->prev->next = a.ptr();
			}
		}
		else
		{
			node_ptr tmp = a->next;
			a->next = b->next;
			b->next = tmp;
			tmp = a->prev;
			a->prev = b->prev;
			b->prev = tmp;
			if( a->next != NULL )
			{
				a->next->prev = a.ptr();
			}
			if( b->next != NULL )
			{
				b->next->prev = b.ptr();
			}
			if( a->prev != NULL )
			{
				a->prev->next = a.ptr();
			}
			if( b->prev != NULL )
			{
				b->prev->next = b.ptr();
			}
		}
	}

public:
	iterator begin(void) IUTEST_CXX_NOEXCEPT_SPEC
	{
		return m_node;
	}
	iterator end(void) IUTEST_CXX_NOEXCEPT_SPEC
	{
		return iterator(NULL);
	}
	const_iterator begin(void) const IUTEST_CXX_NOEXCEPT_SPEC
	{
		return m_node;
	}
	const_iterator end(void) const IUTEST_CXX_NOEXCEPT_SPEC
	{
		return const_iterator(NULL);
	}


public:
	struct EqualOp
	{
		template<typename T>
		bool operator () (const T* lhs, const T* rhs) const	{ return *lhs == *rhs; }
	};
public:
	template<typename FUNC>
	node_ptr find(node_ptr p, FUNC& f) const
	{
		node_ptr cur = m_node;
		while( cur != NULL )
		{
			if( f(cur, p) )
			{
				return cur;
			}
			cur = cur->next;
		}
		return NULL;
	}
	template<typename FUNC>
	node_ptr find(FUNC& f) const
	{
		node_ptr cur = m_node;
		while( cur != NULL )
		{
			if( f(cur) )
			{
				return cur;
			}
			cur = cur->next;
		}
		return NULL;
	}

public:
	node_ptr	operator -> (void)	{ return m_node; }
	node_ptr	operator &	(void)	{ return m_node; }
	NODE&		operator *  (void)	{ return *m_node; }

	node_ptr	operator [] (int index) const
	{
		node_ptr cur = m_node;
		for( int i=0; i < index; ++i )
		{
			cur = cur->next;
			if( cur == NULL )
			{
				break;
			}
		}
		return cur;
	}

	bool operator == (node_ptr p) const { return m_node == p; }
	bool operator != (node_ptr p) const { return m_node != p; }

private:
#ifdef _IUTEST_DEBUG
	// ノードの状態チェック
	bool check_node(void)
	{
		if( m_node == NULL ) return true;
		node_ptr prev = m_node;
		node_ptr curr = prev->next;
		while( curr != NULL )
		{
			assert( prev->next == curr );
			assert( curr->prev == prev );
			prev = curr;
			curr = prev->next;
		}
		return true;
	}
#endif
};

/**
 * @brief	vector シャッフル
*/
template<typename It>
void RandomShuffle(It begin, It last, iuRandom& r)
{
	r.shuffle(begin, last);
}

template<typename Node, typename Fn>
void RandomShuffle(iu_list<Node>& list, Fn& r)
{
	list.shuffle(r);
}
template<typename Node, typename Fn>
void RandomShuffle(::std::vector<Node>& list, Fn& r)
{
	RandomShuffle(list.begin(), list.end(), r);
}

template<typename Node, typename Fn>
Node* FindList(const iu_list<Node>& list, Fn& f)
{
	return list.find(f);
}
template<typename Node, typename Fn>
Node FindList(const ::std::vector<Node>& list, Fn& f)
{
	for( typename ::std::vector<Node>::const_iterator it=list.begin(), end=list.end(); it != end; ++it )
	{
		if( f(*it) )
		{
			return *it;
		}
	}
	return NULL;
}

/**
 * @brief	条件に合う要素数をカウント
*/
template<typename Node, typename Fn>
int CountIf(const iu_list<Node>& list, Fn f)
{
	int count = 0;
	for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
	{
		if( f(it) )
		{
			++count;
		}
	}
	return count;
}

/**
 * @brief	リストの示す値の総和
*/
template<typename Node, typename Fn>
int SumOverList(const iu_list<Node>& list, Fn f)
{
	int count = 0;
	for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
	{
		count += ((*it).*f)();
	}
	return count;
}

/**
 * @brief	リストの示す真の総和
*/
template<typename Node, typename Fn>
int CountIfOverList(const iu_list<Node>& list, Fn f)
{
	int count = 0;
	for( typename iu_list<Node>::const_iterator it = list.begin(), end=list.end(); it != end; ++it )
	{
		if( ((*it).*f)() )
		{
			++count;
		}
	}
	return count;
}

}	// end of namespace detail
}	// end of namespace iutest


#endif // INCG_IRIS_IUTEST_LIST_HPP_CB5AECEA_6147_4A89_BB97_236338CA177E_

namespace iutest
{

//======================================================================
// typedef
//! Message クラス
typedef detail::iuStreamMessage	Message;

//======================================================================
// function
template<typename T>
inline ::std::string StreamableToString(const T& value)
{
	return (Message() << value).GetString();
}

//======================================================================
// declare
namespace detail
{
	//! TestPartResultReporter がない場合の処理関数
	void DefaultReportTestPartResult(const TestPartResult& test_part_result);
}

//======================================================================
// class
/**
 * @brief	テスト結果
*/
class AssertionResult
{
public:
	/**
	 * @brief	コンストラクタ
	 * @param [in] result = テスト結果真偽値
	*/
	AssertionResult(bool result) : m_result(result) {}
	//! コピーコンストラクタ
	AssertionResult(const AssertionResult& rhs) : m_message(rhs.m_message), m_result(rhs.m_result) {}

	/**
	 * @brief	成否
	*/
	bool failed(void) const IUTEST_CXX_NOEXCEPT_SPEC { return !m_result; }

	/**
	 * @brief	成否
	*/
	bool passed(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_result; }

	/**
	 * @brief	メッセージの取得
	*/
	const char* message(void) const { return m_message.c_str(); }

	/**
	 * @brief	メッセージの取得
	 * @deprecated please use message() instead.
	*/
	const char* failure_message(void) const { return message(); }

	
	IUTEST_CXX_EXPLICIT_CONVERSION operator bool (void) const { return m_result; }

public:
	/**
	 * @brief	メッセージ追加
	*/
	template<typename T>
	AssertionResult& operator << (const T& value)
	{
		Message msg;
		msg << value;
		m_message += msg.GetString();
		return *this;
	}
public:
	AssertionResult operator ! (void) 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:
	/**
	 * @brief	成功結果の作成
	*/
	static AssertionResult Success(void) { return AssertionResult(true); }
	/**
	 * @brief	失敗結果の作成
	*/
	static AssertionResult Failure(void) { return AssertionResult(false); }
	/**
	 * @brief	成否の取得
	*/
	template<typename T>
	static AssertionResult Is(const T& b) { return AssertionResult(b ? true : false); }
	
	static AssertionResult Is(const AssertionResult& ar) { return AssertionResult(ar); }

private:
	IUTEST_PP_DISALLOW_ASSIGN(AssertionResult);

	::std::string m_message;
	bool m_result;
};

#if IUTEST_HAS_ASSERTION_RETURN
/**
 * @brief	Assetion Return Type
*/
template<typename R>
struct AssertionReturnType
{
	R value;	//!< 戻り値
	//! コンストラクタ
	AssertionReturnType() {}
	/**
	 * @brief	コンストラクタ
	 * @param [in]	v : 戻り値の値
	*/
	AssertionReturnType(const R& v) : value(v) {}
};
/**
 * @brief	Assetion Return Type (void)
*/
template<>
struct AssertionReturnType<void>
{
	//! コンストラクタ
	AssertionReturnType() {}
};

/**
 * @brief	Assetion Return 設定
*/
template<typename T>
inline AssertionReturnType<T> AssertionReturn(const T& ret) { return AssertionReturnType<T>(ret); }


inline AssertionReturnType<void> AssertionReturn(void) { return AssertionReturnType<void>(); }

#endif

/**
 * @brief	Assertion 構築クラス
*/
class AssertionHelper
{
public:
	/**
	 * @brief	コンストラクタ
	 * @param [in]	file	= ファイル名
	 * @param [in]	line	= 行番号
	 * @param [in]	message	= メッセージ
	 * @param [in]	type	= テスト結果のタイプ
	*/
	AssertionHelper(const char* file, int line, const char* message, TestPartResult::Type type)
		: m_part_result(file, line, message, type)
	{}
	/**
	 * @brief	コンストラクタ
	 * @param [in]	file	= ファイル名
	 * @param [in]	line	= 行番号
	 * @param [in]	message	= メッセージ
	 * @param [in]	type	= テスト結果のタイプ
	*/
	AssertionHelper(const char* file, int line, const ::std::string& message, TestPartResult::Type type)
		: m_part_result(file, line, message.c_str(), type)
	{}

private:
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(AssertionHelper);

#if IUTEST_HAS_RVALUE_REFS
	AssertionHelper(AssertionHelper&& rhs) IUTEST_CXX_DELETED_FUNCTION;
	AssertionHelper& operator=(AssertionHelper&&) IUTEST_CXX_DELETED_FUNCTION;
#endif

public:
	
	class ScopedMessage : public detail::iu_list_node<ScopedMessage>
		, public detail::iuCodeMessage
	{
	public:
		ScopedMessage(const detail::iuCodeMessage& msg)
			: detail::iuCodeMessage(msg)
		{
			ScopedTrace::GetInstance().list.push_back(this);
		}
		~ScopedMessage(void)
		{
			ScopedTrace::GetInstance().list.erase(this);
		}
	};
private:
	class ScopedTrace
	{
	public:
		typedef detail::iu_list<ScopedMessage> msg_list;
		msg_list list;
		static ScopedTrace& GetInstance(void) { static ScopedTrace inst; return inst; }
	public:
		void append_message(TestPartResult& part_result)
		{
			if( list.count() )
			{
				part_result.add_message("\niutest trace:");
				for( msg_list::iterator it = list.begin(), end=list.end(); it != end; ++it )
				{
					// TODO : 追加メッセージとして保存するべき
					// 現状はテスト結果のメッセージに追加している。
					part_result.add_message("\n");
					part_result.add_message(it->make_message().c_str());
				}
			}
		}
	};

#if defined(IUTEST_NO_PRIVATE_IN_AGGREGATE)
	friend class ScopedMessage;
#endif

#if IUTEST_HAS_ASSERTION_RETURN
private:
	template<typename R>struct ReturnTypedFixed;
#endif

public:
	
	class Fixed : public Message {
	public:
		template<typename T>
		Fixed& operator << (T val)
		{
			Message::operator << (val);
			return *this;
		}
#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
		Fixed& operator << (iu_basic_iomanip val)
		{
			Message::operator << (val);
			return *this;
		}
#endif

#if IUTEST_HAS_ASSERTION_RETURN
		Fixed& operator << (const AssertionReturnType<void>&)
		{
			return *this;
		}
		template<typename R>
		ReturnTypedFixed<R> operator << (const AssertionReturnType<R>& ret)
		{
			return ReturnTypedFixed<R>(*this, ret);
		}
#endif
	};

#if IUTEST_HAS_ASSERTION_RETURN
private:
	template<typename R>
	struct ReturnTypedFixed {
		Fixed fixed;
		AssertionReturnType<R> ret;
		ReturnTypedFixed(const Fixed& f, const AssertionReturnType<R>& r) : fixed(f), ret(r) {}
	};
#endif

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
	}
#if IUTEST_HAS_ASSERTION_RETURN
	
	template<typename R>
	R operator = (const ReturnTypedFixed<R>& fixed)
	{
		this->operator=(fixed.fixed);
		return fixed.ret.value;
	}
#endif

private:
	void OnFixed(const Fixed& fixed)
	{
		// OnFixed で throw しないこと！テスト側の例外キャッチにかからなくなる
		m_part_result.add_message(fixed.GetString());
		ScopedTrace::GetInstance().append_message(m_part_result);

		if( TestEnv::GetGlobalTestPartResultReporter() != NULL )
		{
			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;
};

}	// end of namespace iutest

namespace iutest
{

//======================================================================
// function
/**
 * @brief	テスト成功を示す AssertionResult オブジェクトの取得
*/
inline AssertionResult AssertionSuccess(void) { return AssertionResult::Success(); }
/**
 * @brief	テスト失敗を示す AssertionResult オブジェクトの取得
*/
inline AssertionResult AssertionFailure(void) { return AssertionResult::Failure(); }

namespace internal
{

/**
 * @brief	比較テストの値を文字列にフォーマット
*/
template<typename T1, typename T2>
inline ::std::string FormatForComparisonFailureMessage(const T1& value, const T2& )
{
	return PrintToString(value);
}

/**
 * @brief	boolean テストの失敗メッセージの出力
*/
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;
}

/**
 * @brief	Eq 系アサーション
*/
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);
}

/**
 * @private
 * @{
 */
#define DECL_COMPARE_HELPER_I_(op_name, op, type1, type2)						\
	inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelper##op_name(			\
			const char* expr1, const char* expr2, type1 val1, type2 val2) {		\
		if( val1 op val2 ) { return AssertionSuccess();							\
		} else { return CmpHelperOpFailure(expr1, expr2, #op, val1, val2); }	\
	}

#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)

#define DECL_COMPARE_HELPER_(op_name, op)							\
	template<typename T1, typename T2>								\
	DECL_COMPARE_HELPER_I_(op_name, op, const T1&, const T2&)		\
	DECL_COMPARE_HELPER_I_(op_name, op, BiggestInt, BiggestInt)

#else

#define DECL_COMPARE_HELPER_(op_name, op)							\
	template<typename T1, typename T2>								\
	DECL_COMPARE_HELPER_I_(op_name, op, const T1&, const T2&)

#endif

DECL_COMPARE_HELPER_(NE, !=)
DECL_COMPARE_HELPER_(LE, <=)
DECL_COMPARE_HELPER_(LT, < )
DECL_COMPARE_HELPER_(GE, >=)
DECL_COMPARE_HELPER_(GT, > )

#undef DECL_COMPARE_HELPER_I_
#undef DECL_COMPARE_HELPER_

/**
 * @}
*/

/**
 * @brief	Null Helper
 * @tparam	IsNullLiteral	= val が NULL リテラルかどうか
*/
template<bool IsNullLiteral>
class NullHelper
{
public:
	template<typename T>
	static AssertionResult CompareEq(const char* expr, const T* val)
	{
		if( NULL == val )
		{
			return AssertionSuccess();
		}

		return AssertionFailure() << "error: Value of " << expr
			<< "\n  Actual: " << val
			<< "\nExpected: NULL";
	}
	template<typename T>
	static AssertionResult CompareNe(const char* expr, const T* val)
	{
		if( NULL != val )
		{
			return AssertionSuccess();
		}

		return AssertionFailure() << "error: Value of " << expr
			<< "\n  Actual: NULL\nExpected: not NULL";
	}
};

/**
 * @brief	NullHelper 特殊化
*/
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: NULL\nExpected: not NULL";
	}
};

template<typename T1, typename T2>
inline AssertionResult CmpHelperSame(const char* expected_str, const char* actual_str
									  , const T1& expected, const T2& actual)
{
	if( &expected == &actual )
	{
		return AssertionSuccess();
	}

	return AssertionFailure() << "error: Expected: &(" << expected_str << ") == &(" << actual_str
		<< ")\n  Actual: " << FormatForComparisonFailureMessage(&expected, &actual)
		<< " vs " << FormatForComparisonFailureMessage(&actual, &expected);
}

template<typename T1, typename T2>
inline AssertionResult CmpHelperEQ(const char* expected_str, const char* actual_str
	, const T1& expected, const T2& actual)
{
	IUTEST_UNUSED_VAR(expected_str);

IUTEST_PARGMA_WARN_PUSH()
IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()

	if( actual == expected )
	{
		return AssertionSuccess();
	}

	return EqFailure(expected_str, actual_str
		, FormatForComparisonFailureMessage(expected, actual)
		, FormatForComparisonFailureMessage(actual, expected)
		);

IUTEST_PARGMA_WARN_POP()
}

template<typename T>
inline AssertionResult CmpHelperMemCmpEQ(const char* expected_str, const char* actual_str
	, const T& expected, const T& actual)
{
	IUTEST_UNUSED_VAR(expected_str);

IUTEST_PARGMA_WARN_PUSH()
IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()

	if( memcmp(&actual, &expected, sizeof(T)) == 0 )
	{
		return AssertionSuccess();
	}

	return EqFailure(expected_str, actual_str
		, FormatForComparisonFailureMessage(expected, actual)
		, FormatForComparisonFailureMessage(actual, expected)
		);

IUTEST_PARGMA_WARN_POP()
}

template<typename T>
inline AssertionResult CmpHelperMemCmpNE(const char* expected_str, const char* actual_str
	, const T& expected, const T& actual)
{
IUTEST_PARGMA_WARN_PUSH()
IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()

	if( memcmp(&actual, &expected, sizeof(T)) != 0 )
	{
		return AssertionSuccess();
	}

	return AssertionFailure() << "error: Expected: " << expected_str << " != " << actual_str
		<< "\n  Actual: " << FormatForComparisonFailureMessage(expected, actual);

IUTEST_PARGMA_WARN_POP()
}

/**
 * @brief	Equal Helper
 * @tparam	IsNullLiteral	= val1 が NULL リテラルかどうか
*/
template<bool IsNullLiteral>
class EqHelper
{
#if IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT
	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);
	}

#endif

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);
	}
};

/**
 * @brief	EqHelper 特殊化
*/
template<>
class EqHelper<true>
{
public:
#if !defined(IUTEST_NO_SFINAE)
	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)
	{
		IUTEST_UNUSED_VAR(val1);
		return CmpHelperEQ(expr1, expr2, static_cast<T2*>(NULL), val2);
	}
#else
	template<typename T1, typename T2>
	static AssertionResult Compare(const char* expr1, const char* expr2, const T1& val1, const T2& val2)
	{
		return CmpHelperEQ(expr1, expr2, (T2)val1, val2);
	}
#endif
};

/**
 * @brief	Not Equal Helper
 * @tparam	IsNullLiteral	= val1 が NULL リテラルかどうか
*/
template<bool IsNullLiteral>
class NeHelper
{
#if IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT
	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);
	}

#endif

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);
	}
};

/**
 * @brief	NeHelper 特殊化
*/
template<>
class NeHelper<true>
{
public:
#if !defined(IUTEST_NO_SFINAE)
	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)
	{
		IUTEST_UNUSED_VAR(val1);
		return CmpHelperNE(expr1, expr2, static_cast<T2*>(NULL), val2);
	}
#else
	template<typename T1, typename T2>
	static AssertionResult Compare(const char* expr1, const char* expr2, const T1& val1, const T2& val2)
	{
		return CmpHelperNE(expr1, expr2, (T2)val1, val2);
	}
#endif
};

template<typename RawType>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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);
}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
template<typename T, typename A>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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));
}
#endif
template<typename A>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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
{

inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const char* val1, const char* val2)
{
	if( val1 == NULL || val2 == NULL )
	{
		return val1 == val2;
	}
	return strcmp(val1, val2) == 0;
}

inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const wchar_t* val1, const wchar_t* val2)
{
	if( val1 == NULL || val2 == NULL )
	{
		return val1 == val2;
	}
	return wcscmp(val1, val2) == 0;
}

template<typename Elem, typename Traits, typename Ax>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const ::std::basic_string<Elem, Traits, Ax>& val1
	, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return val1 == val2;
}
template<typename Elem, typename Traits, typename Ax>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const Elem* val1
	, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return val2 == val1;
}
template<typename Elem, typename Traits, typename Ax>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const ::std::basic_string<Elem, Traits, Ax>& val1
	, const Elem* val2)
{
	return val1 == val2;
}
#if IUTEST_HAS_CHAR16_T
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const char16_t* val1, const char16_t* val2)
{
	if( val1 == NULL || val2 == NULL )
	{
		return val1 == val2;
	}
	::std::u16string v1 = val1;
	return Compare(v1, val2);
}
#endif
#if IUTEST_HAS_CHAR32_T
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const char32_t* val1, const char32_t* val2)
{
	if( val1 == NULL || val2 == NULL )
	{
		return val1 == val2;
	}
	::std::u32string v1 = val1;
	return Compare(v1, val2);
}
#endif

template<typename T1, typename T2>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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)));
}

}

inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
							   , const char* val1, const char* val2)
{
	return StrEqHelper::Assertion(expr1, expr2, val1, val2);
}

inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
							   , const wchar_t* val1, const wchar_t* val2)
{
	return StrEqHelper::Assertion(expr1, expr2, val1, val2);
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
																, const ::std::basic_string<Elem, Traits, Ax>& val1
																, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return StrEqHelper::Assertion(expr1, expr2, val1, val2);
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
																, const Elem* val1
																, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return StrEqHelper::Assertion(expr1, expr2, val1, val2);
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
																, const ::std::basic_string<Elem, Traits, Ax>& val1
																, const Elem* val2)
{
	return StrEqHelper::Assertion(expr1, expr2, val1, val2);
}
#if IUTEST_HAS_CHAR16_T
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
															, const char16_t* val1, const char16_t* val2)
{
	return StrEqHelper::Assertion(expr1, expr2, val1, val2);
}
#endif
#if IUTEST_HAS_CHAR32_T
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
															, const char32_t* val1, const char32_t* val2)
{
	return StrEqHelper::Assertion(expr1, expr2, val1, val2);
}
#endif

namespace StrNeHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& val1, const T2& val2)
{
	return !StrEqHelper::Compare(val1, val2);
}

template<typename T1, typename T2>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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
		<< "\n  Actual: " << detail::ShowStringQuoted(FormatForComparisonFailureMessage(val2, val1))
		<< " vs " << detail::ShowStringQuoted(FormatForComparisonFailureMessage(val1, val2));
}

}

inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
							, const char* val1, const char* val2)
{
	return StrNeHelper::Assertion(expr1, expr2, val1, val2);
}
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
							, const wchar_t* val1, const wchar_t* val2)
{
	return StrNeHelper::Assertion(expr1, expr2, val1, val2);
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
															, const ::std::basic_string<Elem, Traits, Ax>& val1
															, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return StrNeHelper::Assertion(expr1, expr2, val1, val2);
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
															, const Elem* val1
															, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return StrNeHelper::Assertion(expr1, expr2, val1, val2);
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
															, const ::std::basic_string<Elem, Traits, Ax>& val1
															, const Elem* val2)
{
	return StrNeHelper::Assertion(expr1, expr2, val1, val2);
}
#if IUTEST_HAS_CHAR16_T
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
															, const char16_t* val1, const char16_t* val2)
{
	return StrNeHelper::Assertion(expr1, expr2, val1, val2);
}
#endif
#if IUTEST_HAS_CHAR32_T
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
															, const char32_t* val1, const char32_t* val2)
{
	return StrNeHelper::Assertion(expr1, expr2, val1, val2);
}
#endif

namespace StrCaseEqHelper
{

inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const char* val1, const char* val2)
{
	if( val1 == NULL || val2 == NULL )
	{
		return val1 == val2;
	}
	return detail::iu_stricmp(val1, val2) == 0;
}

inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const wchar_t* val1, const wchar_t* val2)
{
	if( val1 == NULL || val2 == NULL )
	{
		return val1 == val2;
	}
	return detail::iu_wcsicmp(val1, val2) == 0;
}

template<typename Elem, typename Traits, typename Ax>
inline bool IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRCASEEQ(const char* expr1, const char* expr2
							, const char* val1, const char* val2)
{
	return StrCaseEqHelper::Assertion(expr1, expr2, val1, val2);
}
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& val1, const T2& val2)
{
	return !StrCaseEqHelper::Compare(val1, val2);
}

template<typename T1, typename T2>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRCASENE(const char* expr1, const char* expr2
							, const char* val1, const char* val2)
{
	return StrCaseNeHelper::Assertion(expr1, expr2, val1, val2);
}
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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);
}


template<typename RawType>
static 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>
static 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)));
}

#if defined(IUTEST_OS_WINDOWS)

inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ IsHRESULTSuccess(const char* expr, HRESULT hr)
{
	if( SUCCEEDED(hr) )
	{
		return AssertionSuccess();
	}
	return AssertionFailure() << "error: Expected: SUCCEEDED(" << expr << ")"
		<< "\n  Actual: " << hr << ": " << detail::win::GetHResultString(hr);
}
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ IsHRESULTFailure(const char* expr, HRESULT hr)
{
	if( FAILED(hr) )
	{
		return AssertionSuccess();
	}
	return AssertionFailure() << "error: Expected : FAILED(" << expr << ")"
		<< "\n  Actual: " << hr;
}

#endif

}	// end of namespace internal

/**
 * @brief	Float LE Formatter
 * @note	IUTEST_ASSERT_PRED_FORMAT2(::iutest::FloatLE , 0, 1);
*/
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ FloatLE(const char* expr1, const char* expr2
	, float val1, float val2)
{
	return internal::CmpHelperFloatingPointLE<float>(expr1, expr2, val1, val2);
}

/**
 * @brief	Double LE Formatter
 * @note	IUTEST_ASSERT_PRED_FORMAT2(::iutest::DoubleLE , 0, 1);
*/
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ DoubleLE(const char* expr1, const char* expr2
	, double val1, double val2)
{
	return internal::CmpHelperFloatingPointLE<double>(expr1, expr2, val1, val2);
}


}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_ASSERTION_HPP_E6AF3476_DA81_46F7_A961_ACCEF7363932_

//======================================================================
// 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

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

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_PRED_HPP_ADF851F3_C89B_4CA4_B9A0_A2B2229945C6_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_package.hpp
 * @brief		iris unit test testcase package
 *
 * @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_PACKAGE_HPP_F57C9B7E_7CAA_4429_BE75_FCAAEED1B220_
#define INCG_IRIS_IUTEST_PACKAGE_HPP_F57C9B7E_7CAA_4429_BE75_FCAAEED1B220_

//======================================================================
// include

//======================================================================
// define
/**
 * @ingroup	TESTDEF
 * @brief	パッケージ名前空間の定義
 * @param	name	= パッケージ名
*/
#define IUTEST_PACKAGE(name)	IIUT_PACKAGE_(name)

/**
 * @private
 * @{
*/

#if IUTEST_HAS_PACKAGE

#define IUTEST_CONCAT_PACKAGE_(testcase_name)	IIUT_CONCAT_PACKAGE_I(testcase_name).c_str()
#define IIUT_CONCAT_PACKAGE_I(testcase_name)					\
	iuTest_ConcatTestCaseName( iuTest_GetTestCasePackageName(	\
	static_cast<iuTest_TestCasePackage*>(NULL))					\
	, #testcase_name)

#define IUTEST_GET_PACKAGENAME_()	\
	iuTest_GetTestCasePackageName( static_cast<iuTest_TestCasePackage*>(NULL) )


#if IUTEST_HAS_IF_EXISTS

#define IIUT_PACKAGE_DECL_NAME_FUNC(name)				\
	static ::std::string IUTEST_ATTRIBUTE_UNUSED_		\
	iuTest_GetTestCasePackageName(const iuTest_TestCasePackage*) {			\
		return iuTest_GetTestCaseParentPackageName(		\
			static_cast<iuTest_TestCaseParentPackage*>(NULL)) + #name ".";	\
	}

#define IIUT_PACKAGE_DECL_PARENT_NAME_FUNC(name)		\
	static ::std::string IUTEST_ATTRIBUTE_UNUSED_		\
	iuTest_GetTestCaseParentPackageName(const iuTest_TestCaseParentPackage*) {				\
		return iuTest_GetTestCasePackageName(static_cast<iuTest_TestCasePackage*>(NULL));	\
	}


#define IIUT_PACKAGE_(name)									\
	namespace name {										\
	class iuTest_TestCasePackage;							\
	__if_not_exists(name::iuTest_GetTestCasePackageName) {	\
		IIUT_PACKAGE_DECL_NAME_FUNC(name)					\
	}														\
	class iuTest_TestCaseParentPackage;						\
	__if_not_exists(name::iuTest_GetTestCaseParentPackageName) {	\
		IIUT_PACKAGE_DECL_PARENT_NAME_FUNC(name)			\
	}														\
	}														\
	namespace name

#else

#define IIUT_PACKAGE_(name)								\
	namespace name {									\
	class iuTest_TestCasePackage;						\
	namespace { const int IUTEST_PP_CAT( k_iutest_package_##name##_dummy_, IUTEST_PP_UNIQUEID)	\
		IUTEST_ATTRIBUTE_UNUSED_ = package_name_server<iuTest_TestCasePackage>::setname(		\
			iuTest_GetTestCaseParentPackageName(static_cast<iuTest_TestCaseParentPackage*>(NULL)) + #name ".");	}	\
	class iuTest_TestCaseParentPackage;					\
	namespace { const int IUTEST_PP_CAT( k_iutest_package_##name##_parent_dummy_, IUTEST_PP_UNIQUEID)	\
		IUTEST_ATTRIBUTE_UNUSED_ = package_name_server<iuTest_TestCaseParentPackage>					\
		::setname(iuTest_GetTestCasePackageName(static_cast<iuTest_TestCasePackage*>(NULL))); }			\
	}													\
	namespace name

#endif

#else

#define IUTEST_CONCAT_PACKAGE_(testcase_name)	IIUT_CONCAT_PACKAGE_I(testcase_name)
#define IIUT_CONCAT_PACKAGE_I(testcase_name)	#testcase_name
#define IIUT_PACKAGE_(name)						namespace name
#define IUTEST_GET_PACKAGENAME_()				""

#endif

/**
 * @}
*/

#if IUTEST_HAS_PACKAGE

class iuTest_TestCasePackage;			//!< パッケージ名参照用定義
class iuTest_TestCaseParentPackage;		//!< 親パッケージ名参照用定義

#if IUTEST_HAS_IF_EXISTS

/**
 * @brief	グローバルパッケージ名の取得
 * @return	パッケージ名
*/
inline ::std::string IUTEST_ATTRIBUTE_UNUSED_ iuTest_GetTestCasePackageName(const iuTest_TestCasePackage*) { return ""; }

/**
 * @brief	親空間のパッケージ名の取得
 * @return	パッケージ名
*/
inline ::std::string IUTEST_ATTRIBUTE_UNUSED_ iuTest_GetTestCaseParentPackageName(const iuTest_TestCaseParentPackage*) { return ""; }

#else

/**
 * @brief	パッケージ名のサーバー
*/
template<typename T>
class package_name_server
{
	static ::std::string& getname_(void) { static ::std::string s; return s; }
public:
	static ::std::string getname(void) { return getname_(); }
	static int setname(const ::std::string& s)
	{
		::std::string& name = getname_();
		if( name.empty() ) name = s;
		return 0;
	}
};

/**
 * @brief	パッケージ名の取得
 * @return	パッケージ名
*/
template<typename T>
::std::string iuTest_GetTestCasePackageName(T*)
{
	return package_name_server<T>::getname();
}

/**
 * @brief	親空間のパッケージ名の取得
 * @return	パッケージ名
*/
template<typename T>
::std::string iuTest_GetTestCaseParentPackageName(T*)
{
	return package_name_server<T>::getname();
}

#endif

/**
 * @brief	テストケース名との結合
 * @return	テストケース名
*/
inline ::std::string IUTEST_ATTRIBUTE_UNUSED_ iuTest_ConcatTestCaseName(const ::std::string& package, const char* testcase_name) { return package + testcase_name; }

#endif

#endif // INCG_IRIS_IUTEST_PACKAGE_HPP_F57C9B7E_7CAA_4429_BE75_FCAAEED1B220_

//======================================================================
// define
/**
 * @private
 * @{
*/
#define IUTEST_TEST_CLASS_NAME_(testcase_, testname_)	IIUT_TEST_CLASS_NAME_I(IIUT_TO_VARNAME_(testcase_), IIUT_TO_VARNAME_(testname_))
#define IIUT_TEST_CLASS_NAME_I(testcase_, testname_)	IIUT_TEST_CLASS_NAME_I_(testcase_, testname_)
#define IIUT_TEST_CLASS_NAME_I_(testcase_, testname_)	iu_##testcase_##_x_##testname_##_Test

#define IUTEST_TEST_INSTANCE_NAME_(testcase_, testname_)	IIUT_TEST_INSTANCE_NAME_I(IIUT_TO_VARNAME_(testcase_), IIUT_TO_VARNAME_(testname_))
#define IIUT_TEST_INSTANCE_NAME_I(testcase_, testname_)		IIUT_TEST_INSTANCE_NAME_I_(testcase_, testname_)
#define IIUT_TEST_INSTANCE_NAME_I_(testcase_, testname_)	s_##testcase_##_##testname_##_Instance

#if IUTEST_HAS_TESTNAME_ALIAS

#define IIUT_TO_VARNAME_(name_)					IIUT_TO_VARNAME_I( (IIUT_ALIAS_TESTNAME_PP_##name_, name_, dummy_) )
#define IIUT_TO_VARNAME_I(tuple_)				IUTEST_PP_EXPAND( IIUT_TO_VARNAME_I_ tuple_ )
#define IIUT_TO_VARNAME_I_(dummy, name_, ...)	name_

#define IIUT_TO_NAME_(name_)					IIUT_TO_NAME_I( (IIUT_ALIAS_TESTNAME_PP_##name_, name_, name_, dummy_) )
#define IIUT_TO_NAME_I(tuple_)					IUTEST_PP_EXPAND( IIUT_TO_NAME_I_ tuple_ )
#define IIUT_TO_NAME_I_(dummy, dummy_2, name_, ...)	name_

#define IIUT_TO_NAME_STR_(name_)				IUTEST_PP_TOSTRING( IIUT_TO_NAME_(name_) )

#define IIUT_ALIAS_TESTNAME_PP_UNPAREN_(...)	__VA_ARGS__

#if defined(_MSC_VER)
#  define IUTEST_ALIAS_TESTNAME_(name_)			name_
#  define IUTEST_ALIAS_TESTNAME_F_(var_, name_)	UNPAREN_(dummy, var_, name_)
#else
#  define IUTEST_ALIAS_TESTNAME_(name_)			UNPAREN_(dummy, IUTEST_PP_CAT(iutest_japanese_var, __LINE__), name_)
#  define IUTEST_ALIAS_TESTNAME_F_(var_, name_)	UNPAREN_(dummy, var_, name_)
#endif

#else

#define IIUT_TO_VARNAME_(name_)		name_
#define IIUT_TO_NAME_(name_)		name_
#define IIUT_TO_NAME_STR_(name_)	#name_

#endif

#if IUTEST_HAS_IF_EXISTS
#  define IIUT_CHECK_TESTFIXTURE_I(testfixture_)		\
	IUTEST_IF_EXISTS(testfixture_, IUTEST_IF_EXISTS(testfixture_::SetUp,				\
		IUTEST_STATIC_ASSERT_MSG(														\
			(!::iutest_type_traits::is_base_of< ::iutest::Test, testfixture_ >::value)	\
			, #testfixture_ " is fixture class, mistake the IUTEST_F?");				\
	) )
#elif !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
#  define IIUT_CHECK_TESTFIXTURE_I(testfixture_)		\
	IUTEST_STATIC_ASSERT_MSG(						\
			(! ::iutest::detail::is_useful_testfixture< void (int (testfixture_)) >::value) \
			, #testfixture_ " is fixture class, mistake the IUTEST_F?");
#else
#  define IIUT_CHECK_TESTFIXTURE_I(testfixture_)
#endif
#define IIUT_CHECK_TESTFIXTURE_(testfixture_)	IIUT_CHECK_TESTFIXTURE_I(testfixture_)
#define IIUT_CHECK_TESTFIXTURE(testfixture_)	IIUT_CHECK_TESTFIXTURE_(IIUT_TO_VARNAME_(testfixture_))

#if !defined(IUTEST_TEST_STRICT_)
#if IUTEST_CHECK_STRICT
#  define IUTEST_TEST_STRICT_(testcase_, testname_, parent_class_, type_id_)	\
			IIUT_CHECK_TESTFIXTURE(testcase_)									\
			IUTEST_TEST_(testcase_, testname_, parent_class_, type_id_)
#else
#  define IUTEST_TEST_STRICT_	IUTEST_TEST_
#endif
#endif

#define IUTEST_TEST_F_(testfixture_, testname_)		IUTEST_TEST_(testfixture_, testname_, IIUT_TO_VARNAME_(testfixture_)	\
														, ::iutest::internal::GetTypeId< IIUT_TO_VARNAME_(testfixture_) >())

#define IUTEST_TEST_F_IGNORE_(testfixture_, testname_)	IUTEST_TEST_IGNORE_(testfixture_, testname_, IIUT_TO_VARNAME_(testfixture_)	\
															, ::iutest::internal::GetTypeId< IIUT_TO_VARNAME_(testfixture_) >())

/**
 * @}
*/

/**
 * @internal
 * @brief	Test class defined macro
*/
#define IUTEST_TEST_(testcase_, testname_, parent_class_, type_id_)							\
	class IUTEST_TEST_CLASS_NAME_(testcase_, testname_) : public parent_class_ {			\
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(IUTEST_TEST_CLASS_NAME_(testcase_, testname_));		\
		public:	IUTEST_TEST_CLASS_NAME_(testcase_, testname_)(void) {}						\
		protected: virtual void Body(void);													\
	};																						\
	::iutest::detail::TestInstance<IUTEST_TEST_CLASS_NAME_(testcase_, testname_)>			\
	IUTEST_TEST_INSTANCE_NAME_(testcase_, testname_)(										\
		IUTEST_CONCAT_PACKAGE_(IIUT_TO_NAME_(testcase_)), IIUT_TO_NAME_STR_(testname_)		\
		, type_id_, parent_class_::SetUpTestCase, parent_class_::TearDownTestCase);			\
	void IUTEST_TEST_CLASS_NAME_(testcase_, testname_)::Body(void)

/**
 * @internal
 * @brief	Test class defined macro
 *			関数の中はコンパイルできなくてもよい
*/
#define IUTEST_TEST_IGNORE_(testcase_, testname_, parent_class_, type_id_)					\
	class IUTEST_TEST_CLASS_NAME_(testcase_, testname_) : public parent_class_ {			\
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN( IUTEST_TEST_CLASS_NAME_(testcase_, testname_) );	\
		public: IUTEST_TEST_CLASS_NAME_(testcase_, testname_)(void) {}						\
		protected: virtual void Body(void) { IUTEST_SKIP() << "ignored test..."; }			\
		template<typename T>void Body(void);												\
	};																						\
	::iutest::detail::TestInstance<IUTEST_TEST_CLASS_NAME_(testcase_, testname_)>			\
	IUTEST_TEST_INSTANCE_NAME_(testcase_, testname_)(										\
		IUTEST_CONCAT_PACKAGE_(IIUT_TO_NAME_(testcase_)), IIUT_TO_NAME_STR_(testname_)		\
		, type_id_, parent_class_::SetUpTestCase, parent_class_::TearDownTestCase);			\
	template<typename T>void IUTEST_TEST_CLASS_NAME_(testcase_, testname_ )::Body(void)

#if !defined(IUTEST_NO_VARIADIC_MACROS)

/**
 * @private
 * @{
*/
#define IUTEST_PMZ_TEST_CLASS_NAME_(testcase_, testname_)	IIUT_PMZ_TEST_CLASS_NAME_I(IIUT_TO_VARNAME_(testcase_), IIUT_TO_VARNAME_(testname_))
#define IIUT_PMZ_TEST_CLASS_NAME_I(testcase_, testname_)	IIUT_PMZ_TEST_CLASS_NAME_I_(testcase_, testname_)
#define IIUT_PMZ_TEST_CLASS_NAME_I_(testcase_, testname_)	IUTEST_PP_CAT( IUTEST_PP_CAT(iu_##testcase_##_x_Test_, testname_), __LINE__)
/**
 * @}
*/

/**
 * @internal
 * @brief	Parameterized test class defined macro
*/
#define IIUT_TEST_PMZ_(testcase_, testname_, method_, parent_class_, type_id_, ...)				\
	class IUTEST_TEST_CLASS_NAME_(testcase_, testname_);										\
	class IUTEST_PMZ_TEST_CLASS_NAME_(testcase_, testname_) : public parent_class_ {			\
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(IUTEST_PMZ_TEST_CLASS_NAME_(testcase_, testname_));		\
		public: IUTEST_PMZ_TEST_CLASS_NAME_(testcase_, testname_)(void) {}						\
		static ::std::string MakeTestName(void) { return ::iutest::detail::MakeIndexTestName(	\
			IIUT_TO_NAME_STR_(testname_), ::iutest::detail::GetTypeUniqueCounter<				\
				IUTEST_TEST_CLASS_NAME_(testcase_, testname_)>()); }							\
		protected: virtual void Body(void) { method_(__VA_ARGS__); }							\
	};																							\
	::iutest::detail::TestInstance<IUTEST_PMZ_TEST_CLASS_NAME_(testcase_, testname_)>			\
	IUTEST_PP_CAT( IUTEST_TEST_INSTANCE_NAME_(testcase_, testname_), __LINE__)(					\
		IUTEST_CONCAT_PACKAGE_(IIUT_TO_NAME_(testcase_))										\
		, IUTEST_PMZ_TEST_CLASS_NAME_(testcase_, testname_)::MakeTestName().c_str()				\
		, #__VA_ARGS__, type_id_, parent_class_::SetUpTestCase, parent_class_::TearDownTestCase)

#endif

#define IUTEST_CLASS_INITIALIZE(methodName)		static void SetUpTestCase() { methodName(); } static void methodName()
#define IUTEST_CLASS_CLEANUP(methodName)		static void TearDownTestCase() { methodName(); } static void methodName()

#define IUTEST_METHOD_INITIALIZE(methodName)	virtual void SetUp() IUTEST_CXX_OVERRIDE { methodName(); } void methodName()
#define IUTEST_METHOD_CLEANUP(methodName)		virtual void TearDown() IUTEST_CXX_OVERRIDE { methodName(); } void methodName()

/**
 * @private
 * @{
*/
#define IUTEST_CLASS_INITIALIZE(methodName)		static void SetUpTestCase() { methodName(); } static void methodName()
#define IUTEST_CLASS_CLEANUP(methodName)		static void TearDownTestCase() { methodName(); } static void methodName()

#define IUTEST_METHOD_INITIALIZE(methodName)	virtual void SetUp() IUTEST_CXX_OVERRIDE { methodName(); } void methodName()
#define IUTEST_METHOD_CLEANUP(methodName)		virtual void TearDown() IUTEST_CXX_OVERRIDE { methodName(); } void methodName()
/**
 * @}
*/

/**
 * @internal
 * @brief	Assertion message
*/
#define IUTEST_MESSAGE_AT(file_, line_, msg_, result_type_)	::iutest::AssertionHelper(file_, line_, msg_, result_type_) = ::iutest::AssertionHelper::Fixed()
#define IUTEST_MESSAGE(msg_, result_type_)					IUTEST_MESSAGE_AT(__FILE__, __LINE__, msg_, result_type_)

/**
 * @internal
 * @brief	ASSERT message
*/
#define IUTEST_ASSERT_FAILURE(msg)					IUTEST_ASSERT_FAILURE_AT(msg, __FILE__, __LINE__)

#if !defined(IUTEST_NO_VOID_RETURNS)
#  define IUTEST_ASSERT_FAILURE_AT(msg, file, line)	return IUTEST_MESSAGE_AT(file, line, msg, ::iutest::TestPartResult::kFatalFailure)
#else
#  define IUTEST_ASSERT_FAILURE_AT(msg, file, line)	IUTEST_MESSAGE_AT(file, line, msg, ::iutest::TestPartResult::kFatalFailure)
#endif

/**
 * @internal
 * @brief	EXPECT message
*/
#define IUTEST_EXPECT_FAILURE(msg)					IUTEST_EXPECT_FAILURE_AT(msg, __FILE__, __LINE__)

#define IUTEST_EXPECT_FAILURE_AT(msg, file, line)	IUTEST_MESSAGE_AT(file, line, msg, ::iutest::TestPartResult::kNonFatalFailure)

/**
 * @internal
 * @brief	INFORM message
*/
#define IUTEST_INFORM_FAILURE(msg)					IUTEST_INFORM_FAILURE_AT(msg, __FILE__, __LINE__)

#define IUTEST_INFORM_FAILURE_AT(msg, file, line)	IUTEST_MESSAGE_AT(file, line, msg, ::iutest::TestPartResult::kWarning)

/**
 * @internal
 * @brief	ASSUME message
*/
#define IUTEST_ASSUME_FAILURE(msg)					IUTEST_ASSUME_FAILURE_AT(msg, __FILE__, __LINE__)

#if !defined(IUTEST_NO_VOID_RETURNS)
#  define IUTEST_ASSUME_FAILURE_AT(msg, file, line)	return IUTEST_MESSAGE_AT(file, line, msg, ::iutest::TestPartResult::kAssumeFailure)
#else
#  define IUTEST_ASSUME_FAILURE_AT(msg, file, line)	IUTEST_MESSAGE_AT(file, line, msg, ::iutest::TestPartResult::kAssumeFailure)
#endif

/**
 * @internal
 * @brief	SKIP message
*/
#define IUTEST_SKIP_MESSAGE(msg)					IUTEST_SKIP_MESSAGE_AT(msg, __FILE__, __LINE__)

#if !defined(IUTEST_NO_VOID_RETURNS)
#  define IUTEST_SKIP_MESSAGE_AT(msg, file, line)	return IUTEST_MESSAGE_AT(file, line, msg, ::iutest::TestPartResult::kSkip)
#else
#  define IUTEST_SKIP_MESSAGE_AT(msg, file, line)	IUTEST_MESSAGE_AT(file, line, msg, ::iutest::TestPartResult::kSkip)
#endif

#ifndef IUTEST_MAKE_ASSERTIONRESULT_
#  define IUTEST_MAKE_ASSERTIONRESULT_(ar)	ar
#endif

/**
 * @internal
 * @biref	比較検証マクロ
*/
#define IUTEST_TEST_ASSERT_(expression, on_failure)	\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_					\
	if( const ::iutest::AssertionResult iutest_ar = IUTEST_MAKE_ASSERTIONRESULT_(expression) )	\
		;											\
	else											\
		on_failure(iutest_ar.message())

#if IUTEST_HAS_EXCEPTIONS
/**
 * @internal
 * @brief	throw assertion defined macro
*/
#define IUTEST_TEST_THROW_(statement, expected_exception, on_failure)		\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_											\
	if( const char* msg = "" ) {											\
		try {																\
			IUTEST_SUPPRESS_UNREACHABLE_CODE_WARNING((void)(statement));	\
			msg = "\nExpected: " #statement " throws an exception of type "	\
				  #expected_exception ".\n  Actual: it throws nothing.";	\
			goto IUTEST_PP_CAT(iutest_label_throw, __LINE__);				\
		} catch( expected_exception const& ) {								\
		} catch( ... ) {													\
			msg = "\nExpected: " #statement " throws an exception of type "	\
          #expected_exception ".\n  Actual: it throws a different type.";	\
			goto IUTEST_PP_CAT(iutest_label_throw, __LINE__);				\
		}																	\
	} else																	\
		IUTEST_PP_CAT(iutest_label_throw, __LINE__):						\
		on_failure(msg)

/**
 * @internal
 * @brief	throw value assertion defined macro
*/
#define IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, pred_formatter)	\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_														\
	if( ::iutest::AssertionResult iutest_ar = ::iutest::AssertionSuccess() ) {			\
		try {																			\
			IUTEST_SUPPRESS_UNREACHABLE_CODE_WARNING((void)(statement));				\
			iutest_ar << "\nExpected: " #statement " throws an exception of type "		\
				#expected_exception ".\n  Actual: it throws nothing.";					\
			goto IUTEST_PP_CAT(iutest_label_throw_value, __LINE__);						\
		} catch( expected_exception const& e) {											\
			if( const ::iutest::AssertionResult	ar										\
				= pred_formatter("e", #expected_exception_value, e, expected_exception_value) ) {			\
			} else {																	\
				iutest_ar << "\nExpected: " #statement " throws an exception of value\n" << ar.message();	\
				goto IUTEST_PP_CAT(iutest_label_throw_value, __LINE__);					\
			}																			\
		} catch( ... ) {																\
			iutest_ar << "\nExpected: " #statement " throws an exception of type "		\
				#expected_exception ".\n  Actual: it throws a different type.";			\
			goto IUTEST_PP_CAT(iutest_label_throw_value, __LINE__);						\
		}																				\
	} else																				\
		IUTEST_PP_CAT(iutest_label_throw_value, __LINE__):								\
		on_failure(iutest_ar.message())

#define IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_exception_value, on_failure)	\
	IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, ::iutest::internal::EqHelper<IUTEST_IS_NULLLITERAL(expected_exception_value)>::Compare)
#define IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, expected_exception_value, on_failure)	\
	IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, ::iutest::internal::NeHelper<IUTEST_IS_NULLLITERAL(expected_exception_value)>::Compare)
#define IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_exception_value, on_failure)	\
	IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, ::iutest::internal::CmpHelperSTREQ)
#define IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_exception_value, on_failure)	\
	IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, ::iutest::internal::CmpHelperSTRCASEEQ)

/**
 * @internal
 * @brief	any throw assertion defined macro
*/
#define IUTEST_TEST_ANY_THROW_(statement, on_failure)						\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_											\
	if( ::iutest::detail::AlwaysTrue() ) {									\
		try {																\
			(void)(statement);												\
			goto IUTEST_PP_CAT(iutest_label_anythrow, __LINE__);			\
		} catch( ... ) {													\
		}																	\
	} else																	\
		IUTEST_PP_CAT(iutest_label_anythrow, __LINE__):						\
		on_failure("\nExpected: " #statement " throws an exception.\n  Actual: it doesn's throws.")

/**
 * @internal
 * @brief	no throw assertion defined macro
*/
#define IUTEST_TEST_NO_THROW_(statement, on_failure)						\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_											\
	if( ::iutest::AssertionResult iutest_ar = ::iutest::AssertionSuccess() ) {	\
		try {																\
			(void)(statement);												\
		} catch( const ::std::exception& e ) {								\
			iutest_ar << "\nExpected: " #statement " doesn't throw an exception.\n  Actual: it throws. what is \""	\
				<< e.what() << "\"";										\
			goto IUTEST_PP_CAT(iutest_label_nothrow, __LINE__);				\
		} catch( const char *e ) {											\
			iutest_ar << "\nExpected: " #statement " doesn't throw an exception.\n  Actual: it throws. \""	\
				<< e << "\"";												\
			goto IUTEST_PP_CAT(iutest_label_nothrow, __LINE__);				\
		} catch( ... ) {													\
			iutest_ar << "\nExpected: " #statement " doesn't throw an exception.\n  Actual: it throws.";	\
			goto IUTEST_PP_CAT(iutest_label_nothrow, __LINE__);				\
		}																	\
	} else																	\
		IUTEST_PP_CAT(iutest_label_nothrow, __LINE__):						\
		on_failure(iutest_ar.message())

#endif

#define IUTEST_TEST_BOOLEAN_(expression, text, actual, expected, on_failure)	\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_												\
	if( const ::iutest::AssertionResult iutest_ar = ::iutest::AssertionResult::Is(expression) )	\
		;																		\
	else																		\
		on_failure(::iutest::internal::GetBooleanAssertionFailureMessage(		\
			iutest_ar, text, #actual, #expected).c_str() )

/**
 * @internal
 * @brief	assert
*/
#define IUTEST_ASSERT_EXIT(cond)			do { if( !(cond) ) {												\
												IUTEST_MESSAGE(#cond, ::iutest::TestPartResult::kFatalFailure);	\
												exit(1);														\
											} } while(::iutest::detail::AlwaysFalse())

/**
 * @internal
 * @brief	明示的な成功
*/
#define IIUT_SUCCEED()						IUTEST_MESSAGE("Succeeded.\n", ::iutest::TestPartResult::kSuccess)
/**
 * @internal
 * @brief	明示的な失敗
*/
#define IIUT_FAIL()							IUTEST_ASSERT_FAILURE("Failed.\n")
#define IIUT_ADD_FAILURE()					IUTEST_EXPECT_FAILURE("Failed.\n")
#define IIUT_ADD_FAILURE_AT(file_, line_)	IUTEST_EXPECT_FAILURE_AT("Failed.\n", file_, line_)

/**
 * @internal
 * @brief	メッセージロギング
*/
#define IIUT_SCOPED_MESSAGE(msg_)			\
	const ::iutest::AssertionHelper::ScopedMessage IUTEST_PP_CAT(scoped_message_, IUTEST_PP_COUNTER) = ::iutest::detail::iuCodeMessage(__FILE__, __LINE__, ::iutest::Message() << (msg_))

/**
 * @internal
 * @brief	IUTEST_ANALYSIS_ASSUME_ を通す
*/
#if IUTEST_HAS_ANALYSIS_ASSUME

#define IUTEST_THROUGH_ANALYSIS_ASSUME_(expr, todo)					\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_									\
	if( bool b = true ) {											\
		IUTEST_UNUSED_VAR(b);										\
		IUTEST_ANALYSIS_ASSUME(expr);								\
		goto IUTEST_PP_CAT(iutest_label_analysis_assume, __LINE__);	\
	} else															\
		IUTEST_PP_CAT(iutest_label_analysis_assume, __LINE__):		\
		todo

#else

#define IUTEST_THROUGH_ANALYSIS_ASSUME_(expr, todo)	todo

#endif

/**
 * @internal
 * @brief	all flavor assertion macro
 * @{
*/
#define	IUTEST_TEST_EQ(expected, actual, on_failure)	IUTEST_PRED_FORMAT2_( ::iutest::internal::EqHelper<IUTEST_IS_NULLLITERAL(expected)>::Compare, expected, actual, on_failure )
#define	IUTEST_TEST_NE(v1, v2, on_failure)				IUTEST_PRED_FORMAT2_( ::iutest::internal::NeHelper<IUTEST_IS_NULLLITERAL(v1)>::Compare, v1, v2, on_failure )
//#define	IUTEST_TEST_NE(v1, v2, on_failure)				IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperNE, v1, v2, on_failure )
#define	IUTEST_TEST_LE(v1, v2, on_failure)				IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperLE, v1, v2, on_failure )
#define	IUTEST_TEST_LT(v1, v2, on_failure)				IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperLT, v1, v2, on_failure )
#define	IUTEST_TEST_GE(v1, v2, on_failure)				IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperGE, v1, v2, on_failure )
#define	IUTEST_TEST_GT(v1, v2, on_failure)				IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperGT, v1, v2, on_failure )

#define IUTEST_TEST_TRUE(expr, text, on_failure)		IUTEST_TEST_BOOLEAN_( expr, text, false, true, on_failure)
#define IUTEST_TEST_FALSE(expr, text, on_failure)		IUTEST_TEST_BOOLEAN_( !(expr), text, true, false, on_failure)

#define IUTEST_TEST_FLOAT_EQ(expected, actual, on_failure)		IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperFloatingPointEQ<float> , expected, actual, on_failure )
#define IUTEST_TEST_DOUBLE_EQ(expected, actual, on_failure)		IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperFloatingPointEQ<double>, expected, actual, on_failure )

#define IUTEST_TEST_NEAR(v1, v2, abs_v, on_failure)		IUTEST_PRED_FORMAT3_( ::iutest::internal::CmpHelperNear, v1, v2, abs_v, on_failure )

#define	IUTEST_TEST_STREQ(expected_str, actual_str, on_failure)		IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperSTREQ, expected_str, actual_str, on_failure )
#define	IUTEST_TEST_STRNE(v1, v2, on_failure)						IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperSTRNE, v1, v2, on_failure )
#define	IUTEST_TEST_STRCASEEQ(expected_str, actual_str, on_failure)	IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperSTRCASEEQ, expected_str, actual_str, on_failure )
#define	IUTEST_TEST_STRCASENE(v1, v2, on_failure)					IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperSTRCASENE, v1, v2, on_failure )

#define IUTEST_TEST_HRESULT_SUCCEEDED(hr, on_failure)	IUTEST_PRED_FORMAT1_( ::iutest::internal::IsHRESULTSuccess, hr, on_failure )
#define IUTEST_TEST_HRESULT_FAILED(hr, on_failure)		IUTEST_PRED_FORMAT1_( ::iutest::internal::IsHRESULTFailure, hr, on_failure )

#define IUTEST_TEST_NULL(v, on_failure)					IUTEST_THROUGH_ANALYSIS_ASSUME_(v==NULL, IUTEST_PRED_FORMAT1_( ::iutest::internal::NullHelper<IUTEST_IS_NULLLITERAL(v)>::CompareEq, v, on_failure ))
#define IUTEST_TEST_NOTNULL(v, on_failure)				IUTEST_THROUGH_ANALYSIS_ASSUME_(v!=NULL, IUTEST_PRED_FORMAT1_( ::iutest::internal::NullHelper<IUTEST_IS_NULLLITERAL(v)>::CompareNe, v, on_failure ))

#define IUTEST_TEST_SAME(v1, v2, on_failure)			IUTEST_PRED_FORMAT2_( ::iutest::internal::CmpHelperSame, v1, v2, on_failure )

#define IUTEST_TEST_NO_FAILURE_(statement, on_failure)						\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_											\
	if( ::iutest::detail::AlwaysTrue() ) {									\
		::iutest::detail::NewTestPartResultCheckHelper::Counter<			\
			::iutest::detail::NewTestPartResultCheckHelper::CondGt<			\
			::iutest::TestPartResult::kSuccess> > iutest_failure_checker;	\
		IUTEST_SUPPRESS_UNREACHABLE_CODE_WARNING( { (void)0; statement; } )	\
		if( iutest_failure_checker.count() > 0 ) {							\
			goto IUTEST_PP_CAT(iutest_label_test_no_failure_, __LINE__);	\
		}																	\
	} else																	\
		IUTEST_PP_CAT(iutest_label_test_no_failure_, __LINE__):				\
		on_failure("\nExpected: " #statement " doesn't generate new failure.\n  Actual: it does.")

#define IUTEST_TEST_NO_FATAL_FAILURE_(statement, on_failure)				\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_											\
	if( ::iutest::detail::AlwaysTrue() ) {									\
		::iutest::detail::NewTestPartResultCheckHelper::Counter<			\
			::iutest::detail::NewTestPartResultCheckHelper::CondEq<			\
			::iutest::TestPartResult::kFatalFailure> > iutest_failure_checker;	\
		IUTEST_SUPPRESS_UNREACHABLE_CODE_WARNING( { (void)0; statement; } )	\
		if( iutest_failure_checker.count() > 0 ) {							\
			goto IUTEST_PP_CAT(iutest_label_test_no_fatalfailure_, __LINE__);	\
		}																	\
	} else																	\
		IUTEST_PP_CAT(iutest_label_test_no_fatalfailure_, __LINE__):		\
		on_failure("\nExpected: " #statement " doesn't generate new fatal failure.\n  Actual: it does.")

#define IUTEST_TEST_SKIP()					\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_			\
	if( (::iutest::UnitTest::current_test_result()->Failed())					\
		|| (::iutest::UnitTest::SkipTest(), ::iutest::detail::AlwaysTrue()) )	\
		IUTEST_SKIP_MESSAGE( ::iutest::UnitTest::current_test_result()->Failed() ? "Skipped. but already failed. " : "Skipped. " )

/**
 * @}
*/

/**
 * @brief	コンパイルエラーチェックタグ
*/
#if defined(_MSC_VER)
#  define IUTEST_TEST_COMPILEERROR(e)	IUTEST_PRAGMA_MESSAGE(	\
	__FILE__ "(" IUTEST_PP_TOSTRING(__LINE__) "): note : " "IUTEST_TEST_COMPILEERROR( " #e " )")
#else
#  define IUTEST_TEST_COMPILEERROR(e)	IUTEST_PRAGMA_MESSAGE("IUTEST_TEST_COMPILEERROR( " #e " )")
#endif

/**
* @brief	static_assert チェックタグ
* @{
*/
#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
/**
* @}
*/

#endif // INCG_IRIS_IUTEST_INTERNAL_HPP_A5BD9FBB_B57A_4C1D_B205_0ADB7798DBF9_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_option_message.hpp
 * @brief		iris unit test コマンドラインメッセージ ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_OPTION_MESSAGE_HPP_00EB9B17_0615_4678_9AD0_1F5B295B404F_
#define INCG_IRIS_IUTEST_OPTION_MESSAGE_HPP_00EB9B17_0615_4678_9AD0_1F5B295B404F_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_console.hpp
 * @brief		iris unit test console
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_
#define INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_

//======================================================================
// include
#include <stdio.h>
#include <stdarg.h>

namespace iutest {
namespace detail
{

//======================================================================
// define
#ifndef IUTEST_VPRINTF
#  define IUTEST_VPRINTF(f, a)	vprintf(f, a)	//!< vprintf 呼び出しマクロ
#endif

#ifndef IUTEST_HAS_COLORCONSOLE
#  if defined(IUTEST_OS_WINDOWS_MOBILE) || defined(IUTEST_OS_NACL)
#    define IUTEST_HAS_COLORCONSOLE	0	//!< 色つきターミナルが使用可能かどうか
#  else
#    define IUTEST_HAS_COLORCONSOLE	1	//!< 色つきターミナルが使用可能かどうか
#  endif
#endif

//======================================================================
// class
/**
 * @internal
 * @brief	カスタム Logger クラス
*/
class iuLogger
{
public:
	virtual void output(const char* fmt, ...)
	{
		va_list va;
		va_start(va, fmt);
		voutput(fmt, va);
		va_end(va);
	}
	virtual void voutput(const char* fmt, va_list va) = 0;
};

/**
 * @internal
 * @brief	コンソールクラス
*/
class iuConsole
{
	template<typename T>
	struct Variable
	{
		static iuLogger* m_pLogger;
	};

	typedef Variable<void> var;

public:
	//! コンソール文字色
	enum Color
	{
		black,
		red,
		green,
		yellow,
		blue,
		magenta,
		cyan,
		white
	};
public:
	/**
	 * @brief	標準出力
	*/
	static inline void output(const char *fmt, ...);

	/**
	 * @brief	標準出力
	*/
	static inline void voutput(const char* fmt, va_list va);

	/**
	 * @brief	色指定で標準出力
	 * @param [in]	color	= 文字色
	*/
	static inline void color_output(Color color, const char *fmt, ...);

public:
	/**
	 * @brief	標準出力
	 * @note	no logger
	*/
	static inline void nl_output(const char *fmt, ...);

	/**
	 * @brief	標準出力
	 * @note	no logger
	*/
	static inline void nl_voutput(const char* fmt, va_list va);

public:
	//! Logger のセット
	static iuLogger* SetLogger(iuLogger* logger)
	{
		iuLogger* pre = var::m_pLogger;
		var::m_pLogger = logger;
		return pre;
	}
private:
	static inline void color_output_impl(Color color, const char* fmt, va_list va);
	static inline bool IsShouldUseColor(bool use_color);

private:
	static inline bool IsStringEqual(const char* str1, const char* str2) { return strcmp(str1, str2) == 0; }

	static bool IsColorModeOff(void)
	{
#if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
		return TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_OFF);
#else
		return IUTEST_FLAG(color) == "no";
#endif
	}
	static bool IsColorModeOn(void)
	{
#if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
		return TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ON);
#else
		return IUTEST_FLAG(color) == "yes";
#endif
	}
	static bool IsColorModeAnsi(void)
	{
#if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
		return TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ANSI);
#else
		return false;
#endif
	}
};

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)
{
	if( var::m_pLogger != NULL )
	{
		var::m_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);
#if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MOBILE) && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
	if( !IsColorModeAnsi() )
	{
		const WORD attr[] = {
			0,
			FOREGROUND_RED,
			FOREGROUND_GREEN,
			FOREGROUND_GREEN | FOREGROUND_RED,
			FOREGROUND_BLUE,
			FOREGROUND_RED | FOREGROUND_BLUE,
			FOREGROUND_GREEN | FOREGROUND_BLUE,
			FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
		};
		const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
		CONSOLE_SCREEN_BUFFER_INFO csbi;
		::GetConsoleScreenBufferInfo(stdout_handle, &csbi);
		const WORD wAttributes = csbi.wAttributes;

		fflush(stdout);
		::SetConsoleTextAttribute(stdout_handle, attr[color] | FOREGROUND_INTENSITY);

		voutput(fmt, va);

		fflush(stdout);
		::SetConsoleTextAttribute(stdout_handle, wAttributes);
	}
	else
#endif
	{
		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;
	}

#if !IUTEST_HAS_COLORCONSOLE
	(void)(use_color);
	return false;
#else
#if defined(IUTEST_OS_WINDOWS)
	return use_color;
#else
	const char* env = internal::posix::GetEnv("TERM");
	bool term_conf = (env != NULL) && (
		IsStringEqual(env, "xterm")
		|| IsStringEqual(env, "xterm-color")
		|| IsStringEqual(env, "xterm-256color")
		|| IsStringEqual(env, "screen")
		|| IsStringEqual(env, "screen-256color")
		|| IsStringEqual(env, "rxvt-unicode")
		|| IsStringEqual(env, "rxvt-unicode-256color")
		|| IsStringEqual(env, "linux")
		|| IsStringEqual(env, "cygwin")
		);
	return use_color && term_conf;
#endif

#endif
}

}	// end of namespace detail
}	// end of namespace iutest

#if IUTEST_HAS_LIB && IUTEST_HAS_EXTERN_TEMPLATE

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template struct ::iutest::detail::iuConsole::Variable<void>;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#else

template<typename T>
::iutest::detail::iuLogger* ::iutest::detail::iuConsole::Variable<T>::m_pLogger = NULL;

#endif

#endif // INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_

namespace iutest {
namespace detail
{

//======================================================================
// class
class iuOptionMessage
{
public:
	/**
	 * @brief	ヘルプの出力
	*/
	static void ShowHelp(void);
	/**
	 * @brief	バージョン出力
	*/
	static void ShowVersion(void);
	/**
	 * @brief	機能出力
	*/
	static void ShowFeature(void);
	/**
	 * @brief	コンパイラスペック出力
	*/
	static void ShowSpec(void);
};

inline void iuOptionMessage::ShowHelp(void)
{
	const char* readme =
		"--------------------------------------------------\n"
		"Name\n"
		"    iutest - iris unit test framework\n"
		"--------------------------------------------------\n"
		"Command Line Options\n"
		"\n"
		"    --help, -h                       : Generate help message.\n"
		"    --iutest_output=xml[:path]       : Path of xml report.\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_failure[=0|1]  : When that failed to break.\n"
		"    --iutest_throw_on_failure[=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_repeat=<count>          : Set the number of repetitions\n"
		"                                       of the test.\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"
		"--------------------------------------------------\n"
		"License\n"
		"\n"
		"    Copyright (c) 2011-2015, Takazumi-Shirayanagi\n"
		"\n"
		"    This software is released under the new BSD License, see LICENSE\n"
		"\n"
		;
	detail::iuConsole::color_output(detail::iuConsole::cyan, readme);
}

inline void iuOptionMessage::ShowVersion(void)
{
	detail::iuConsole::output("iutest version %x.%x.%x.%x\n"
		, IUTEST_MAJORVER, IUTEST_MINORVER, IUTEST_BUILD, IUTEST_REVISION);
}


#define SHOW_MACRO(macro)	detail::iuConsole::output("#define %s  %s\n", #macro, IUTEST_PP_TOSTRING(macro))

inline void iuOptionMessage::ShowFeature(void)
{
	SHOW_MACRO(IUTEST_HAS_ANY_PARAM_TEST);
	SHOW_MACRO(IUTEST_HAS_ASSERTION_RETURN);
	SHOW_MACRO(IUTEST_HAS_CHAR16_T);
	SHOW_MACRO(IUTEST_HAS_CHAR32_T);
	SHOW_MACRO(IUTEST_HAS_COMBINE);
	SHOW_MACRO(IUTEST_HAS_CONCAT);
	SHOW_MACRO(IUTEST_HAS_EXCEPTIONS);
	SHOW_MACRO(IUTEST_HAS_GENRAND);
	SHOW_MACRO(IUTEST_HAS_IF_EXISTS);
	SHOW_MACRO(IUTEST_HAS_IGNORE_TEST);
	SHOW_MACRO(IUTEST_HAS_INITIALIZER_LIST);
	SHOW_MACRO(IUTEST_HAS_LIB);
	SHOW_MACRO(IUTEST_HAS_MATCHERS);
	SHOW_MACRO(IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF);
	SHOW_MACRO(IUTEST_HAS_MATCHER_ELEMENTSARE);
	SHOW_MACRO(IUTEST_HAS_MATCHER_REGEX);
	SHOW_MACRO(IUTEST_HAS_MINIDUMP);
	SHOW_MACRO(IUTEST_HAS_NULLPTR);
	SHOW_MACRO(IUTEST_HAS_PACKAGE);
	SHOW_MACRO(IUTEST_HAS_PAIRWISE);
	SHOW_MACRO(IUTEST_HAS_PARAM_METHOD_TEST);
	SHOW_MACRO(IUTEST_HAS_PARAM_TEST);
	SHOW_MACRO(IUTEST_HAS_PEEP);
	SHOW_MACRO(IUTEST_HAS_PEEP_CLASS);
	SHOW_MACRO(IUTEST_HAS_PEEP_FUNC);
	SHOW_MACRO(IUTEST_HAS_PEEP_STATIC_FUNC);
	SHOW_MACRO(IUTEST_HAS_PRINT_TO);
	SHOW_MACRO(IUTEST_HAS_RANDOMVALUES);
	SHOW_MACRO(IUTEST_HAS_REGEX);
	SHOW_MACRO(IUTEST_HAS_REPORT_SKIPPED);
	SHOW_MACRO(IUTEST_HAS_SEH);
	SHOW_MACRO(IUTEST_HAS_SOCKET);
	SHOW_MACRO(IUTEST_HAS_SPI_LAMBDA_SUPPORT);
	SHOW_MACRO(IUTEST_HAS_STATIC_ASSERT);
	SHOW_MACRO(IUTEST_HAS_STATIC_ASSERT_TYPEEQ);
	SHOW_MACRO(IUTEST_HAS_STREAM_RESULT);
	SHOW_MACRO(IUTEST_HAS_STREAMCAPTURE);
	SHOW_MACRO(IUTEST_HAS_TESTNAME_ALIAS);
	SHOW_MACRO(IUTEST_HAS_TESTNAME_ALIAS_JP);
	SHOW_MACRO(IUTEST_HAS_TUPLE);
	SHOW_MACRO(IUTEST_HAS_TYPED_TEST);
	SHOW_MACRO(IUTEST_HAS_TYPED_TEST_P);
	SHOW_MACRO(IUTEST_HAS_VALUESGEN);
	SHOW_MACRO(IUTEST_HAS_VARIADIC_COMBINE);
	SHOW_MACRO(IUTEST_HAS_VARIADIC_PAIRWISE);
	SHOW_MACRO(IUTEST_HAS_VARIADIC_VALUES);
	SHOW_MACRO(IUTEST_CHECK_STRICT);
	SHOW_MACRO(IUTEST_PLATFORM);
	SHOW_MACRO(IUTEST_USE_THROW_ON_ASSERTION_FAILURE);
}

inline void iuOptionMessage::ShowSpec(void)
{
	SHOW_MACRO(IUTEST_HAS_ANALYSIS_ASSUME);
	SHOW_MACRO(IUTEST_HAS_CHAR16_T);
	SHOW_MACRO(IUTEST_HAS_CHAR32_T);
	SHOW_MACRO(IUTEST_HAS_CLOCK);
	SHOW_MACRO(IUTEST_HAS_CONSTEXPR);
	SHOW_MACRO(IUTEST_HAS_COUNTER_MACRO);
	SHOW_MACRO(IUTEST_HAS_CTIME);
	SHOW_MACRO(IUTEST_HAS_CXX_HDR_CHRONO);
	SHOW_MACRO(IUTEST_HAS_CXX_HDR_RANDOM);
	SHOW_MACRO(IUTEST_HAS_CXX_HDR_REGEX);
	SHOW_MACRO(IUTEST_HAS_CXX11);
	SHOW_MACRO(IUTEST_HAS_DELETED_FUNCTIONS);
	SHOW_MACRO(IUTEST_HAS_EXCEPTIONS);
	SHOW_MACRO(IUTEST_HAS_EXPLICIT_CONVERSION);
	SHOW_MACRO(IUTEST_HAS_EXTERN_TEMPLATE);
	SHOW_MACRO(IUTEST_HAS_GETTIMEOFDAY);
	SHOW_MACRO(IUTEST_HAS_HDR_CXXABI);
	SHOW_MACRO(IUTEST_HAS_HDR_SYSTIME);
	SHOW_MACRO(IUTEST_HAS_IF_EXISTS);
	SHOW_MACRO(IUTEST_HAS_INITIALIZER_LIST);
	SHOW_MACRO(IUTEST_HAS_LAMBDA);
	SHOW_MACRO(IUTEST_HAS_NOEXCEPT);
	SHOW_MACRO(IUTEST_HAS_NULLPTR);
	SHOW_MACRO(IUTEST_HAS_OVERRIDE_AND_FINAL);
	SHOW_MACRO(IUTEST_HAS_RTTI);
	SHOW_MACRO(IUTEST_HAS_RVALUE_REFS);
	SHOW_MACRO(IUTEST_HAS_SEH);
	SHOW_MACRO(IUTEST_HAS_STD_EMPLACE);
	SHOW_MACRO(IUTEST_HAS_STRINGSTREAM);
	SHOW_MACRO(IUTEST_HAS_STRONG_ENUMS);
	SHOW_MACRO(IUTEST_HAS_STRSTREAM);
	SHOW_MACRO(IUTEST_HAS_VARIADIC_TEMPLATES);
	SHOW_MACRO(IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES);

#ifdef _MSC_FULL_VER
	SHOW_MACRO(_MSC_FULL_VER);
#endif
#ifdef _LIBCPP_VERSION
	SHOW_MACRO(_LIBCPP_VERSION);
#endif
#ifdef __GLIBCXX__
	SHOW_MACRO(__GLIBCXX__);
#endif

#undef SHOW_MACRO
}

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_OPTION_MESSAGE_HPP_00EB9B17_0615_4678_9AD0_1F5B295B404F_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_case.hpp
 * @brief		iris unit test testcase
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CASE_HPP_F57C9B7E_7CAA_4429_BE75_FCAAEED1B220_
#define INCG_IRIS_IUTEST_CASE_HPP_F57C9B7E_7CAA_4429_BE75_FCAAEED1B220_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_info.hpp
 * @brief		iris unit test 情報 ファイル
 *
 * @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_INFO_HPP_764A79A8_E822_4C0F_8CB7_82C635BA28BA_
#define INCG_IRIS_IUTEST_INFO_HPP_764A79A8_E822_4C0F_8CB7_82C635BA28BA_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_body.hpp
 * @brief		iris unit test テスト単体クラス ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_BODY_HPP_3EEA6706_9954_4330_B292_129667FA6B96_
#define INCG_IRIS_IUTEST_BODY_HPP_3EEA6706_9954_4330_B292_129667FA6B96_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_mediator.hpp
 * @brief		iris unit test 仲介者 ファイル
 *
 * @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_MEDIATOR_HPP_BFBE202B_0E60_4E44_8BDA_CB801D264F3E_
#define INCG_IRIS_IUTEST_MEDIATOR_HPP_BFBE202B_0E60_4E44_8BDA_CB801D264F3E_

namespace iutest {

//======================================================================
// declare
class TestInfo;
class TestCase;
class TestPartResult;

namespace detail
{

//======================================================================
// class
/**
 * @brief	TestInfo 仲介者インターフェイス
*/
class iuITestInfoMediator
{
protected:
	TestInfo* m_test_info;
public:
	iuITestInfoMediator(TestInfo* p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : m_test_info(p) {}
public:
	virtual bool HasFatalFailure(void) const = 0;
	virtual bool HasNonfatalFailure(void) const = 0;
	virtual bool HasFailure(void) const = 0;
	virtual bool IsSkipped(void) const = 0;
	TestInfo* ptr(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_test_info; }
};

/**
 * @brief	TestCase 仲介者インターフェイス
*/
class iuITestCaseMediator
{
protected:
	TestCase* m_test_case;
public:
	iuITestCaseMediator(TestCase* p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : m_test_case(p) {}
public:
	virtual const char* test_case_name(void) const = 0;
	virtual const char* type_param(void) const = 0;
	TestCase* ptr(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_test_case; }
};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_MEDIATOR_HPP_BFBE202B_0E60_4E44_8BDA_CB801D264F3E_

namespace iutest
{

//======================================================================
// declare
template<typename T>class WithParamInterface;
template<typename T>class TestWithParam;

namespace detail
{

::std::string MakeIndexTestName(const char* basename, int index);

}

//======================================================================
// class
/**
 * @brief	テストベース
*/
class Test
{
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(Test);

public:
	Test(void)
		: test_info_(NULL)
		, m_test_info(NULL)
#if IUTEST_HAS_GENRAND
		, m_random_seed(0)
#endif
	{
		CurrentTestObserver::s_current = this;
	}

	virtual ~Test(void)
	{
		CurrentTestObserver::s_current = NULL;
	}

public:
	/**
	 * @brief	実行中の TestInfo の取得
	*/
	static const TestInfo* GetCurrentTestInfo(void)
	{
		const Test* curr = GetCurrentTest();
		if( curr == NULL || curr->m_test_info == NULL )
		{
			return NULL;
		}
		return curr->m_test_info->ptr();
	}

	/**
	 * @brief	実行中の Test の取得
	*/
	static Test* GetCurrentTest(void) { return CurrentTestObserver::GetCurrentTest(); }


	/**
	 * @brief	致命的なエラーが出たかどうか
	 * @return	真偽値
	*/
	static bool HasFatalFailure(void)
	{
		return GetCurrentTest()->m_test_info->HasFatalFailure();
	}

	/**
	 * @brief	致命的ではないエラーが出たかどうか
	 * @return	真偽値
	*/
	static bool HasNonfatalFailure(void)
	{
		return GetCurrentTest()->m_test_info->HasNonfatalFailure();
	}

	/**
	 * @brief	エラーが出たかどうか
	 * @return	真偽値
	*/
	static bool HasFailure(void)
	{
		return GetCurrentTest()->m_test_info->HasFailure();
	}

	/**
	 * @brief	スキップされたかどうか
	 * @return	真偽値
	*/
	static bool IsSkipped(void)
	{
		return GetCurrentTest()->m_test_info->IsSkipped();
	}

#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	/**
	 * @brief	テスト結果の情報追加
	 * @param [in]	key		= プロパティのキー
	 * @param [in]	value	= 値
	*/
	static void RecordProperty(const ::std::string& key, const ::std::string& value);
#endif

	/**
	 * @brief	テスト結果の情報追加
	 * @param [in]	key		= プロパティのキー
	 * @param [in]	value	= 値
	*/
	template<typename T>
	static void RecordProperty(const ::std::string& key, const T& value)
	{
		RecordPropertyString(key, PrintToString(value));
	}

#if IUTEST_HAS_GENRAND

	/**
	 * @brief	乱数の生成
	 * @note	乱数シードは --iutest_random_seed で指定した値になります。
	 *			指定しなかった場合は実行時に決定します。
	*/
	unsigned int	genrand(void)				{ return m_random.genrand(); }
	/**
	 * @overload
	 * @param [in]	max	= 上限値
	 * @return		[0,max) の乱数を生成
	*/
	unsigned int	genrand(unsigned int max)	{ return m_random.genrand(max); }
	/**
	 * @overload
	 * @return		max	= [0,1] の乱数を生成
	*/
	float			genrandf(void)				{ return m_random.genrandf(); }
	
	unsigned int	random_seed(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_random_seed; }

	
	detail::iuRandom& random_engine(void)		{ return m_random; }

#endif

protected:
	virtual void SetUp(void)	{}	//!< 実行前処理
#if IUTEST_HAS_AUTOFIXTURE_PARAM_TEST
	virtual void Body(void)		{}	//!< テスト実装部
#else
	virtual void Body(void)	 = 0;	//!< テスト実装部
#endif
	virtual void TearDown(void)	{}	//!< 実行後処理

public:
	static void SetUpTestCase(void)		{}	//!< test case setup
	static void TearDownTestCase(void)	{}	//!< test case tear down

private:
	/**
	 * @brief	テストの実行
	*/
	void Run(detail::iuITestInfoMediator* test_info);

	/**
	 * @brief	テスト結果の情報追加
	 * @param [in]	key		= プロパティのキー
	 * @param [in]	value	= 値
	*/
	static void RecordPropertyString(const ::std::string& key, const ::std::string& value);

private:
	struct should_be_SetUp {};
	virtual should_be_SetUp* Setup(void) IUTEST_CXX_FINAL { return NULL; }

private:
	template<typename DMY>
	class Observer
	{
	public:
		static Test* s_current;
	public:
		static Test* GetCurrentTest(void) IUTEST_CXX_NOEXCEPT_SPEC { 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;
#if IUTEST_HAS_GENRAND
	detail::iuRandom				m_random;
	unsigned int					m_random_seed;
#endif
};

/**
 * @brief	パラメータテストインターフェース
 * @tparam	T = パラメータ型
*/
template<typename T>
class WithParamInterface
{
public:
	typedef T ParamType;	//!< パラメータ型
protected:
	virtual ~WithParamInterface(void) {}

public:
	/**
	 * @brief	パラメータの取得
	*/
	static const ParamType& GetParam(void)
	{
		IUTEST_CHECK_(s_params != NULL) << "GetParam() can only use the value-parameterized test";
		IUTEST_ANALYSIS_ASSUME(s_params != NULL);
		return *s_params;
	}

#if IUTEST_HAS_TUPLE
	/**
	 * @brief	パラメータの取得
	*/
	template<int N>
	static const typename tuples::tuple_element<N, ParamType>::type& GetParam(void)
	{
		return tuples::get<N>(GetParam());
	}
#endif

	/**
	 * @brief	テスト名の生成
	*/
	template<typename U>
	static const ::std::string MakeTestName(const char* basename, int index, const U&)
	{
		return detail::MakeIndexTestName(basename, index);
	}

	
	static void SetParam(const ParamType* params) IUTEST_CXX_NOEXCEPT_SPEC { s_params = params; }

private:
	static const ParamType* s_params;
};

template<typename T>
const T* WithParamInterface<T>::s_params = NULL;

/**
 * @brief	パラメータテストベース
 * @tparam	T = パラメータ型
*/
template<typename T>
class TestWithParam : public Test, public WithParamInterface<T>
{
};

namespace detail
{

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)

/**
 * @brief	有益な TestFixture が定義されているかどうか
*/
template<typename T>
class is_useful_testfixture : public iutest_type_traits::false_type {};

namespace is_useful_testfixture_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_testfixture_helper::is_override_setup<T>::type
{
};

#endif

}

}	// end of namespace iutest

template<typename DMY>
::iutest::Test* ::iutest::Test::Observer<DMY>::s_current = NULL;

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_body.ipp
 * @brief		iris unit test テスト単体クラス ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_BODY_IPP_3EEA6706_9954_4330_B292_129667FA6B96_
#define INCG_IRIS_IUTEST_BODY_IPP_3EEA6706_9954_4330_B292_129667FA6B96_

//======================================================================
// include

namespace iutest
{

IUTEST_IPP_INLINE void Test::RecordPropertyString(const ::std::string& key, const ::std::string& value)
{
	TestProperty prop(key, value);
	TestRecordPropertyHelper::RecordProperty(prop);
}

#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
IUTEST_IPP_INLINE void Test::RecordProperty(const ::std::string& key, const ::std::string& value)
{
	RecordPropertyString(key, value);
}
#endif

IUTEST_IPP_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();
	}
#if IUTEST_HAS_GENRAND
	m_random_seed = seed;
	m_random.init(seed);
#endif

	SetUp();

	if( !HasFailure() && !IsSkipped() )
	{
		Body();
	}

	TearDown();

	test_info_ = NULL;
	m_test_info = NULL;
}

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_BODY_IPP_3EEA6706_9954_4330_B292_129667FA6B96_
#endif

#endif // INCG_IRIS_IUTEST_BODY_HPP_3EEA6706_9954_4330_B292_129667FA6B96_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_factory.hpp
 * @brief		iris unit test テストファクトリー ファイル
 *
 * @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_FACTORY_HPP_9C2B4B94_95A0_479A_9C9D_43FB31845A73_
#define INCG_IRIS_IUTEST_FACTORY_HPP_9C2B4B94_95A0_479A_9C9D_43FB31845A73_

//======================================================================
// include

namespace iutest {

//======================================================================
// declare
class Test;

namespace detail
{

//======================================================================
// class
/**
 * @internal
 * @brief	テスト生成クラスインターフェース
*/
class iuFactoryBase
{
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(iuFactoryBase);
public:
	iuFactoryBase(void) IUTEST_CXX_NOEXCEPT_SPEC {}
	virtual ~iuFactoryBase(void) {}
public:
	virtual auto_ptr<Test> Create(void) = 0;
};

/**
 * @internal
 * @brief	テスト生成クラス
 * @tparam	Tester	= テストクラス
*/
template<class Tester>
class iuFactory : public iuFactoryBase
{
public:
	virtual auto_ptr<Test> Create(void) IUTEST_CXX_OVERRIDE
	{
		auto_ptr<Test> p = new Tester();
		return p;
	}
};

/**
 * @internal
 * @brief	パラメータセットテスト生成クラスインターフェース
 * @tparam	ParamType	= パラメータの型
*/
template<typename ParamType>
class iuParamTestFactoryBase : public iuFactoryBase
{
public:
	iuParamTestFactoryBase(void) {}
	iuParamTestFactoryBase(ParamType param) : m_param(param) {}
public:
	void				SetParam(ParamType param) { m_param = param; }
	const ParamType&	GetParam(void)		const { return m_param; }
protected:
	ParamType m_param;
};


/**
 * @internal
 * @brief	パラメータセットテスト生成クラス
 * @tparam	Tester	= テストクラス
*/
template<class Tester>
class iuParamTestFactory : public iuParamTestFactoryBase<typename Tester::ParamType>
{
	typedef typename Tester::ParamType ParamType;
	typedef iuParamTestFactoryBase<ParamType> _Mybase;
public:
	iuParamTestFactory(void) {}
	iuParamTestFactory(ParamType param) : _Mybase(param) {}

public:
	virtual auto_ptr<Test> Create(void) IUTEST_CXX_OVERRIDE
	{
		Tester::SetParam(&this->m_param);
		auto_ptr<Test> p = new Tester();
		return p;
	}
};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_FACTORY_HPP_9C2B4B94_95A0_479A_9C9D_43FB31845A73_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_exception.hpp
 * @brief		iris unit test exception
 *
 * @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_EXCEPTION_HPP_B73B2E25_97C8_4DFC_BC32_5E53039A1A64_
#define INCG_IRIS_IUTEST_EXCEPTION_HPP_B73B2E25_97C8_4DFC_BC32_5E53039A1A64_

//======================================================================
// include

#if IUTEST_HAS_EXCEPTIONS
#include <exception>
//#include <stdexcept>	// std::invalid_argment

namespace iutest {
namespace detail
{

/**
 * @brief	C++例外メッセージのフォーマット
 * @param [in]	description	= 説明
 * @return	メッセージ
*/
inline ::std::string FormatCxxException(const char* description)
{
	iu_stringstream strm;
	if( description != NULL )
	{
		strm << "C++ exception with description \"" << description << "\"";
	}
	else
	{
		strm << "Unknown C++ exception";
	}
	return strm.str();
}

}	// end of namespace detail
}	// end of namespace iutest

#if IUTEST_HAS_EXCEPTIONS && IUTEST_HAS_SEH
#include <iomanip>

namespace iutest {
namespace detail
{

/**
 * @brief	SEH 例外
*/
class seh_exception : public ::std::exception
{
public:
	seh_exception(const char *const& _What) : ::std::exception(_What) {}
	seh_exception(void) : ::std::exception() {}
public:
	static void translator(DWORD code, _EXCEPTION_POINTERS* ep)
	{
		IUTEST_UNUSED_VAR(ep);
		iu_stringstream strm;
#if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
		strm << "SEH exception with code 0x" << ::std::setbase(16) << code;
#else
		strm << "SEH exception with code " << code;
#endif
		throw seh_exception(strm.str().c_str());
	}
	static int should_process_through_break_and_cppexceptions(DWORD code)
	{
		bool should_handle = true;
		// break point と C++ 例外はハンドリングしない
		if( code == EXCEPTION_BREAKPOINT )
			should_handle = false;
		if( code == kCxxExceptionCode )
			should_handle = false;
		return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
	}
public:
	static const DWORD kCxxExceptionCode = 0xe06d7363;	//!< c++ exception コード
};

}	// end of namespace detail
}	// end of namespace iutest

#endif

#endif

#endif // INCG_IRIS_IUTEST_EXCEPTION_HPP_B73B2E25_97C8_4DFC_BC32_5E53039A1A64_

namespace iutest
{

//======================================================================
// class
/**
 * @brief	テスト情報クラス
*/
class TestInfo
	: public detail::iu_list_node<TestInfo>
{
public:
	/**
	 * @brief	コンストラクタ
	 * @param [in]	testcase	= テストケース仲介者
	 * @param [in]	name		= テスト名
	 * @param [in]	factory		= テスト生成器
	*/
	TestInfo(detail::iuITestCaseMediator* testcase, const char* name, detail::iuFactoryBase* factory)
		: m_testname(name)
		, m_factory(factory)
		, m_testcase(testcase)
		, m_should_run(true)
		, m_ran(false)
		, m_disable(false)
		, m_skip(false)
		, m_matches_filter(true)
	{
		m_mediator.SetPointer(this);
		if( detail::IsStringForwardMatching(name, "DISABLED_")
			|| (strstr(name, "/DISABLED_") != NULL) )
		{
			m_disable = true;
		}
	}

public:
	
	const	char*	test_case_name(void)	const { return m_testcase->test_case_name(); }
	
	const	char*	name(void)				const { return m_testname.c_str(); }
	
	bool			should_run(void)		const IUTEST_CXX_NOEXCEPT_SPEC { return m_should_run; }
	
	bool			is_ran(void)			const IUTEST_CXX_NOEXCEPT_SPEC { return m_ran; }
	
	bool			is_disabled_test(void)	const IUTEST_CXX_NOEXCEPT_SPEC { return m_disable; }
	
	bool			is_skipped(void)		const IUTEST_CXX_NOEXCEPT_SPEC { return m_skip || m_test_result.Skipped(); }
	
	bool			is_reportable(void)		const IUTEST_CXX_NOEXCEPT_SPEC { return m_matches_filter; }
	
	TimeInMillisec	elapsed_time(void)		const { return m_test_result.elapsed_time(); }
	
	const TestResult*	result(void)		const IUTEST_CXX_NOEXCEPT_SPEC { return &m_test_result; }

	
	const	char*	value_param(void)		const { return m_value_param.empty() ? NULL : m_value_param.c_str(); }
	
	const	char*	type_param(void)		const { return m_testcase->type_param(); }

	
	::std::string testcase_name_with_default_package_name(void) const { return TestEnv::AddDefaultPackageName(test_case_name()); }
public:
	/**
	 * @brief	致命的なエラーが出たかどうか
	 * @return	真偽値
	*/
	bool	HasFatalFailure(void) const
	{
		return m_test_result.HasFatalFailure();
	}

	/**
	 * @brief	致命的ではないエラーが出たかどうか
	 * @return	真偽値
	*/
	bool	HasNonfatalFailure(void) const
	{
		return m_test_result.HasNonfatalFailure();
	}

	/**
	 * @brief	エラーが出たかどうか
	 * @return	真偽値
	*/
	bool	HasFailure(void) const
	{
		return m_test_result.Failed();
	}

	/**
	 * @brief	成功したかどうか
	 * @return	真偽値
	*/
	bool	Passed(void) const
	{
		if( is_skipped() )
		{
			return false;
		}
		return m_test_result.Passed();
	}

public:
	
	::std::string test_full_name(void) const
	{
		::std::string fullname = test_case_name();
		fullname += ".";
		fullname += name();
		return fullname;
	}

	
	::std::string test_name_with_where(void) const
	{
		::std::string str = m_testname;
		if( value_param() != NULL )
		{
			str += ", where GetParam() = ";
			str += m_value_param;
		}
		return str;
	}

public:
	/**
	 * @brief	有効なプロパティ名かどうかチェック
	 * @param [in] name	= プロパティ名
	 * @retval	true=有効
	 * @retval	false=無効
	*/
	static bool ValidateTestPropertyName(const ::std::string& name)
	{
		const char* ban[] = { "name", "status", "time", "classname", "type_param", "value_param" };
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
		return TestProperty::ValidateName(name, ban);
#else
		return TestProperty::ValidateName(name, ban, ban+IUTEST_PP_COUNTOF(ban));
#endif
	}
public:
	
	void set_value_param(const char* str) { m_value_param = str; }

private:
	/**
	 * @brief	実行
	*/
	bool Run(void);

private:

	void RunImpl(void);

#if IUTEST_HAS_EXCEPTIONS && IUTEST_HAS_SEH
#if IUTEST_HAS_MINIDUMP
	void MiniDump(_EXCEPTION_POINTERS* ep);
#endif
	void RunOnMSC(Test* test);
#endif

private:
	/**
	 * @brief	テストのクリア
	*/
	void clear(void);

	/*
	 * @brief	テストのフィルタリング
	 * @return	実行する場合は真
	*/
	bool filter(void);

	/**
	* @brief	テストのスキップ
	*/
	void skip(void) { m_skip = true; }

private:
	class Mediator IUTEST_CXX_FINAL : public detail::iuITestInfoMediator
	{
	public:
		Mediator(TestInfo* p=NULL) IUTEST_CXX_NOEXCEPT_SPEC : iuITestInfoMediator(p) {}
	public:
		virtual	bool HasFatalFailure(void) const IUTEST_CXX_OVERRIDE
		{
			return ptr()->HasFatalFailure();
		}
		virtual	bool HasNonfatalFailure(void) const IUTEST_CXX_OVERRIDE
		{
			return ptr()->HasNonfatalFailure();
		}
		virtual bool HasFailure(void) const IUTEST_CXX_OVERRIDE
		{
			return ptr()->HasFailure();
		}
		virtual bool IsSkipped(void) const IUTEST_CXX_OVERRIDE
		{
			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;		//!< value param string
	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;	//!< フィルターにマッチしたかどうか

	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TestInfo);
};

}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_info.ipp
 * @brief		iris unit test 情報 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_INFO_IPP_764A79A8_E822_4C0F_8CB7_82C635BA28BA_
#define INCG_IRIS_IUTEST_INFO_IPP_764A79A8_E822_4C0F_8CB7_82C635BA28BA_

//======================================================================
// include

namespace iutest
{

/**
 * @brief	実行
*/
IUTEST_IPP_INLINE bool TestInfo::Run(void)
{
	if( !should_run() )
	{
		return true;
	}

	// テスト開始
	TestEnv::event_listeners().OnTestStart(*this);

	RunImpl();

	// テスト終了
	TestEnv::event_listeners().OnTestEnd(*this);
	return !HasFailure();
}

IUTEST_IPP_INLINE void TestInfo::RunImpl(void)
{
	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();
#if IUTEST_HAS_SEH
			RunOnMSC(p.get());
#else
			p->Run(&m_mediator);
#endif
			elapsedmsec = sw.stop();
		}
		catch (const ::std::exception& e)
		{
			elapsedmsec = sw.stop();
			iutest::AssertionHelper(NULL, -1, detail::FormatCxxException(e.what()), TestPartResult::kFatalFailure).OnFixed(AssertionHelper::Fixed());
			if( TestFlag::IsEnableFlag(TestFlag::THROW_ON_FAILURE) )
			{
				throw;
			}
		}
		catch (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(NULL, -1, detail::FormatCxxException(NULL), 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
	}
}

#if IUTEST_HAS_EXCEPTIONS && IUTEST_HAS_SEH
#if IUTEST_HAS_MINIDUMP

IUTEST_IPP_INLINE void TestInfo::MiniDump(_EXCEPTION_POINTERS* ep)
{
#if defined(_MSC_VER)

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
		char path[MAX_PATH];
		strcpy(path, test_case_name());
		strcat(path, "_");
		strcat(path, name());
		strcat(path, ".dump");
IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

		detail::MiniDump::Create(path, ep);
#endif
}

#endif

IUTEST_IPP_INLINE void TestInfo::RunOnMSC(Test* test)
{
	_EXCEPTION_POINTERS* ep = NULL;
	__try
	{
		test->Run(&m_mediator);
	}
	__except (ep = GetExceptionInformation()
#if IUTEST_HAS_MINIDUMP
		, MiniDump(ep)
#endif
		, detail::seh_exception::should_process_through_break_and_cppexceptions(GetExceptionCode()))
	{
		detail::seh_exception::translator(GetExceptionCode(), ep);
	}
}
#endif

IUTEST_IPP_INLINE void TestInfo::clear(void)
{
	m_ran = false;
	m_skip = false;
	m_test_result.Clear();
}

IUTEST_IPP_INLINE bool TestInfo::filter(void)
{
	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;
}

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_INFO_IPP_764A79A8_E822_4C0F_8CB7_82C635BA28BA_
#endif

#endif // INCG_IRIS_IUTEST_INFO_HPP_764A79A8_E822_4C0F_8CB7_82C635BA28BA_

namespace iutest
{

//======================================================================
// class
/**
 * @brief	テストケース
*/
class TestCase
	: public detail::iu_list_node<TestCase>
{
protected:
	typedef detail::iu_list<TestInfo>	iuTestInfos;	//!< TestInfo リスト
	//typedef ::std::vector<TestInfo*>	iuTestInfos;	//!< TestInfo リスト
protected:
	/**
	 * @brief	コンストラクタ
	 * @param [in]	testcase_name	= テストケース名
	 * @param [in]	id				= テストケースID
	 * @param [in]	setup			= テスト事前実行関数
	 * @param [in]	teardown		= テスト事後実行関数
	*/
	TestCase(const char* testcase_name, TestTypeId id, SetUpMethod setup, TearDownMethod teardown)
	: m_testcase_name(testcase_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(false)
	{
		if( detail::IsStringForwardMatching(testcase_name, "DISABLED_")
			|| (strstr(testcase_name, "/DISABLED_") != NULL) )
		{
			m_disable = true;
		}
	}

public:
	/**
	 * @brief	デストラクタ
	*/
	virtual ~TestCase(void) {}

public:
	
	const char*		name(void)					const { return m_testcase_name.c_str(); }

	
	int				total_test_count(void)		const IUTEST_CXX_NOEXCEPT_SPEC { return m_testinfos.size(); }
	
	int				reportable_test_count(void)	const;
	
	int				test_to_run_count(void)		const IUTEST_CXX_NOEXCEPT_SPEC { return m_should_run_num; }
	
	int				failed_test_count(void)		const;
	
	int				disabled_test_count(void)	const IUTEST_CXX_NOEXCEPT_SPEC { return m_disable_num; }
	
	int				reportable_disabled_test_count(void) const;
	
	int				successful_test_count(void)	const;
	
	int				skip_test_count(void)		const;
	
	int				reportable_skip_test_count(void) const;
	
	int				test_run_skipped_count(void) const;
	
	int				reportable_test_run_skipped_count(void) const;
	
	TimeInMillisec	elapsed_time(void)			const IUTEST_CXX_NOEXCEPT_SPEC { return m_elapsedmsec; }
	
	TimeInMillisec	start_timestamp(void)		const IUTEST_CXX_NOEXCEPT_SPEC{ return m_start_timestamp; }

	
	const TestInfo*	GetTestInfo(int index)		const { return m_testinfos[index]; }
	
	bool			should_run(void)			const IUTEST_CXX_NOEXCEPT_SPEC { return m_should_run_num != 0; }

	
	bool			Passed(void)				const { return failed_test_count() == 0 && m_ad_hoc_testresult.Passed(); }
	
	bool			Failed(void)				const { return !Passed(); }

	
	virtual const char*	type_param(void)		const { return NULL; }

	
	::std::string testcase_name_with_where(void) const
	{
		::std::string str = m_testcase_name;
		if( type_param() != NULL )
		{
			str += ", where TypeParam = ";
			str += type_param();
		}
		return str;
	}

	
	::std::string testcase_name_with_default_package_name(void) const { return TestEnv::AddDefaultPackageName(name()); }

	
	const TestResult* ad_hoc_testresult(void) const IUTEST_CXX_NOEXCEPT_SPEC { return &m_ad_hoc_testresult; }

public:
	/**
	 * @brief	有効なプロパティ名かどうかチェック
	 * @param [in] name	= プロパティ名
	 * @retval	true=有効
	 * @retval	false=無効
	*/
	static bool ValidateTestPropertyName(const ::std::string& name)
	{
		const char* ban[] = { "name", "tests", "failures", "disabled", "skip", "errors", "time" };
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
		return TestProperty::ValidateName(name, ban);
#else
		return TestProperty::ValidateName(name, ban, ban+IUTEST_PP_COUNTOF(ban));
#endif
	}

private:
	/**
	 * @brief	テストの実行
	 * @return	成否
	*/
	bool Run(void);

	/**
	 * @brief	実行
	 * @return	成否
	*/
	bool RunImpl(void);

private:
	/**
	 * @brief	セットアップのスキップチェック
	*/
	bool CheckSetUpSkipped(void);

public:
	/**
	 * @private
	 * @brief	テストケース比較用オブジェクト
	*/
	struct FindOp
	{
		TestTypeId	m_id;
		const char*	m_name;

		bool operator () (const TestCase* p) const
		{
			if( p->get_typeid() == m_id && (strcmp(p->name(), m_name) == 0) )
			{
				return true;
			}
			return false;
		}
	};
private:
	/**
	 * @brief	テストのクリア
	*/
	void clear(void);
	/*
	 * @brief	テストのフィルタリング
	 * @return	実行する場合は真
	*/
	bool filter(void);

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(void)	const		{ return m_testinfos.begin(); }
	iuTestInfos::const_iterator	end(void)	const		{ return m_testinfos.end(); }
	TestTypeId					get_typeid(void) const IUTEST_CXX_NOEXCEPT_SPEC	{ return m_id; }

private:
	static bool IsSuccessfulTest(const TestInfo* p) { return p->is_ran() && p->Passed(); }
	static bool IsFaildTest(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;

#if defined(IUTEST_NO_PRIVATE_IN_AGGREGATE)
	friend struct FindOp;
#endif

	::std::string	m_testcase_name;	//!< テストケース名
	iuTestInfos		m_testinfos;		//!< テスト情報リスト
	SetUpMethod		m_setup;			//!< SetUp 関数
	TearDownMethod	m_teardown;			//!< TearDown 関数
	TestTypeId		m_id;				//!< TypeID
	int				m_disable_num;		//!< 無視したテストの総数
	int				m_should_run_num;	//!< 実行すべきテストの総数
	TimeInMillisec	m_elapsedmsec;		//!< テスト時間
	TimeInMillisec	m_start_timestamp;	//!< テスト開始時刻
	bool			m_disable;			//!< 無効真偽値
	TestResult		m_ad_hoc_testresult;	//!< テストが実行中でないときのリザルト

	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TestCase);
};

/**
 * @brief	型つきテストケース
*/
template<typename T>
class TypedTestCase : public TestCase
{
public:
	typedef T	TypeParam;	//!< 型

protected:
	/**
	 * @brief	コンストラクタ
	 * @param [in]	testcase_name	= テストケース名
	 * @param [in]	id				= テストケースID
	 * @param [in]	setup			= テスト事前実行関数
	 * @param [in]	teardown		= テスト事後実行関数
	*/
	TypedTestCase(const char* testcase_name, TestTypeId id, SetUpMethod setup, TearDownMethod teardown)
		: TestCase(testcase_name, id, setup, teardown)
		, m_type_param(detail::GetTypeName<TypeParam>())
	{}

public:
	
	virtual const char* type_param(void) const IUTEST_CXX_OVERRIDE { return m_type_param.empty() ? NULL : m_type_param.c_str(); }

private:
	friend class UnitTestImpl;

	::std::string m_type_param;		//!< type param string
};

namespace detail
{

/**
 * @brief	テストケース仲介者
*/
class TestCaseMediator IUTEST_CXX_FINAL : public detail::iuITestCaseMediator
{
public:
	TestCaseMediator(TestCase* p) IUTEST_CXX_NOEXCEPT_SPEC : iuITestCaseMediator(p) {}
public:
	virtual const char* test_case_name(void) const IUTEST_CXX_OVERRIDE { return m_test_case->name(); }
	virtual const char* type_param(void)	 const IUTEST_CXX_OVERRIDE { return m_test_case->type_param(); }
};

}	// end of namespace detail
}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_case.ipp
 * @brief		iris unit test testcase
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CASE_IPP_F57C9B7E_7CAA_4429_BE75_FCAAEED1B220_
#define INCG_IRIS_IUTEST_CASE_IPP_F57C9B7E_7CAA_4429_BE75_FCAAEED1B220_

//======================================================================
// include

namespace iutest
{

IUTEST_IPP_INLINE bool TestCase::Run(void)
{
	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( 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;
}

IUTEST_IPP_INLINE bool TestCase::RunImpl(void)
{
	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;
}

IUTEST_IPP_INLINE bool TestCase::CheckSetUpSkipped(void)
{
	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;
}

IUTEST_IPP_INLINE void TestCase::clear(void)
{
	m_ad_hoc_testresult.Clear();
	for( iuTestInfos::iterator it = m_testinfos.begin(), end=m_testinfos.end(); it != end; ++it )
	{
		(it)->clear();
	}
}

IUTEST_IPP_INLINE bool TestCase::filter(void)
{
	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 )
		{
			// DISABLE の伝搬
			(it)->m_disable = true;
		}
		if( (it)->is_disabled_test() )
		{
			++m_disable_num;
		}
		if( (it)->filter() )
		{
			++m_should_run_num;
		}
	}
	return should_run();
}

IUTEST_IPP_INLINE int TestCase::reportable_test_count(void) const
{
	return detail::CountIfOverList(m_testinfos, &TestInfo::is_reportable);
}

IUTEST_IPP_INLINE int TestCase::failed_test_count(void) const
{
	if( !should_run() )
	{
		return 0;
	}
	//if( m_ad_hoc_testresult.Failed() ) return m_testinfos.count();
	return detail::CountIf(m_testinfos, IsFaildTest);
}

IUTEST_IPP_INLINE int TestCase::successful_test_count(void) const
{
	if( !should_run() )
	{
		return 0;
	}
	//if( m_ad_hoc_testresult.Failed() ) return 0;
	return detail::CountIf(m_testinfos, IsSuccessfulTest);
}

IUTEST_IPP_INLINE int TestCase::skip_test_count(void) const
{
	if( !should_run() )
	{
		return total_test_count();
	}
	return detail::CountIf(m_testinfos, IsSkipTest);
}

IUTEST_IPP_INLINE int TestCase::reportable_skip_test_count(void) const
{
	if( !should_run() )
	{
		return reportable_test_count();
	}
	return detail::CountIf(m_testinfos, IsReportableSkipTest);
}

IUTEST_IPP_INLINE int TestCase::test_run_skipped_count(void) const
{
	if( !should_run() )
	{
		return 0;
	}
	return detail::CountIf(m_testinfos, IsRunSkippedTest);
}

IUTEST_IPP_INLINE int TestCase::reportable_test_run_skipped_count(void) const
{
	if( !should_run() )
	{
		return 0;
	}
	return detail::CountIf(m_testinfos, IsReportableRunSkippedTest);
}

IUTEST_IPP_INLINE int TestCase::reportable_disabled_test_count(void) const
{
	return detail::CountIf(m_testinfos, IsReportableDisabledTest);
}

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_CASE_IPP_F57C9B7E_7CAA_4429_BE75_FCAAEED1B220_
#endif

#endif // INCG_IRIS_IUTEST_CASE_HPP_F57C9B7E_7CAA_4429_BE75_FCAAEED1B220_

namespace iutest
{

//======================================================================
// class

class UnitTestImpl
{
protected:
	typedef detail::iu_list<TestCase>	iuTestCases;
	//typedef ::std::vector<TestCase*>	iuTestCases;
	typedef ::std::vector<Environment*>	iuEnvironmentList;
protected:
	UnitTestImpl(void) : m_total_test_num(0), m_disable_num(0), m_should_run_num(0)
		, m_current_testcase(NULL), m_elapsedmsec(0)
	{
		ptr() = this;
	}
	~UnitTestImpl(void) { TerminateImpl(); }

public:
	/**
	 * @brief	テスト中のテストの TestResult の取得
	*/
	static TestResult* current_test_result(void);

public:
	/**
	 * @brief	有効なプロパティ名かどうかチェック
	 * @param [in] name	= プロパティ名
	 * @retval	true=有効
	 * @retval	false=無効
	*/
	static bool ValidateTestPropertyName(const ::std::string& name)
	{
		const char* ban[] = { "name", "tests", "failures", "disabled", "skip", "errors", "time", "timestamp", "random_seed" };
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
		return TestProperty::ValidateName(name, ban);
#else
		return TestProperty::ValidateName(name, ban, ban+IUTEST_PP_COUNTOF(ban));
#endif
	}

public:
	
	template<typename T>
	TestCase* AddTestCase(const char* testcase_name, TestTypeId id, SetUpMethod setup, TearDownMethod teardown
		IUTEST_APPEND_EXPLICIT_TEMPLATE_TYPE_(T)
		)
	{
		TestCase* p = FindTestCase(testcase_name, id);
		if( p == NULL )
		{
			p = new T (testcase_name, id, setup, teardown);
			m_testcases.push_back(p);
		}
		return p;
	}
	
	void AddTestInfo(TestCase* pCase, TestInfo* pInfo);
	
	static void SkipTest(void);

protected:
	/**
	 * @brief	テストのリストアップ
	*/
	int Listup(void) const;

	/**
	 * @brief	テストのリストアップ(with where)
	*/
	int ListupWithWhere(void) const;

	/**
	 * @brief	事前処理
	*/
	bool PreRunner(void);

	/**
	 * @brief	テスト結果のクリア
	*/
	void ClearNonAdHocTestResult(void);

	/**
	 * @brief	ad_hoc_testresult のクリア
	*/
	void ClearAdHocTestResult(void)
	{
		m_ad_hoc_testresult.Clear();
	}

private:
	/**
	 * @brief	RecordProperty
	*/
	static void RecordProperty(const TestProperty& prop);

	/**
	 * @brief	FindTestCase
	*/
	TestCase* FindTestCase(const char* testcase_name, TestTypeId id);

private:
	/**
	 * @brief	セットアップ
	*/
	void InitializeImpl(void);
	/**
	 * @brief	後片付け
	*/
	void TerminateImpl(void);

private:
#if IUTEST_HAS_EXCEPTIONS && (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(IUTEST_OS_WINDOWS_MOBILE)

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

	// _invalid_parameter_handler
	static void OnInvalidParameter(const wchar_t * expression, const wchar_t * function
		, const wchar_t * file, unsigned int line, uintptr_t pReserved);

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

#endif

private:
	static UnitTestImpl*& ptr(void) IUTEST_CXX_NOEXCEPT_SPEC
	{
		static UnitTestImpl* ptr = NULL;
		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
{

/**
 * @brief	テスト名の作成
 * @param [in]	basename	= ベース名
 * @param [in]	index		= インデックス
*/
::std::string MakeIndexTestName(const char* basename, int index);

/**
 * @brief	テスト名の作成
 * @param [in]	basename	= ベース名
 * @param [in]	index		= インデックス
*/
template<typename T>
::std::string MakeIndexTypedTestName(const char* basename, int index)
{
#if IUTEST_HAS_RTTI
	::std::string name = MakeIndexTestName(basename, index);
	name += "/";
	name += GetTypeName<T>();
	return name;
#else
	return MakeIndexTestName(basename, index);
#endif
}

/**
 * @brief	テスト名の作成
 * @param [in]	prefix		= prefix
 * @param [in]	basename	= ベース名
 * @param [in]	index		= インデックス
*/
::std::string MakePrefixedIndexTestName(const char* prefix, const char* basename, int index);

/**
 * @brief	テスト名の作成
 * @param [in]	prefix		= prefix
 * @param [in]	basename	= ベース名
 * @param [in]	index		= インデックス
*/
template<typename T>
::std::string MakePrefixedIndexTypedTestName(const char* prefix, const char* basename, int 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
}

}	// end of namespace detail

}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_core_impl.ipp
 * @brief		iris unit test UnitTest 実装 ファイル
 *
 * @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_CORE_IMPL_IPP_D5ABC7DE_C751_4AC0_922F_547880163891_
#define INCG_IRIS_IUTEST_CORE_IMPL_IPP_D5ABC7DE_C751_4AC0_922F_547880163891_

//======================================================================
// include

namespace iutest
{

IUTEST_IPP_INLINE TestResult* UnitTestImpl::current_test_result(void)
{
	if( Test::GetCurrentTestInfo() )
	{
		return &(Test::GetCurrentTest()->m_test_info->ptr()->m_test_result);
	}
	UnitTestImpl* p = ptr();
	if( p == NULL )
	{
		return NULL;
	}
	if( p->m_current_testcase != NULL )
	{
		return &p->m_current_testcase->m_ad_hoc_testresult;
	}
	return &p->m_ad_hoc_testresult;
}

IUTEST_IPP_INLINE void UnitTestImpl::AddTestInfo(TestCase* pCase, TestInfo* pInfo)
{
	++m_total_test_num;
	pCase->push_back(pInfo);
}

IUTEST_IPP_INLINE void UnitTestImpl::SkipTest(void)
{
	Test* test = Test::GetCurrentTest();
	if( test != NULL && test->m_test_info->ptr() != NULL )
	{
		test->m_test_info->ptr()->skip();
	}
}

IUTEST_IPP_INLINE int UnitTestImpl::Listup(void) const
{
	detail::iuConsole::output("%d tests from %d 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((it)->name());
		detail::iuConsole::output("\n");

		for( TestCase::iuTestInfos::const_iterator it2 = (it)->begin(), end2=(it)->end(); it2 != end2; ++it2 )
		{
			detail::iuConsole::output("  ");
			detail::iuConsole::output((it2)->name());
			detail::iuConsole::output("\n");
		}
	}
	return 0;
}

IUTEST_IPP_INLINE int UnitTestImpl::ListupWithWhere(void) const
{
	detail::iuConsole::output("%d tests from %d 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((it)->testcase_name_with_where().c_str());
		detail::iuConsole::output("\n");

		for( TestCase::iuTestInfos::const_iterator it2 = (it)->begin(), end2=(it)->end(); it2 != end2; ++it2 )
		{
			detail::iuConsole::output("  ");
			detail::iuConsole::output((it2)->test_name_with_where().c_str());
			detail::iuConsole::output("\n");
		}
	}
	return 0;
}

IUTEST_IPP_INLINE bool UnitTestImpl::PreRunner(void)
{
	InitializeImpl();

	if( TestFlag::IsEnableFlag(TestFlag::SHOW_HELP) )
	{
		detail::iuOptionMessage::ShowHelp();
	}
	else if( TestFlag::IsEnableFlag(TestFlag::SHOW_VERSION) )
	{
		detail::iuOptionMessage::ShowVersion();
	}
	else if( TestFlag::IsEnableFlag(TestFlag::SHOW_FEATURE) )
	{
		detail::iuOptionMessage::ShowFeature();
	}
	else if( TestFlag::IsEnableFlag(TestFlag::SHOW_SPEC) )
	{
		detail::iuOptionMessage::ShowSpec();
	}
	else if( TestFlag::IsEnableFlag(TestFlag::SHOW_TESTS_LIST_WITH_WHERE) )
	{
		ListupWithWhere();
	}
	else if( TestFlag::IsEnableFlag(TestFlag::SHOW_TESTS_LIST) )
	{
		Listup();
	}
	else
	{
		return true;
	}
	TestFlag::SetFlag(0, ~TestFlag::SHOW_MASK);
	return false;
}

IUTEST_IPP_INLINE void UnitTestImpl::ClearNonAdHocTestResult(void)
{
	for( iuTestCases::iterator it=m_testcases.begin(), end=m_testcases.end(); it != end; ++it )
	{
		(it)->clear();
	}
}

IUTEST_IPP_INLINE void UnitTestImpl::RecordProperty(const TestProperty& prop)
{
	UnitTestImpl* p = ptr();
	TestResult* tr = NULL;
	if( Test::GetCurrentTestInfo() )
	{
		tr = &(Test::GetCurrentTest()->m_test_info->ptr()->m_test_result);
		// 不正なキーのチェック
		if( !TestInfo::ValidateTestPropertyName(prop.key()) )
		{
			IIUT_ADD_FAILURE() << "Reserved key used in RecordProperty(): " << prop.key();
			return;
		}
	}
	else if( p->m_current_testcase != NULL )
	{
		tr = &p->m_current_testcase->m_ad_hoc_testresult;
		// 不正なキーのチェック
		if( !TestCase::ValidateTestPropertyName(prop.key()) )
		{
			IIUT_ADD_FAILURE() << "Reserved key used in RecordProperty(): " << prop.key();
			return;
		}
	}
	else
	{
		tr =&p->m_ad_hoc_testresult;
		// 不正なキーのチェック
		if( !ValidateTestPropertyName(prop.key()) )
		{
			IIUT_ADD_FAILURE() << "Reserved key used in RecordProperty(): " << prop.key();
			return;
		}
	}
	tr->RecordProperty(prop);
	TestEnv::event_listeners().OnTestRecordProperty(prop);
}

IUTEST_IPP_INLINE TestCase* UnitTestImpl::FindTestCase(const char* testcase_name, TestTypeId id)
{
	TestCase::FindOp func ={ id, testcase_name };
	return detail::FindList(m_testcases, func);
}

IUTEST_IPP_INLINE void UnitTestImpl::InitializeImpl(void)
{
#if IUTEST_HAS_SEH

#if !defined(IUTEST_OS_WINDOWS_MOBILE) && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
	SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
#endif

#if (defined(_MSC_VER) || IUTEST_OS_WINDOWS_MINGW) && !defined(IUTEST_OS_WINDOWS_MOBILE)
	_set_error_mode(_OUT_TO_STDERR);
#endif

#endif

#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(IUTEST_OS_WINDOWS_MOBILE)
	if( !TestFlag::IsEnableFlag(TestFlag::BREAK_ON_FAILURE) )
	{
		_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
	}
#endif

#if IUTEST_HAS_EXCEPTIONS && (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(IUTEST_OS_WINDOWS_MOBILE)
	_set_invalid_parameter_handler(OnInvalidParameter);
#endif
}

IUTEST_IPP_INLINE void UnitTestImpl::TerminateImpl(void)
{
	for( iuTestCases::iterator it = m_testcases.begin(); it != m_testcases.end(); it = m_testcases.begin())
	{
		TestCase* p = (it);
		m_testcases.erase(it);
		delete p;
	}
}

#if IUTEST_HAS_EXCEPTIONS && (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(IUTEST_OS_WINDOWS_MOBILE)

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

	// _invalid_parameter_handler
IUTEST_IPP_INLINE void UnitTestImpl::OnInvalidParameter(const wchar_t * expression, const wchar_t * function
	, const wchar_t * file, unsigned int line, uintptr_t pReserved)
{
	IUTEST_UNUSED_VAR(file);
	IUTEST_UNUSED_VAR(line);
	IUTEST_UNUSED_VAR(pReserved);
	char func[260];
	wcstombs(func, function, 260);
	char expr[260];
	wcstombs(expr, expression, 260);
	::std::string msg = func;
	msg += expr;
	throw ::std::invalid_argument(msg);
}

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

#endif

namespace detail
{

IUTEST_IPP_INLINE ::std::string MakeIndexTestName(const char* basename, int index)
{
	::std::string name = basename;
	iu_stringstream strm;
	strm << index;
	name += "/";
	name += strm.str();
	return name;
}

IUTEST_IPP_INLINE ::std::string MakePrefixedIndexTestName(const char* prefix, const char* basename, int index)
{
	::std::string name = prefix;
	if( !name.empty() )
	{
		name += "/";
	}
	name += MakeIndexTestName(basename, index);
	return name;
}

}	// end of namespace detail

IUTEST_IPP_INLINE void Test::TestRecordPropertyHelper::RecordProperty(const TestProperty& prop)
{
	iutest::UnitTestImpl::RecordProperty(prop);
}

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_CORE_IMPL_IPP_D5ABC7DE_C751_4AC0_922F_547880163891_
#endif

#endif // INCG_IRIS_IUTEST_CORE_IMPL_HPP_D5ABC7DE_C751_4AC0_922F_547880163891_

namespace iutest {
namespace detail
{

//======================================================================
// class
/**
 * @brief	デフォルト TestPartResult リポーター
*/
class DefaultGlobalTestPartResultReporter : public TestPartResultReporterInterface
{
public:
	virtual ~DefaultGlobalTestPartResultReporter(void) IUTEST_CXX_OVERRIDE {}
	virtual void ReportTestPartResult(const TestPartResult& test_part_result) IUTEST_CXX_OVERRIDE
	{
		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(test_part_result.make_newline_message().c_str());
		}
		TestEnv::event_listeners().OnTestPartResult(test_part_result);
	}
};

/**
 * @brief	Not report
*/
class NoTestPartResultReporter : public TestPartResultReporterInterface
{
public:
	virtual ~NoTestPartResultReporter(void) IUTEST_CXX_OVERRIDE {}
	virtual void ReportTestPartResult(const TestPartResult& result) IUTEST_CXX_OVERRIDE
	{
		IUTEST_UNUSED_VAR(result);
	}
};

/**
 * @brief	TestPartResult の情報収集ヘルパー
*/
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(NULL) {}
		virtual ~ReporterHolder(void)
		{
			Detach();
		}
		void Attach(TestPartResultReporterInterface* p)
		{
			m_origin = TestEnv::GetGlobalTestPartResultReporter();
			TestEnv::SetGlobalTestPartResultReporter(p);
		}
		void Detach(void)
		{
			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(void) : m_count(0)
		{
			m_holder.Attach(this);
		}
		virtual void ReportTestPartResult(const TestPartResult& result) IUTEST_CXX_OVERRIDE
		{
			if( m_cond(result) )
			{
				++m_count;
			}
			_Mybase::ReportTestPartResult(result);
		}
	public:
		int count(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_count; }
	private:
		ReporterHolder m_holder;
		COND m_cond;
		int m_count;

		IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(Counter);
	};
	template<typename REPORTER=DefaultGlobalTestPartResultReporter>
	class Collector : public REPORTER
	{
		typedef REPORTER _Mybase;
		typedef ::std::vector<TestPartResult> TestPartResults;
	public:
		Collector(void)
		{
			m_holder.Attach(this);
		}
	public:
		virtual void ReportTestPartResult(const TestPartResult& result) IUTEST_CXX_OVERRIDE
		{
			m_results.push_back(result);
			_Mybase::ReportTestPartResult(result);
		}
	public:
		size_t count(void) const IUTEST_CXX_NOEXCEPT_SPEC { return m_results.size(); }
		const TestPartResult& GetTestPartResult(int index) const { return m_results[index]; }

		void ReportTestPartResult(void)
		{
			for( TestPartResults::iterator it=m_results.begin(); it != m_results.end(); ++it )
			{
				m_holder.ReportTestPartResultOrigin(*it);
			}
		}
	private:
		ReporterHolder m_holder;
		TestPartResults m_results;
	};
};

//======================================================================
// function
/**
 * @brief	TestPartResult リポーター
*/
inline void DefaultReportTestPartResult(const TestPartResult& test_part_result)
{
	DefaultGlobalTestPartResultReporter::DefaultReportTestPartResult(test_part_result);
}

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_RESULT_REPORTER_HPP_803FD1F7_1FD2_4D1E_9AFC_A5851284316F_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_params_util.hpp
 * @brief		iris unit test parameter 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PARAMS_UTIL_HPP_19F0C0BB_EEAE_4E8B_B269_A09A4A45E890_
#define INCG_IRIS_IUTEST_PARAMS_UTIL_HPP_19F0C0BB_EEAE_4E8B_B269_A09A4A45E890_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_genparams.hpp
 * @brief		iris unit test parameter generator
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_GENPARAMS_HPP_7845F59A_825C_426A_B451_573245408998_
#define INCG_IRIS_IUTEST_GENPARAMS_HPP_7845F59A_825C_426A_B451_573245408998_

//======================================================================
// include

#if IUTEST_HAS_PARAM_TEST

namespace iutest {
namespace detail
{

//======================================================================
// declare
#if IUTEST_HAS_CONCAT
template<typename G1, typename G2>class iuConcatParamHolder;
#endif

//======================================================================
// class
/**
 * @brief	パラメータ生成器インターフェイス
*/
template<typename T>
class iuIParamGenerator
{
	typedef iuIParamGenerator<T> _Myt;
public:
	typedef T type;
public:
	typedef _Myt* (*Generator)(void);
public:
	virtual ~iuIParamGenerator(void) {}
public:
	virtual void	Begin(void) = 0;			//!< パラメータリストの先頭に移動
	virtual T		GetCurrent(void) const = 0;	//!< 現在のパラメータを取得
	virtual void	Next(void)	= 0;			//!< パラメータを取得して次に移動
	virtual bool	IsEnd(void) const = 0;		//!< パラメータリストの終端にいるかどうか
};

/**
 * @brief	パラメータ生成器保持クラス
*/
template<typename T>
class iuParamGenerator : public iuIParamGenerator<T>
{
	typedef iuIParamGenerator<T> _Interface;
	typedef iuParamGenerator<T>  _Myt;
public:
	typedef T type;
public:
	iuParamGenerator(_Interface* pInterface=NULL) : m_pInterface(pInterface) {}

public:
	operator iuIParamGenerator<T>* (void) const { return m_pInterface; }

public:

#if IUTEST_HAS_CONCAT
	template<typename Other>
	iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
	{
		return iuConcatParamHolder<_Myt, Other>(*this, g);
	}
#endif

public:
	virtual void	Begin(void) IUTEST_CXX_OVERRIDE { m_pInterface->Begin(); }
	virtual T		GetCurrent(void) const IUTEST_CXX_OVERRIDE { return m_pInterface->GetCurrent(); }
	virtual void	Next(void) IUTEST_CXX_OVERRIDE { m_pInterface->Next(); }
	virtual bool	IsEnd(void) const IUTEST_CXX_OVERRIDE { return m_pInterface->IsEnd(); }
private:
	_Interface* m_pInterface;
};

/**
 * @brief	範囲パラメータ生成器
 * @tparam T	= パラメータ型
*/
template<typename T>
class iuRangeParamsGenerator : public iuIParamGenerator<T>
{
	T m_begin;
	T m_end;
	T m_step;
	T m_cur;
public:
	/**
	 * @brief	コンストラクタ
	 * @param [in]	begin	= 開始値
	 * @param [in]	end		= 終了値
	 * @param [in]	step	= 増値
	*/
	iuRangeParamsGenerator(T begin, T end, T step=1)
		: m_begin(begin)
		, m_end(end)
		, m_step(step)
		, m_cur(begin)
	{
	}

public:
	virtual void	Begin(void) IUTEST_CXX_OVERRIDE { m_cur = m_begin; }
	virtual T		GetCurrent(void) const IUTEST_CXX_OVERRIDE { return m_cur; }
	virtual void	Next(void) IUTEST_CXX_OVERRIDE { m_cur += m_step; }
	virtual bool	IsEnd(void) const IUTEST_CXX_OVERRIDE { return !(m_cur < m_end); }
};

/**
 * @brief	真偽値パラメータ生成器
 * @tparam T	= パラメータ型
*/
template<typename T>
class iuBoolParamsGenerator : public iuIParamGenerator<T>
{
	T m_cur;
	int m_n;
public:
	iuBoolParamsGenerator(void)
		: m_n(0)
	{}

public:
	virtual void	Begin(void) IUTEST_CXX_OVERRIDE { m_cur = 0; m_n = 0; }
	virtual T		GetCurrent(void) const IUTEST_CXX_OVERRIDE { return m_cur; }
	virtual void	Next(void) IUTEST_CXX_OVERRIDE { ++m_n; m_cur = !m_cur; }
	virtual bool	IsEnd(void) const IUTEST_CXX_OVERRIDE { return (m_n >= 2); }
};

/**
 * @brief	値配列パラメータ生成器
 * @tparam T = パラメータ型
*/
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:
	iuValuesInParamsGenerator(const params_t& values)
		: m_values(values) {}
	template<typename Container>
	iuValuesInParamsGenerator(const Container& values)
	{
		m_values.insert(m_values.end(), values.begin(), values.end());
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename TT, size_t SIZE>
	iuValuesInParamsGenerator(const TT (&values)[SIZE])
	{
		m_values.insert(m_values.end(), values, values + SIZE);
	}
#endif

	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(void) IUTEST_CXX_OVERRIDE{ m_it = m_values.begin(); }
	virtual T		GetCurrent(void) const IUTEST_CXX_OVERRIDE { return *m_it; }
	virtual void	Next(void) IUTEST_CXX_OVERRIDE { ++m_it; }
	virtual bool	IsEnd(void) const IUTEST_CXX_OVERRIDE { return (m_it == m_values.end()); }
};


#if IUTEST_HAS_CONCAT
/**
 * @brief	パラメータ生成器加算保持クラス
*/
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) {}

public:
	template<typename T>
	operator iuIParamGenerator<T>* (void)
	{
		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
	{
		::std::vector<T> val;

		void append(iuIParamGenerator<T>* gen)
		{
			for( gen->Begin(); !gen->IsEnd(); gen->Next() )
			{
				val.push_back(gen->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;
};
#endif


#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[tuples::tuple_size<_MyTuple>::value];

		template<typename U>
		void operator ()(int index, const U& value) { val[index] = value; }

		make_array(const _MyTuple& t)
		{
			tuples::tuple_foreach(t, *this);
		};
	};
public:
	iuValueArray(const Args&... args)
		: v(args...)
	{}
public:
	template<typename T>
	operator iuIParamGenerator<T>* (void) const
	{
		make_array<T> ar(v);
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
		return new iuValuesInParamsGenerator<T>(ar.val);
#else
		return new iuValuesInParamsGenerator<T>(ar.val, ar.val + IUTEST_PP_COUNTOF(ar.val));
#endif
	}

public:

#if IUTEST_HAS_CONCAT
	template<typename Other>
	iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
	{
		return iuConcatParamHolder<_Myt, Other>(*this, g);
	}
#endif

private:
	_MyTuple v;
};

#else

/*
template<typename A1, typename A2>
class iuValueArray2
{
typedef iuValueArray2<A1, A2> _Myt;
public:
iuValueArray2(A1 a1, A2 a2) : v1(a1), v2(a2)
{}
public:
template<typename T>
operator iuIParamGenerator<T>* (void) const
{
const T val[] = { static_cast<T>(v1), static_cast<T>(v2) };
return new iuValuesInParamsGenerator<T>(val);
}
public:
template<typename Other>
iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
{
return iuConcatParamHolder<_Myt, Other>(*this, g);
}
private:
A1 v1;	A2 v2;
};
*/

/**
 * @private
 * @{
 */
#define IIUT_DECL_VALUEARRAY_CONSTRUCT_(i, p1, p2)		IUTEST_PP_CAT(p1, i)(IUTEST_PP_CAT(p2, i))
#define IIUT_DECL_VALUEARRAY_STATICCAST_(i, p1, p2)		static_cast<p1>(IUTEST_PP_CAT(p2, i))
#define IIUT_DECL_VALUEARRAY_VARIABLE_(i, p1, p2)		IUTEST_PP_CAT(p1, i) IUTEST_PP_CAT(p2, i);
#if IUTEST_HAS_CONCAT
#  define IIUT_DECL_VALUEARRAY_CONCAT_()				\
	template<typename Other> iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const {	\
		return iuConcatParamHolder<_Myt, Other>(*this, g);
#else
#  define IIUT_DECL_VALUEARRAY_CONCAT_()
#endif


#define IIUT_DECL_VALUEARRAY_(n)						\
	template< IUTEST_PP_ENUM_PARAMS(n, typename A) >	\
	class IUTEST_PP_CAT(iuValueArray, n) {				\
		typedef IUTEST_PP_CAT(iuValueArray, n)< IUTEST_PP_ENUM_PARAMS(n, A) > _Myt;	\
	public:																			\
		IUTEST_PP_CAT(iuValueArray, n)( IUTEST_PP_ENUM_BINARY_PARAMS(n, A, a) )		\
		: IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_VALUEARRAY_CONSTRUCT_, v, a) {}		\
		template<typename T>operator iuIParamGenerator<T>* (void) const {			\
			const T val[] = { IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_VALUEARRAY_STATICCAST_, T, v) };		\
			return new iuValuesInParamsGenerator<T>(val);							\
		}																			\
		IIUT_DECL_VALUEARRAY_CONCAT_()												\
		}																			\
	private: IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_VALUEARRAY_VARIABLE_, A, v)		\
	}
/**
 * @}
*/

IIUT_DECL_VALUEARRAY_(1);
IIUT_DECL_VALUEARRAY_(2);
IIUT_DECL_VALUEARRAY_(3);
IIUT_DECL_VALUEARRAY_(4);
IIUT_DECL_VALUEARRAY_(5);
IIUT_DECL_VALUEARRAY_(6);
IIUT_DECL_VALUEARRAY_(7);
IIUT_DECL_VALUEARRAY_(8);
IIUT_DECL_VALUEARRAY_(9);
IIUT_DECL_VALUEARRAY_(10);
IIUT_DECL_VALUEARRAY_(11);
IIUT_DECL_VALUEARRAY_(12);
IIUT_DECL_VALUEARRAY_(13);
IIUT_DECL_VALUEARRAY_(14);
IIUT_DECL_VALUEARRAY_(15);
IIUT_DECL_VALUEARRAY_(16);
IIUT_DECL_VALUEARRAY_(17);
IIUT_DECL_VALUEARRAY_(18);
IIUT_DECL_VALUEARRAY_(19);
IIUT_DECL_VALUEARRAY_(20);
IIUT_DECL_VALUEARRAY_(21);
IIUT_DECL_VALUEARRAY_(22);
IIUT_DECL_VALUEARRAY_(23);
IIUT_DECL_VALUEARRAY_(24);
IIUT_DECL_VALUEARRAY_(25);
IIUT_DECL_VALUEARRAY_(26);
IIUT_DECL_VALUEARRAY_(27);
IIUT_DECL_VALUEARRAY_(28);
IIUT_DECL_VALUEARRAY_(29);
IIUT_DECL_VALUEARRAY_(30);
IIUT_DECL_VALUEARRAY_(31);
IIUT_DECL_VALUEARRAY_(32);
IIUT_DECL_VALUEARRAY_(33);
IIUT_DECL_VALUEARRAY_(34);
IIUT_DECL_VALUEARRAY_(35);
IIUT_DECL_VALUEARRAY_(36);
IIUT_DECL_VALUEARRAY_(37);
IIUT_DECL_VALUEARRAY_(38);
IIUT_DECL_VALUEARRAY_(39);
IIUT_DECL_VALUEARRAY_(40);
IIUT_DECL_VALUEARRAY_(41);
IIUT_DECL_VALUEARRAY_(42);
IIUT_DECL_VALUEARRAY_(43);
IIUT_DECL_VALUEARRAY_(44);
IIUT_DECL_VALUEARRAY_(45);
IIUT_DECL_VALUEARRAY_(46);
IIUT_DECL_VALUEARRAY_(47);
IIUT_DECL_VALUEARRAY_(48);
IIUT_DECL_VALUEARRAY_(49);
IIUT_DECL_VALUEARRAY_(50);

#undef IIUT_DECL_VALUEARRAY_CONSTRUCT_
#undef IIUT_DECL_VALUEARRAY_STATICCAST_
#undef IIUT_DECL_VALUEARRAY_VARIABLE_
#undef IIUT_DECL_VALUEARRAY_CONCAT_
#undef IIUT_DECL_VALUEARRAY_

#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 count = tuples::tuple_size<_MyTuple>::value;

	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
	{
		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(void)
	{}

public:
	virtual void Begin(void) IUTEST_CXX_OVERRIDE
	{
		tuples::tuple_foreach(v, begin_func());
	}
	virtual void Next(void) IUTEST_CXX_OVERRIDE
	{
		if( IsEnd() ) return;
		next_foreach<0, count>(v);
	}
	virtual bool IsEnd(void) const IUTEST_CXX_OVERRIDE
	{
		return is_end_foreach<0, count>(v);
	}
	virtual ParamType GetCurrent(void) const IUTEST_CXX_OVERRIDE
	{
		return current_foreach<0, count, Args...>();
	}

	_MyTuple& generators(void) { return v; }
private:
	_MyTuple v;
};

template<typename... Generator>
class iuCartesianProductHolder
{
	typedef iuCartesianProductHolder<Generator...> _Myt;
	typedef tuples::tuple<const Generator...> _MyTuple;

public:
	iuCartesianProductHolder(const Generator&... generators)
		: v(generators...) {}

public:
	template<typename... Args>
	operator iuIParamGenerator< tuples::tuple<Args...> >* (void) const
	{
		iuCartesianProductGenerator<Args...>* p = new iuCartesianProductGenerator<Args...>();
		tuples::tuple_cast_copy(p->generators(), v);
		return p;
	}

public:

#if IUTEST_HAS_CONCAT
	template<typename Other>
	iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
	{
		return iuConcatParamHolder<_Myt, Other>(*this, g);
	}
#endif

private:
	void operator = (const _Myt&);
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(void) IUTEST_CXX_OVERRIDE
	{
		m_g1.Begin();
		m_g2.Begin();
	}
	virtual void Next(void) IUTEST_CXX_OVERRIDE
	{
		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(void) const IUTEST_CXX_OVERRIDE
	{
		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(void) const IUTEST_CXX_OVERRIDE
	{
		return ParamType(this->m_g1.GetCurrent(), this->m_g2.GetCurrent());
	}
};

/*
template<typename T1, typename T2, typename T3>
class iuCartesianProductGenerator3 : public iuICartesianProductGeneratorBase<iuParamGenerator<T1>
																			, iuCartesianProductGenerator2<T2, T3>
																			, tuples::tuple<T1, T2, T3> >
{
	typedef iuICartesianProductGeneratorBase<iuParamGenerator<T1>, iuCartesianProductGenerator2<T2, T3>, tuples::tuple<T1, T2, T3> >	_Mybase;
	typedef iuParamGenerator<T1> Generator1;
	typedef iuParamGenerator<T2> Generator2;
	typedef iuParamGenerator<T3> Generator3;
public:
	typedef tuples::tuple<T1, T2, T3> ParamType;
public:
	iuCartesianProductGenerator3(const Generator1& g1, const Generator2& g2, const Generator3& g3)
		: _Mybase(g1, iuCartesianProductGenerator2<T2, T3>(g2, g3))
	{}

public:
	virtual ParamType GetCurrent(void) const IUTEST_CXX_OVERRIDE
	{
		tuples::tuple<T2, T3> param(this->m_g2.GetCurrent());
		return ParamType(this->m_g1.GetCurrent(), tuples::get<0>(param), tuples::get<1>(param) );
	}
};
*/

/**
 * @private
 * @{
*/
#define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TYPEDEF_(i, p1, p2)		\
	typedef iuParamGenerator<IUTEST_PP_CAT(p1, i)> IUTEST_PP_CAT(p2, i);

#define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TUPLEGET_(i, param)		\
	tuples::get<i>(param)

#define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_(n)					\
	iuICartesianProductGeneratorBase< iuParamGenerator<T0>				\
		, IUTEST_PP_CAT(iuCartesianProductGenerator, IUTEST_PP_DEC(n))< \
			IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), T) >		\
		, tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > >

#define IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(n)							\
	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >						\
	class IUTEST_PP_CAT(iuCartesianProductGenerator, n)						\
	: public IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_(n) {				\
		typedef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_(n) _Mybase;		\
		IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TYPEDEF_, T, Generator)			\
	public:																	\
		typedef tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > ParamType;		\
		IUTEST_PP_CAT(iuCartesianProductGenerator, n)( IUTEST_PP_ENUM_BINARY_PARAMS(n, const Generator, &g) ) \
		: _Mybase(g0, IUTEST_PP_CAT(iuCartesianProductGenerator, IUTEST_PP_DEC(n))<							\
		IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), T)>					\
		( IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), g) ) ) {}			\
		virtual ParamType GetCurrent(void) const IUTEST_CXX_OVERRIDE {		\
			tuples::tuple< IUTEST_PP_ENUM_SHIFTED_PARAMS(IUTEST_PP_DEC(n), T) >	\
			params(this->m_g2.GetCurrent());								\
			return ParamType(this->m_g1.GetCurrent(), IUTEST_PP_ENUM(IUTEST_PP_DEC(n)	\
				, IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TUPLEGET_, params) );			\
		}																	\
	}
/**
 * @}
*/


IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(3);
IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(4);
IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(5);
IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(6);
IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(7);
IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(8);
IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_(9);

#undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TYPEDEF_
#undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_TUPLEGET_
#undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_BASE_
#undef IIUT_DECL_CARTESIAN_PRODUCT_GENERATOR_

// iuCartesianProductHolder

/*
template<typename Generator1, typename Generator2>
class iuCartesianProductHolder2
{
	typedef iuCartesianProductHolder2<Generator1, Generator2> _Myt;
public:
	iuCartesianProductHolder2(const Generator1& g1, const Generator2& g2)
		: m_g1(g1), m_g2(g2) {}

public:
	template<typename T1, typename T2>
	operator iuIParamGenerator< tuples::tuple<T1, T2> >* () const
	{
		return new iuCartesianProductGenerator2<T1, T2>(
			static_cast< iuIParamGenerator<T1>* >(m_g1)
			, static_cast< iuIParamGenerator<T2>* >(m_g2)
		);
	}

public:
	template<typename Other>
	iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
	{
		return iuConcatParamHolder<_Myt, Other>(*this, g);
	}

private:
	void operator = (const _Myt&) {}
private:
	const Generator1 m_g1;
	const Generator2 m_g2;
};
*/

/**
 * @private
 * @{
*/
#define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONSTRUCT_(i, p1, p2)	IUTEST_PP_CAT(p1, i)(IUTEST_PP_CAT(p2, i))
#define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_STATICCAST_(i, p1, p2)	\
	static_cast< iuIParamGenerator< IUTEST_PP_CAT(p1, i) >* >(IUTEST_PP_CAT(p2, i))
#define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_VARIABLE_(i, p1, p2)	IUTEST_PP_CAT(p1, i) IUTEST_PP_CAT(p2, i);
#if IUTEST_HAS_CONCAT
#define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_()	\
		template<typename Other> iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const {		\
			return iuConcatParamHolder<_Myt, Other>(*this, g);
#else
#define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_()
#endif

#define IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(n)					\
	template< IUTEST_PP_ENUM_PARAMS(n, typename Generator) >	\
	class IUTEST_PP_CAT(iuCartesianProductHolder, n) {			\
		typedef IUTEST_PP_CAT(iuCartesianProductHolder, n)< IUTEST_PP_ENUM_PARAMS(n, Generator) > _Myt;		\
	public:														\
		IUTEST_PP_CAT(iuCartesianProductHolder, n)( IUTEST_PP_ENUM_BINARY_PARAMS(n, const Generator, &g) )	\
		: IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONSTRUCT_, m_g, g) {}				\
		template< IUTEST_PP_ENUM_PARAMS(n, typename T) >		\
		operator iuIParamGenerator< tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > >* (void) const {			\
			return new IUTEST_PP_CAT(iuCartesianProductGenerator, n)< IUTEST_PP_ENUM_PARAMS(n, T) >(		\
				IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_STATICCAST_, T, m_g) );			\
		}														\
		IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_()			\
		}														\
	private: void operator = (const _Myt&) {}					\
		IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_VARIABLE_, const Generator, m_g)		\
	}

/**
 * @}
*/

IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(2);
IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(3);
IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(4);
IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(5);
IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(6);
IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(7);
IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(8);
IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_(9);

#undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONSTRUCT_
#undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_STATICCAST_
#undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_VARIABLE_
#undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_CONCAT_
#undef IIUT_DECL_CARTESIAN_PRODUCT_HOLDER_

#endif

#endif

#if IUTEST_HAS_PAIRWISE

class iuPairwiseGeneratorBase
{
protected:
	template<int N>
	struct ParamIndexes
	{
		int index[N];
		ParamIndexes(void) { 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;
				}
			}
		}

		//for( list_iterator it=list.begin(), end=list.end(); it != end; ++it )
		//{
		//	for( int i=0; i < N; ++i ) printf("%2d ", it->index[i]);
		//	printf("\n");
		//}
	}

	template<int N, typename Fn>
	static int GetParamIndex(const ParamIndexes<N>& indexes, int raw, size_t 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)
	{
		const int index = GetParamIndex(indexes, raw, params.size(), TestEnv::genrand());
		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 )
			{
#if 0
				IUTEST_UNUSED_VAR(free_idx);
				IUTEST_UNUSED_VAR(max_overlap);
				return it;
#else
				// 仮に入ったとして重複がないか調べる
				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;
				}
#endif
			}
		}
		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 RAW_COUNT = tuples::tuple_size<ParamType>::value;

	typedef ParamIndexes<RAW_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 == RAW_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 == RAW_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[RAW_COUNT];

		template<int N>
		void MakeParamVecotrs(GeneratorTuple& generators, typename detail::disable_if<N == RAW_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 == RAW_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());
		}

		ParamVecotrs(GeneratorTuple& generators)
		{
			MakeParamVecotrs<0>(generators);
		}
	};
};

template<typename... Generator>
class iuPairwiseHolder
{
	typedef iuPairwiseHolder<Generator...> _Myt;
	typedef tuples::tuple<const Generator...> _MyTuple;

public:
	iuPairwiseHolder(const Generator&... generators)
		: v(generators...) {}

public:
	template<typename... Args>
	operator iuIParamGenerator< tuples::tuple<Args...> >* (void) const
	{
		tuples::tuple< iuParamGenerator<Args>... > generators;
		tuples::tuple_cast_copy(generators, v);
		return iuPairwiseGenerator<Args...>::Create(generators);
	}

public:

#if IUTEST_HAS_CONCAT
	template<typename Other>
	iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
	{
		return iuConcatParamHolder<_Myt, Other>(*this, g);
	}
#endif

private:
	void operator = (const _Myt&);
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(void) IUTEST_CXX_OVERRIDE
	{
		m_g1.Begin();
		m_g2.Begin();
	}
	virtual void Next(void) IUTEST_CXX_OVERRIDE
	{
		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(void) const IUTEST_CXX_OVERRIDE
	{
		return m_g1.IsEnd() && m_g2.IsEnd();
	}
	virtual ParamType GetCurrent(void) const IUTEST_CXX_OVERRIDE
	{
		return ParamType(this->m_g1.GetCurrent(), this->m_g2.GetCurrent());
	}
private:
	Generator1 m_g1;
	Generator2 m_g2;
};

/*
template<typename T1, typename T2, typename T3>
class iuPairwiseGenerator3 : public iuPairwiseGeneratorBase
{
	typedef iuParamGenerator<T1> Generator1;
	typedef iuParamGenerator<T2> Generator2;
	typedef iuParamGenerator<T3> Generator3;

	static const int RAW_COUNT = 3;
	typedef ParamIndexes<RAW_COUNT> _MyParamIndexes;
	typedef ::std::vector< _MyParamIndexes > ParamIndexesList;

public:
	typedef tuples::tuple<T1, T2, T3> ParamType;
public:
	static iuIParamGenerator< ParamType >* Create(Generator1 g1, Generator2 g2, Generator3 g3)
	{
		ParamIndexesList list;
		::std::vector<T1> params1;
		::std::vector<T2> params2;
		::std::vector<T3> params3;

		MakeParamVector(params1, g1);
		MakeParamVector(params2, g2);
		MakeParamVector(params3, g3);

		int count_list[] = {
			static_cast<int>(params1.size())
			, static_cast<int>(params2.size())
			, static_cast<int>(params3.size())
		};
		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(
				GetParam(params1, indexes, 0)
				, GetParam(params2, indexes, 1)
				, GetParam(params3, indexes, 2)
				) );
		}

		return new iuValuesInParamsGenerator< ParamType >(params);
	}
};
*/

/**
 * @private
 * @{
*/
#define IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_(i, p1, p2)			\
	p1<IUTEST_PP_CAT(T, i)> IUTEST_PP_CAT(p2, i);
#define IIUT_DECL_PAIRWISE_GENERATOR_MAKEPARAM_VECTOR_(i, p1, p2)	\
	MakeParamVector( IUTEST_PP_CAT(p1, i), IUTEST_PP_CAT(p2, i) );
#define IIUT_DECL_PAIRWISE_GENERATOR_PARAM_SIZE_(i, param)			\
	static_cast<int>( IUTEST_PP_CAT(param, i).size() )
#define IIUT_DECL_PAIRWISE_GENERATOR_GETPARAM_(i, param)			\
	GetParam( IUTEST_PP_CAT(param, i), indexes, i)

#define IIUT_DECL_PAIRWISE_GENERATOR_(n)				\
	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >	\
	class IUTEST_PP_CAT(iuPairwiseGenerator, n) : public iuPairwiseGeneratorBase {	\
		IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_, typedef iuParamGenerator, Generator)	\
		typedef ParamIndexes<n> _MyParamIndexes;							\
		typedef ::std::vector< _MyParamIndexes > ParamIndexesList;			\
	public: typedef tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > ParamType;	\
		static iuIParamGenerator< ParamType >* Create(						\
			IUTEST_PP_ENUM_BINARY_PARAMS(n, Generator, g) ) {				\
			ParamIndexesList list;											\
			IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_, ::std::vector, params)	\
			IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_GENERATOR_MAKEPARAM_VECTOR_, params, g)		\
			int count_list[] = { IUTEST_PP_ENUM(n, IIUT_DECL_PAIRWISE_GENERATOR_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( IUTEST_PP_ENUM(n, IIUT_DECL_PAIRWISE_GENERATOR_GETPARAM_, params) ) );	\
			}																\
			return new iuValuesInParamsGenerator< ParamType >(params);		\
		}																	\
	}

/**
 * @}
*/

IIUT_DECL_PAIRWISE_GENERATOR_(3);
IIUT_DECL_PAIRWISE_GENERATOR_(4);
IIUT_DECL_PAIRWISE_GENERATOR_(5);
IIUT_DECL_PAIRWISE_GENERATOR_(6);
IIUT_DECL_PAIRWISE_GENERATOR_(7);
IIUT_DECL_PAIRWISE_GENERATOR_(8);
IIUT_DECL_PAIRWISE_GENERATOR_(9);

#undef IIUT_DECL_PAIRWISE_GENERATOR_TEMPLATE_T_
#undef IIUT_DECL_PAIRWISE_GENERATOR_MAKEPARAM_VECTOR_
#undef IIUT_DECL_PAIRWISE_GENERATOR_PARAM_SIZE_
#undef IIUT_DECL_PAIRWISE_GENERATOR_GETPARAM_
#undef IIUT_DECL_PAIRWISE_GENERATOR_

/*
template<typename Generator1, typename Generator2>
class iuPairwiseHolder2
{
	typedef iuPairwiseHolder2<Generator1, Generator2> _Myt;
public:
	iuPairwiseHolder2(const Generator1& g1, const Generator2& g2)
		: m_g1(g1), m_g2(g2) {}

public:
	template<typename T1, typename T2>
	operator iuIParamGenerator< tuples::tuple<T1, T2> >* () const
	{
		return iuPairwiseGenerator2<T1, T2>::Create(
			static_cast< iuIParamGenerator<T1>* >(m_g1)
			, static_cast< iuIParamGenerator<T2>* >(m_g2)
			);
	}

public:
	template<typename Other>
	iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
	{
		return iuConcatParamHolder<_Myt, Other>(*this, g);
	}

private:
	void operator = (const _Myt&) {}
private:
	const Generator1 m_g1;
	const Generator2 m_g2;
};
*/

#define IIUT_DECL_PAIRWISE_HOLDER_CONSTRUCT_(i, p1, p2)	IUTEST_PP_CAT(p1, i)(IUTEST_PP_CAT(p2, i))
#define IIUT_DECL_PAIRWISE_HOLDER_STATICCAST_(i, p1, p2)	\
	static_cast< iuIParamGenerator< IUTEST_PP_CAT(p1, i) >* >(IUTEST_PP_CAT(p2, i))
#define IIUT_DECL_PAIRWISE_HOLDER_VARIABLE_(i, p1, p2)	IUTEST_PP_CAT(p1, i) IUTEST_PP_CAT(p2, i);
#if IUTEST_HAS_CONCAT
#  define IIUT_DECL_PAIRWISE_HOLDER_CONCAT_()	\
		template<typename Other> iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const { \
			return iuConcatParamHolder<_Myt, Other>(*this, g);
#else
#  define IIUT_DECL_PAIRWISE_HOLDER_CONCAT_()
#endif

#define IIUT_DECL_PAIRWISE_HOLDER_(n)	\
	template< IUTEST_PP_ENUM_PARAMS(n, typename Generator) >	\
	class IUTEST_PP_CAT(iuPairwiseHolder, n) {					\
		typedef IUTEST_PP_CAT(iuPairwiseHolder, n)< IUTEST_PP_ENUM_PARAMS(n, Generator) > _Myt;		\
	public: IUTEST_PP_CAT(iuPairwiseHolder, n)(					\
		IUTEST_PP_ENUM_BINARY_PARAMS(n, const Generator, &g) )	\
		: IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_PAIRWISE_HOLDER_CONSTRUCT_, m_g, g) {}					\
		template< IUTEST_PP_ENUM_PARAMS(n, typename T) >		\
		operator iuIParamGenerator< tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > >* (void) const {	\
			return IUTEST_PP_CAT(iuPairwiseGenerator, n)< IUTEST_PP_ENUM_PARAMS(n, T) >::Create(	\
				IUTEST_PP_ENUM_BINARY(n, IIUT_DECL_PAIRWISE_HOLDER_STATICCAST_, T, m_g) );			\
		}														\
		IIUT_DECL_PAIRWISE_HOLDER_CONCAT_()						\
		}														\
	private: void operator = (const _Myt&) {}					\
		IUTEST_PP_REPEAT_BINARY(n, IIUT_DECL_PAIRWISE_HOLDER_VARIABLE_, const Generator, m_g)		\
	}

IIUT_DECL_PAIRWISE_HOLDER_(2);
IIUT_DECL_PAIRWISE_HOLDER_(3);
IIUT_DECL_PAIRWISE_HOLDER_(4);
IIUT_DECL_PAIRWISE_HOLDER_(5);
IIUT_DECL_PAIRWISE_HOLDER_(6);
IIUT_DECL_PAIRWISE_HOLDER_(7);
IIUT_DECL_PAIRWISE_HOLDER_(8);
IIUT_DECL_PAIRWISE_HOLDER_(9);

#undef IIUT_DECL_PAIRWISE_HOLDER_CONSTRUCT_
#undef IIUT_DECL_PAIRWISE_HOLDER_STATICCAST_
#undef IIUT_DECL_PAIRWISE_HOLDER_VARIABLE_
#undef IIUT_DECL_PAIRWISE_HOLDER_CONCAT_
#undef IIUT_DECL_PAIRWISE_HOLDER_

#endif

#endif

#if IUTEST_HAS_VALUESGEN

/**
 * @brief	パラメータ生成器
 * @tparam G	= パラメータ生成器
*/
template<typename G>
class iuValuesParamsGeneratorHolder
{
	typedef iuValuesParamsGeneratorHolder<G> _Myt;
public:
	iuValuesParamsGeneratorHolder(size_t num, const G& g)
		: m_num(num), m_g(g)
	{}
public:
	template<typename T>
	operator iuIParamGenerator<T>* (void) const
	{
		::std::vector<T> params(m_num);
		::std::generate(params.begin(), params.end(), m_g);
		return new iuValuesInParamsGenerator<T>( params );
	}

public:

#if IUTEST_HAS_CONCAT
	template<typename Other>
	iuConcatParamHolder<_Myt, Other> operator + (const Other& g) const
	{
		return iuConcatParamHolder<_Myt, Other>(*this, g);
	}
#endif

private:
	size_t m_num;
	G m_g;
};

/**
 * @brief	乱数ジェネレータ
*/
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 ()(void)
	{
		type val =  m_rnd.genrand();
		for( ; !(m_fn)(val); val = m_rnd.genrand() )
		{
		}
		return val;
	}
private:
	F m_fn;
	iuTypedRandom<type> m_rnd;
};

#endif

#if IUTEST_HAS_RANDOMVALUES

/**
 * @brief	乱数パラメータ生成器
*/
class iuRandomParamsHolder
{
public:
	iuRandomParamsHolder(size_t num, unsigned int seed=0) IUTEST_CXX_NOEXCEPT_SPEC
		: m_num(num), m_seed(seed) {}
public:
	template<typename T>
	operator iuIParamGenerator<T>* (void) const
	{
		unsigned int seed = m_seed;
		if( seed == 0 )
		{
			seed = GetIndefiniteValue();
		}
		iuValuesParamsGeneratorHolder< iuTypedRandom<T> > gen( m_num, iuTypedRandom<T>(seed) );
		return gen;
	}

public:

#if IUTEST_HAS_CONCAT
	template<typename Other>
	iuConcatParamHolder<iuRandomParamsHolder, Other> operator + (const Other& g) const
	{
		return iuConcatParamHolder<iuRandomParamsHolder, Other>(*this, g);
	}
#endif

private:
	size_t m_num;
	unsigned int m_seed;
};

#endif

}	// end of namespace detail
}	// end of namespace iutest

#endif

#endif // INCG_IRIS_IUTEST_GENPARAMS_HPP_7845F59A_825C_426A_B451_573245408998_

#if IUTEST_HAS_PARAM_TEST
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_pool.hpp
 * @brief		iris unit test memory pool ファイル
 *
 * @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_POOL_HPP_60F7CC27_EA15_4AC7_BCA6_80FFDCBC890E_
#define INCG_IRIS_IUTEST_POOL_HPP_60F7CC27_EA15_4AC7_BCA6_80FFDCBC890E_

//======================================================================
// include
#include <vector>

#if IUTEST_HAS_LIB && IUTEST_HAS_EXTERN_TEMPLATE

namespace iutest { namespace detail { class iuIObject; } }

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template class ::std::vector< ::iutest::detail::iuIObject* >;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#endif

namespace iutest {
namespace detail
{

/**
 * @brief	pool で管理するオブジェクトのベースクラス
*/
class iuIObject
{
public:
	virtual ~iuIObject() {}
};

/**
 * @brief	new したオブジェクトを管理
*/
class iuPool
{
	typedef ::std::vector<iuIObject*> pool;
	pool m_pool;
public:
	typedef iuIObject *value_ptr;

public:
	~iuPool(void)
	{
		// すべて解放する
		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(void) { static iuPool inst; return inst; }
};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_POOL_HPP_60F7CC27_EA15_4AC7_BCA6_80FFDCBC890E_

namespace iutest {
namespace detail
{

//======================================================================
// class
/**
 * @brief	パラメータ単体テスト TestInfo データクラス
*/
class IParamTestInfoData
{
public:
	class EachTestBase : public iuIObject {};
	template<typename T>
	class ParamEachTestBase : public EachTestBase
	{
	public:
		virtual void SetParam(const T& param) = 0;
	};
public:
	IParamTestInfoData(const char* name) : m_name(name) {}
	virtual TestCase* MakeTestCase(const char* , TestTypeId , SetUpMethod , TearDownMethod ) const = 0;
	virtual EachTestBase* RegisterTest(TestCase* , const char* ) const = 0;
	const char* GetName(void) const { return m_name.c_str(); }
protected:
	::std::string m_name;
};

/**
 * @brief	パラメータ単体テストインスタンスインターフェイス
*/
class IParamTestCaseInfo
{
public:
	virtual ~IParamTestCaseInfo(void) {}
protected:
	IParamTestCaseInfo(const ::std::string& base_name, const ::std::string& package_name)
		: m_testcase_base_name(base_name), m_package_name(package_name) {}
	
public:
	/**
	 * @brief	テストパターンの登録
	*/
	void AddTestPattern(IParamTestInfoData* testinfo)
	{
		m_testinfos.push_back(testinfo);
	};

public:
	void RegisterTests(void) const
	{
		for( TestInfoContainer::const_iterator it=m_testinfos.begin(), end=m_testinfos.end(); it != end; ++it )
		{
			OnRegisterTests(*it);
		}
	}
	
	::std::string GetTestCaseBaseName(void)	const { return m_testcase_base_name; }
	::std::string GetPackageName(void)		const { return m_package_name; }

public:
	bool is_same(const ::std::string& base_name, const ::std::string& package_name)
	{
		return m_testcase_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_testcase_base_name;
	::std::string m_package_name;
};

/**
 * @brief	パラメータ単体テストインスタンス
 * @tparam	T	= テストクラス
*/
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)();

public:
	/// コンストラクタ
	ParamTestCaseInfo(const ::std::string& testcase_name, const ::std::string& package_name)
		: IParamTestCaseInfo(testcase_name, package_name)
	{
	}
	virtual ~ParamTestCaseInfo(void) {}

	/**
	 * @brief	インスタンスの登録
	*/
	int	AddTestCaseInstantiation(::std::string name, pfnCreateGeneratorFunc* func)
	{
#if IUTEST_HAS_STD_EMPLACE
		m_instantiation.emplace_back(name, func);
#else
		m_instantiation.push_back(InstantiationPair(name, func));
#endif
		return 0;
	}

	/**
	 * @brief	テストの作成
	*/
	virtual void OnRegisterTests(IParamTestInfoData* infodata) const IUTEST_CXX_OVERRIDE
	{
		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)());

			::std::string testcase_name = m_package_name;
			if( !gen_it->first.empty() )
			{
				testcase_name += gen_it->first;
				testcase_name += "/";
			}
			testcase_name += m_testcase_base_name;
			TestCase* testcase = infodata->MakeTestCase(testcase_name.c_str()
				, internal::GetTypeId<Tester>()
				, Tester::SetUpTestCase
				, Tester::TearDownTestCase);

			if( p.get() != NULL )
			{
				int i=0;
				for( p->Begin(); !p->IsEnd(); p->Next() )
				{
					const ::std::string name = Tester::MakeTestName(infodata->GetName(), i, p->GetCurrent());
#if IUTEST_CHECK_STRICT
					if( !CheckTestName(testcase, name) )
					{
						IUTEST_LOG_(WARNING) << testcase_name << "." << name << " is already exist.";
					}
#endif
					EachTest* test = static_cast<EachTest*>(infodata->RegisterTest(testcase, name.c_str()));
					test->SetParam(p->GetCurrent());
					++i;
				}
			}
		}
	}

private:
	static bool CheckTestName(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, pfnCreateGeneratorFunc* > InstantiationPair;
	typedef ::std::vector<InstantiationPair> InstantiationContainer;
	InstantiationContainer m_instantiation;
};

/**
 * @brief	パラメータテストパターン保管庫
*/
class ParamTestCaseHolder
{
private:
	~ParamTestCaseHolder(void)
	{
		// 解放
		for( TestCaseInfoContainer::const_iterator it=m_testcase_infos.begin(), end=m_testcase_infos.end(); it != end; ++it )
		{
			delete *it;
		}
	}
public:
	template<typename T>
	ParamTestCaseInfo<T>* GetTestCasePatternHolder(const ::std::string& testcase, const ::std::string& package
		IUTEST_APPEND_EXPLICIT_TEMPLATE_TYPE_(T)
		)
	{
		for( TestCaseInfoContainer::iterator it=m_testcase_infos.begin(), end=m_testcase_infos.end(); it != end; ++it )
		{
			if( (*it)->is_same(testcase, package) )
			{
				return static_cast<ParamTestCaseInfo<T>*>(*it);
			}
		}
		ParamTestCaseInfo<T>* p = new ParamTestCaseInfo<T>(testcase, package);
		m_testcase_infos.push_back(p);
		return p;
	}

public:
	size_t count(void) const { return m_testcase_infos.size(); }

private:
	struct RegisterTestsFunctor
	{
		inline void operator ()(const IParamTestCaseInfo* p) const
		{
			p->RegisterTests();
		}
	};

	// テストを登録
	void RegisterTests(void)
	{
		::std::for_each(m_testcase_infos.begin(), m_testcase_infos.end(), RegisterTestsFunctor());
	}
private:
	friend class ::iutest::UnitTest;
	typedef ::std::vector<IParamTestCaseInfo*> TestCaseInfoContainer;
	TestCaseInfoContainer m_testcase_infos;
};

}	// end of namespace detail
}	// end of namespace iutest

#endif

#endif // INCG_IRIS_IUTEST_PARAMS_UTIL_HPP_19F0C0BB_EEAE_4E8B_B269_A09A4A45E890_

namespace iutest
{

//======================================================================
// class
/**
 * @brief	テスト全体の管理者
*/
class UnitTest : public UnitTestImpl
{
public:
	
	static UnitTest& instance(void)		{ static UnitTest inst; return inst; }
	/**
	 * @brief	UnitTest インスタンスの取得
	*/
	static UnitTest* GetInstance(void)	{ return &instance(); }

public:
	/**
	 * @brief	テスト中の TestCase の取得
	*/
	const TestCase*		current_test_case(void)	const { return m_current_testcase; }

	/**
	 * @brief	テスト中の TestInfo の取得
	 * @note	互換性のため メンバ関数 にしています。
	*/
	const TestInfo*		current_test_info(void)	const { return Test::GetCurrentTestInfo(); }

	
	unsigned int		random_seed(void)		const { return TestEnv::current_random_seed(); }

	
	int					repeat_counter(void)	const IUTEST_CXX_NOEXCEPT_SPEC { return m_repeat_counter; }

public:
	
	int				total_test_count(void)		const IUTEST_CXX_NOEXCEPT_SPEC { return m_total_test_num; }
	
	int				reportable_test_count(void)	const;
	
	int				test_to_run_count(void)		const IUTEST_CXX_NOEXCEPT_SPEC { return m_should_run_num; }
	
	int				failed_test_count(void)		const;
	
	int				disabled_test_count(void)	const IUTEST_CXX_NOEXCEPT_SPEC { return m_disable_num; }
	
	int				reportable_disabled_test_count(void) const;
	
	int				successful_test_count(void)	const;
	
	int				skip_test_count(void)		const;
	
	int				reportable_skip_test_count(void) const;
	
	int				test_run_skipped_count(void) const;
	
	int				reportable_test_run_skipped_count(void) const;

	
	int				total_test_case_count(void)	const { return m_testcases.size(); }
	
	int				test_case_to_run_count(void) const;
	
	int				successful_test_case_count(void) const;
	
	int				failed_test_case_count(void) const;

	
	const TestResult* ad_hoc_testresult(void) const IUTEST_CXX_NOEXCEPT_SPEC { return &m_ad_hoc_testresult; }

	
	TimeInMillisec	elapsed_time(void)		const IUTEST_CXX_NOEXCEPT_SPEC { return m_elapsedmsec; }

	
	TimeInMillisec	start_timestamp(void)	const IUTEST_CXX_NOEXCEPT_SPEC { return m_start_timestamp; }

	
	const TestCase*	GetTestCase(int index)	const { return m_testcases[index]; }

	
	bool			Passed(void)			const;
	
	bool			Failed(void)			const { return !Passed(); }

	
	TestEventListeners&	listeners(void)		const { return TestEnv::event_listeners(); }

protected:
	/**
	 * @brief	テストの実行
	*/
	int Run(void);

private:
#if IUTEST_HAS_EXCEPTIONS && IUTEST_HAS_SEH
	int RunOnMSC(void);
#endif
	int RunImpl(void);

	/**
	 * @brief	テストの実行（１ループ）
	*/
	bool RunOnce(void);

private:
	/**
	 * @brief	プログラムの開始
	*/
	void TestProgramStart(void);

	/**
	 * @brief	イテレーション毎のセットアップ
	*/
	void SetUpTestIteration(void);

	/**
	 * @brief	環境セットアップ
	*/
	void EnvironmentSetUp(void);

	/**
	 * @brief	環境解除
	*/
	void EnvironmentTearDown(void);

	/**
	 * @brief	プログラムの終了
	*/
	void TestProgramEnd(void);

private:
	// C言語の終了コールバック関数
	static void OnExit(void)
	{
		instance().TestProgramEnd();
	}

private:
	UnitTest(void)
		: 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::LoadEnviromentVariable();
	}
#if defined(_MSC_VER) && _MSC_VER < 1300
public:	// VC++6.0 bug
#endif
	~UnitTest(void)
	{
		TestEnv::ReleaseGlobalTestEnvironment();
		TestEnv::SetGlobalTestPartResultReporter(NULL);
	}

private:
	// 初期化処理
	void Initialize(void);

#if IUTEST_HAS_PARAM_TEST
public:
	
	detail::ParamTestCaseHolder& parameterized_test_registry(void) IUTEST_CXX_NOEXCEPT_SPEC{ return m_param_testcase_holder; }

private:
	detail::ParamTestCaseHolder	m_param_testcase_holder;
#endif

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;

	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(UnitTest);
};

namespace detail
{

/**
 * @private
 * @internal
 * @brief	単体テストインスタンス
*/
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 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);
	}

private:
	TestCase* AddTestCase(const char* testcase, TestTypeId id, SetUpMethod setup, TearDownMethod teardown)
	{
#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
		return UnitTest::instance().AddTestCase<TestCase>(testcase, id, setup, teardown);
#else
		return UnitTest::instance().AddTestCase(testcase, id, setup, teardown, detail::explicit_type<TestCase>());
#endif
	}
private:
	TestCaseMediator	m_mediator;
	TestInfo			m_info;
	iuFactory<Tester>	m_factory;
};

}	// end of namespace detail
}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_core.ipp
 * @brief		iris unit test core
 *
 * @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_CORE_IPP_33560431_783B_4AE7_8FC8_6E78355CAF87_
#define INCG_IRIS_IUTEST_CORE_IPP_33560431_783B_4AE7_8FC8_6E78355CAF87_

//======================================================================
// include

namespace iutest
{

IUTEST_IPP_INLINE int UnitTest::reportable_test_count(void) const
{
	return detail::SumOverList(m_testcases, &TestCase::reportable_test_count);
}

IUTEST_IPP_INLINE int UnitTest::failed_test_count(void) const
{
	return detail::SumOverList(m_testcases, &TestCase::failed_test_count);
}

IUTEST_IPP_INLINE int UnitTest::reportable_disabled_test_count(void) const
{
	return detail::SumOverList(m_testcases, &TestCase::reportable_disabled_test_count);
}

IUTEST_IPP_INLINE int UnitTest::successful_test_count(void) const
{
	return detail::SumOverList(m_testcases, &TestCase::successful_test_count);
}

IUTEST_IPP_INLINE int UnitTest::skip_test_count(void) const
{
	return detail::SumOverList(m_testcases, &TestCase::skip_test_count);
}

IUTEST_IPP_INLINE int UnitTest::reportable_skip_test_count(void) const
{
	return detail::SumOverList(m_testcases, &TestCase::reportable_skip_test_count);
}

IUTEST_IPP_INLINE int UnitTest::test_run_skipped_count(void) const
{
	return detail::SumOverList(m_testcases, &TestCase::test_run_skipped_count);
}

IUTEST_IPP_INLINE int UnitTest::reportable_test_run_skipped_count(void) const
{
	return detail::SumOverList(m_testcases, &TestCase::reportable_test_run_skipped_count);
}

IUTEST_IPP_INLINE int UnitTest::test_case_to_run_count(void) const
{
	return detail::CountIfOverList(m_testcases, &TestCase::should_run);
}

IUTEST_IPP_INLINE int UnitTest::successful_test_case_count(void) const
{
	return detail::CountIfOverList(m_testcases, &TestCase::Passed);
}

IUTEST_IPP_INLINE int UnitTest::failed_test_case_count(void) const
{
	return detail::CountIfOverList(m_testcases, &TestCase::Failed);
}

IUTEST_IPP_INLINE bool UnitTest::Passed(void) 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;
}

IUTEST_IPP_INLINE int UnitTest::Run(void)
{
	if( m_init_iutest_count == 0 )
	{
//#if IUTEST_HAS_PARAM_TEST
//		if( m_param_testcase_holder.count() )
//#endif
		{
			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;
	}

	int ret = 1;
#if IUTEST_HAS_EXCEPTIONS
	if( TestFlag::IsEnableFlag(TestFlag::CATCH_EXCEPTION_GLOBAL) )
	{
		try
		{
#if IUTEST_HAS_SEH
			ret = RunOnMSC();
#else
			ret = RunImpl();
#endif
		}
		//catch( ::std::exception& e )
		//{
		//	iutest::AssertionHelper(NULL, -1, detail::FormatCxxException(e.what()), TestPartResult::kFatalFailure) = AssertionHelper::Fixed();
		//}
		catch( ... )
		{
		}
	}
	else
#endif
	{
		ret = RunImpl();
	}
	return ret;
}

#if IUTEST_HAS_EXCEPTIONS && IUTEST_HAS_SEH
IUTEST_IPP_INLINE int UnitTest::RunOnMSC(void)
{
	_EXCEPTION_POINTERS* ep = NULL;
	int ret = 1;
	__try
	{
		ret = RunImpl();
	}
	__except (ep = GetExceptionInformation()
#if IUTEST_HAS_MINIDUMP
		, detail::MiniDump::Create("minidump.dump", ep)
#endif
		, detail::seh_exception::should_process_through_break_and_cppexceptions(GetExceptionCode()))
	{
		detail::seh_exception::translator(GetExceptionCode(), ep);
	}
	return ret;
}
#endif

IUTEST_IPP_INLINE int UnitTest::RunImpl(void)
{
	m_repeat_counter = 0;
	int repeat = TestEnv::get_repeat_count();
	if( repeat == 0 )
	{
		return 0;
	}

	m_start_timestamp = detail::GetTimeInMillis();
	TestProgramStart();

	bool result = true;
	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();

	return result ? 0 : 1;
}

IUTEST_IPP_INLINE bool UnitTest::RunOnce(void)
{
	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;
			(it)->Run();
			m_current_testcase = NULL;
		}
		m_elapsedmsec = sw.stop();
	}

	// グローバル環境セット
	EnvironmentTearDown();

	return Passed();
}

IUTEST_IPP_INLINE void UnitTest::TestProgramStart(void)
{
#if 0
#if IUTEST_HAS_EXCEPTIONS && defined(_MSC_VER) && IUTEST_HAS_SEH
	// /EHa オプションが必要
	if( TestFlag::IsEnableFlag(TestFlag::CATCH_EXCEPTION) )
	{
		// SEH 例外に対応する
		_set_se_translator(detail::seh_exception::translator);
	}
#endif
#endif

	// フィルタリング
	m_should_run_num = 0;
	m_disable_num = 0;
	for( iuTestCases::iterator it = m_testcases.begin(), end=m_testcases.end(); it != end; ++it )
	{
		(it)->filter();
		m_should_run_num += (it)->test_to_run_count();
		m_disable_num += (it)->disabled_test_count();
	}

	atexit(OnExit);
#if IUTEST_HAS_QUICK_EXIT
	::std::at_quick_exit(OnExit);
#endif

	m_test_started = true;

	listeners().OnTestProgramStart(*this);
}

IUTEST_IPP_INLINE void UnitTest::SetUpTestIteration(void)
{
	TestEnv::SetUp();
}

IUTEST_IPP_INLINE void UnitTest::EnvironmentSetUp(void)
{
	listeners().OnEnvironmentsSetUpStart(*this);
	for( iuEnvironmentList::iterator it = TestEnv::environments().begin(), end=TestEnv::environments().end(); it != end; ++it )
	{
		(*it)->SetUp();
	}
	listeners().OnEnvironmentsSetUpEnd(*this);
}

IUTEST_IPP_INLINE void UnitTest::EnvironmentTearDown(void)
{
	listeners().OnEnvironmentsTearDownStart(*this);
	for( iuEnvironmentList::reverse_iterator it = TestEnv::environments().rbegin(), end=TestEnv::environments().rend(); it != end; ++it )
	{
		(*it)->TearDown();
	}
	listeners().OnEnvironmentsTearDownEnd(*this);
}

IUTEST_IPP_INLINE void UnitTest::TestProgramEnd(void)
{
	if( !m_test_started )
	{
		return;
	}
	if( current_test_info() != NULL )
	{
		IUTEST_EXPECT_FAILURE("program exit.");
	}
	listeners().OnTestProgramEnd(*this);
	m_test_started = false;
}

IUTEST_IPP_INLINE void UnitTest::Initialize(void)
{
	m_init_iutest_count++;

	ClearAdHocTestResult();

	// ファイルシステムの初期化
	if( detail::IFileSystem::GetInstance() == NULL )
	{
#if defined(IUTEST_FILE)
		static FileSystem<IUTEST_FILE> filesystem;
		filesystem.Initialize();
#elif IUTEST_HAS_FOPEN
		static FileSystem<StdioFile> filesystem;
		filesystem.Initialize();
#endif
	}

	// 以降初回のみ
	if( m_init_iutest_count != 1 )
	{
		return;
	}

#if IUTEST_HAS_PARAM_TEST
	m_param_testcase_holder.RegisterTests();
#endif
}

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_CORE_IPP_33560431_783B_4AE7_8FC8_6E78355CAF87_
#endif

#endif // INCG_IRIS_IUTEST_CORE_HPP_33560431_783B_4AE7_8FC8_6E78355CAF87_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_param_tests.hpp
 * @brief		iris unit test parameter 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PARAM_TESTS_HPP_3DBBF55E_A076_4207_B49E_34734EE333EE_
#define INCG_IRIS_IUTEST_PARAM_TESTS_HPP_3DBBF55E_A076_4207_B49E_34734EE333EE_

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

//======================================================================
// include

//======================================================================
// class
namespace iutest
{

/**
 * @brief	any
*/
class any
{
	typedef internal::TypeId type_id;
public:
	any(void) : content(NULL) {}
	template<typename T>
	any(const T& rhs) : content(new holder<T>(rhs)) {}
	any(const any& rhs) : content(rhs.content == NULL ? NULL : rhs.content->clone()) {}
	~any(void) { delete content; }
public:
	/**
	 * @brief	swap
	*/
	any& swap(any& rhs)
	{
		::std::swap(content, rhs.content);
		return *this;
	}
	/**
	 * @brief	空かどうか
	 * @retval	true = 空
	*/
	bool empty(void) const
	{
		return content == NULL;
	}
	/**
	 * @brief	要素のクリア
	*/
	void clear(void)
	{
		any().swap(*this);
	}
	/**
	 * @brief	型IDの取得
	 * @return	型ID
	*/
	type_id type(void) const
	{
		return content == NULL ? internal::GetTypeId<void>() : content->type();
	}
	/**
	 * @brief	型の比較
	 * @retval	true = 同一
	*/
	template<typename T>
	bool type_equal(void) const
	{
		return type() == internal::GetTypeId<T>();
	}

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(void) const = 0;
		virtual placeholder* clone(void) const = 0;
	};
	template<typename T>
	class holder : public placeholder
	{
	public:
		holder(const T& v) : held(v) {}
	public:
		virtual type_id type(void) const IUTEST_CXX_OVERRIDE
		{
			return internal::GetTypeId<T>();
		}
		virtual placeholder* clone(void) const IUTEST_CXX_OVERRIDE
		{
			return new holder<T>(held);
		}
	public:
		T held;
	private:
		holder& operator = (const holder&);
	};
private:
	placeholder* content;
};

#if IUTEST_HAS_EXCEPTIONS
/**
 * @brief	any_cast の失敗例外
*/
class bad_any_cast : public ::std::bad_cast {};
#endif

inline void swap(any& lhs, any& rhs) { lhs.swap(rhs); }

/**
 * @brief	型を考慮したキャスト
*/
template<typename T>
T* any_cast(any* p)
{
	return p != NULL && p->type_equal<T>() ?
		&static_cast< any::holder<T>* >(p->content)->held : NULL;
}

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 == NULL ) {
		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));
}

/**
 * @brief	型を考慮せずキャスト
*/
template<typename T>
T* unsafe_any_cast(any* p)
{
	return p != NULL ?
		&static_cast< any::holder<T>* >(p->content)->held : NULL;
}

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));
}

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_ANY_HPP_8DB2417F_568A_4E01_95AD_21164565B975_

#if IUTEST_HAS_PARAM_TEST

//======================================================================
// define
/**
 * @defgroup	VALUE_PARAMETERIZED_TEST	値のパラメータ化テスト
 * @brief		値のパラメータ化テスト
*/

/**
 * @ingroup	VALUE_PARAMETERIZED_TEST
 * @def		IUTEST_INSTANTIATE_TEST_CASE_P
 * @brief	パラメータテストインスタンス化マクロ
 * @param	prefix_			= インスタンス名
 * @param	testfixture_	= テストフィクスチャ
 * @param	generator_		= Range, Bool, Values, ValuesIn, Combine, Pairwise ...
*/
#define IUTEST_INSTANTIATE_TEST_CASE_P(prefix_, testfixture_, generator_)	\
	IIUT_INSTANTIATE_TEST_CASE_P_(prefix_, testfixture_, generator_)

/**
 * @ingroup	VALUE_PARAMETERIZED_TEST
 * @def		IUTEST_P(testfixture_, testname_)
 * @brief	パラメータユーザー指定テスト関数定義マクロ
 * @param	testfixture_	= テストフィクスチャ
 * @param	testname_		= テスト名
 * @note	
 *	class TestCaseName : public ::iutest::TestWithParam<int> {};\n
 *  IUTEST_P(TestCaseName, TestName) {}\n
 *  IUTEST_INSTANTIATE_TEST_CASE_P(InstantiateName, TestCaseName, ParamGenerator);\n
*/
#define IUTEST_P(testfixture_, testname_)		IIUT_TEST_P_(testfixture_, testname_)


#if IUTEST_HAS_ANY_PARAM_TEST

/**
 * @ingroup	VALUE_PARAMETERIZED_TEST
 * @def		IUTEST_INSTANTIATE_TEST_CASE_AP
 * @brief	パラメータテストインスタンス化マクロ
 * @param	prefix_		= インスタンス名
 * @param	testcase_	= テストケース名
 * @param	generator_	= Range, Bool, Values, ValuesIn, Combine, Pairwise ...
*/
#define IUTEST_INSTANTIATE_TEST_CASE_AP(prefix_, testcase_, generator_)	\
	IIUT_INSTANTIATE_TEST_CASE_P_(prefix_, IUTEST_ALIAS_TESTNAME_F(iuTestWithAny, testcase_), generator_)

/**
 * @ingroup	VALUE_PARAMETERIZED_TEST
 * @def		IUTEST_AP(testcase_, testname_)
 * @brief	パラメータユーザー指定テスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
 * @note	
 *  IUTEST_AP(TestCaseName, TestName) {}\n
 *  IUTEST_INSTANTIATE_TEST_CASE_AP(InstantiateName, TestCaseName, ParamGenerator);\n
*/
#define IUTEST_AP(testcase_, testname_)			IIUT_TEST_P_(IUTEST_ALIAS_TESTNAME_F(iuTestWithAny, testcase_), testname_)


#endif


/**
 * @private
 * @{
*/

#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
#  define IIUT_GETTESTCASEPATTERNHOLDER(T, testcase_, package_)	\
	::iutest::UnitTest::GetInstance()->parameterized_test_registry().GetTestCasePatternHolder<T>(testcase_, package_)
#else
#  define IIUT_GETTESTCASEPATTERNHOLDER(T, testcase_, package_)	\
	::iutest::UnitTest::GetInstance()->parameterized_test_registry().GetTestCasePatternHolder(testcase_, package_, ::iutest::detail::explicit_type<T>())
#endif

#if IUTEST_HAS_AUTOFIXTURE_PARAM_TEST
#  if IUTEST_HAS_IF_EXISTS
#    define IIUT_TEST_P_FIXTURE_DECL_(testcase_)	IIUT_TEST_P_FIXTURE_DECL_I(IIUT_TO_VARNAME_(testcase_))
#    define IIUT_TEST_P_FIXTURE_DECL_I(testcase_)	IUTEST_IF_NOT_EXISTS(testcase_, typedef ::iutest::TestWithAny testcase_;)
#    define IIUT_TEST_P_BASE_FIXTURE(testcase_)		IIUT_TO_VARNAME_(testcase_)
#  else
#    define IIUT_TEST_P_FIXTURE_DECL_(testcase_)
#    if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#      define IIUT_TEST_P_BASE_FIXTURE(testcase_)	::iutest::detail::paramtest_select_base_testcase< void (int (IIUT_TO_VARNAME_(testcase_))) >::type
#    else
#      define IIUT_TEST_P_BASE_FIXTURE(testcase_)	IIUT_TO_VARNAME_(testcase_)
#    endif
#  endif
#else
#  define IIUT_TEST_P_FIXTURE_DECL_(testcase_)
#  define IIUT_TEST_P_BASE_FIXTURE(testcase_)		IIUT_TO_VARNAME_(testcase_)
#endif

/**
 * @brief	パラメータテスト登録
*/
#define IIUT_INSTANTIATE_TEST_CASE_P_(prefix_, testcase_, generator_)								\
	IIUT_TEST_P_FIXTURE_DECL_(testcase_)															\
	static ::iutest::detail::iuIParamGenerator< IIUT_TEST_P_BASE_FIXTURE(testcase_)::ParamType >*	\
		IUTEST_TEST_P_EVALGENERATOR_NAME_(prefix_, testcase_)(void) { return generator_; }			\
		int IUTEST_TEST_P_INSTANTIATIONREGISTER_NAME_(prefix_, testcase_)(void) {					\
			::iutest::detail::ParamTestCaseInfo< IIUT_TEST_P_BASE_FIXTURE(testcase_) >* p =			\
				IIUT_GETTESTCASEPATTERNHOLDER( IIUT_TEST_P_BASE_FIXTURE(testcase_)					\
					, IIUT_TO_NAME_STR_(testcase_), IUTEST_GET_PACKAGENAME_());						\
			return p->AddTestCaseInstantiation(#prefix_, IUTEST_TEST_P_EVALGENERATOR_NAME_(prefix_, testcase_));	\
		} IUTEST_TEST_P_INSTANTIATIONREGISTER_(prefix_, testcase_)

/**
 * @brief	パラメータテストクラス定義
*/
#define IIUT_TEST_P_(testcase_, testname_)															\
	IIUT_TEST_P_FIXTURE_DECL_(testcase_)															\
	class IUTEST_TEST_CLASS_NAME_(testcase_, testname_) : public IIUT_TEST_P_BASE_FIXTURE(testcase_) {		\
		public: IUTEST_TEST_CLASS_NAME_(testcase_, testname_)(void) {}								\
		protected: virtual void Body(void);															\
		private: static int AddRegister(void) {														\
			static ::iutest::detail::ParamTestInstance< IUTEST_TEST_CLASS_NAME_(testcase_			\
				, testname_) > testinfo(IIUT_TO_NAME_STR_(testname_));								\
			IIUT_GETTESTCASEPATTERNHOLDER(IIUT_TEST_P_BASE_FIXTURE(testcase_), IIUT_TO_NAME_STR_(testcase_)	\
					, IUTEST_GET_PACKAGENAME_())->AddTestPattern(&testinfo); return 0;				\
		}																							\
		static int dummy_;																			\
		IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(IUTEST_TEST_CLASS_NAME_(testcase_, testname_));			\
	};																								\
	int IUTEST_TEST_CLASS_NAME_(testcase_, testname_)::dummy_ IUTEST_ATTRIBUTE_UNUSED_				\
		= IUTEST_TEST_CLASS_NAME_(testcase_, testname_)::AddRegister();								\
	void IUTEST_TEST_CLASS_NAME_(testcase_, testname_)::Body(void)

#define IIUT_TEST_P_IGNORE_(testcase_, testname_)													\
	class IUTEST_TEST_CLASS_NAME_(testcase_, testname_) : public IIUT_TEST_P_BASE_FIXTURE(testcase_) {		\
		public: IUTEST_TEST_CLASS_NAME_(testcase_, testname_)(void) {}								\
		protected: virtual void Body(void) { IUTEST_SKIP() << "ignored test..."; }					\
		template<typename T>void Body(void);														\
		private: static int AddRegister(void) {														\
			static ::iutest::detail::ParamTestInstance< IUTEST_TEST_CLASS_NAME_(testcase_			\
				, testname_) > testinfo(IIUT_TO_NAME_STR_(testname_));								\
			IIUT_GETTESTCASEPATTERNHOLDER(IIUT_TEST_P_BASE_FIXTURE(testcase_), IIUT_TO_NAME_STR_(testcase_)	\
				, IUTEST_GET_PACKAGENAME_())->AddTestPattern(&testinfo); return 0;					\
		}																							\
		static int dummy_;																			\
		IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(IUTEST_TEST_CLASS_NAME_(testcase_, testname_));			\
	};																								\
	int IUTEST_TEST_CLASS_NAME_(testcase_, testname_)::dummy_ IUTEST_ATTRIBUTE_UNUSED_				\
		= IUTEST_TEST_CLASS_NAME_(testcase_, testname_)::AddRegister();								\
	template<typename T>void IUTEST_TEST_CLASS_NAME_(testcase_, testname_)::Body(void)

#define IUTEST_TEST_P_EVALGENERATOR_NAME_(prefix_, testcase_)	IIUT_TEST_P_EVALGENERATOR_NAME_I(prefix_, IIUT_TO_VARNAME_(testcase_))
#define IIUT_TEST_P_EVALGENERATOR_NAME_I(prefix_, testcase_)	IIUT_TEST_P_EVALGENERATOR_NAME_I_(prefix_, testcase_)
#define IIUT_TEST_P_EVALGENERATOR_NAME_I_(prefix_, testcase_)	s_##prefix_##_##testcase_##_EvalGenerator_

#define IUTEST_TEST_P_INSTANTIATIONREGISTER_NAME_(prefix_, testcase_)	IIUT_TEST_P_INSTANTIATIONREGISTER_NAME_I(prefix_, IIUT_TO_VARNAME_(testcase_))
#define IIUT_TEST_P_INSTANTIATIONREGISTER_NAME_I(prefix_, testcase_)	IIUT_TEST_P_INSTANTIATIONREGISTER_NAME_I_(prefix_, testcase_)
#define IIUT_TEST_P_INSTANTIATIONREGISTER_NAME_I_(prefix_, testcase_)	prefix_##_##testcase_##_TestCaseInstantiationRegister

#define IUTEST_TEST_P_INSTANTIATIONREGISTER_(prefix_, testcase_)			IIUT_TEST_P_INSTANTIATIONREGISTER_I(prefix_, IIUT_TO_VARNAME_(testcase_), IUTEST_TEST_P_INSTANTIATIONREGISTER_NAME_(prefix_, testcase_))
#define IIUT_TEST_P_INSTANTIATIONREGISTER_I(prefix_, testcase_, register_)	IIUT_TEST_P_INSTANTIATIONREGISTER_I_(prefix_, testcase_, register_)
#define IIUT_TEST_P_INSTANTIATIONREGISTER_I_(prefix_, testcase_, register_)	int s_##prefix_##_##testcase_##_dummy = register_()

/**
 * @}
*/

namespace iutest {
namespace detail
{

//======================================================================
// class
/**
 * @private
 * @brief	パラメータ単体テスト TestInfo 情報インスタンス
*/
template<typename T>
class ParamTestInstance : public IParamTestInfoData
{
	typedef T Tester;
	typedef typename Tester::ParamType ParamType;
	typedef detail::iuParamTestFactory<T> Factory;

	// 各テストのインスタンス
	class EachTest IUTEST_CXX_FINAL : public IParamTestInfoData::ParamEachTestBase<ParamType>
	{
	public:
		EachTest(TestCase* testcase, const char* name)
			: m_mediator(testcase)
			, m_info(&m_mediator, name, &m_factory)
		{
			UnitTest::instance().AddTestInfo(testcase, &m_info);
		}
	private:
		virtual void SetParam(const ParamType& param) IUTEST_CXX_OVERRIDE
		{
			m_factory.SetParam(param);
			m_info.set_value_param(PrintToString(param).c_str());
		}
	private:
		TestCaseMediator	m_mediator;
		Factory				m_factory;
		TestInfo			m_info;
	};
public:
	ParamTestInstance(const char* testcase_name) : IParamTestInfoData(testcase_name) {}

private:
	// テストケースの作成
	virtual TestCase* MakeTestCase(const char* testcase_name, TestTypeId id, SetUpMethod setup, TearDownMethod teardown) const IUTEST_CXX_OVERRIDE
	{
#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
		return UnitTest::instance().AddTestCase<TestCase>(testcase_name, id, setup, teardown);
#else
		return UnitTest::instance().AddTestCase(testcase_name, id, setup, teardown, detail::explicit_type<TestCase>());
#endif
	}

	// テストの作成登録
	virtual IParamTestInfoData::EachTestBase* RegisterTest(TestCase* testcase, const char* name) const IUTEST_CXX_OVERRIDE
	{
		EachTest* test = new EachTest(testcase, name);
		// new オブジェクトを管理してもらう
		detail::iuPool::GetInstance().push(test);
		return test;
	}
};

}	// end of namespace detail

/**
 * @ingroup	PARAMETERIZED_TEST
 * @brief	any パラメータテストフィクスチャ
*/
class TestWithAny : public Test, public WithParamInterface<any>
{
public:
	/**
	 * @brief	パラメータの取得
	*/
	static const ParamType& GetParam(void) { return WithParamInterface<any>::GetParam(); }

	/**
	 * @brief	パラメータの取得
	*/
	template<typename T>
	static T GetParam(void) { return unsafe_any_cast<T>(WithParamInterface<any>::GetParam()); }
};

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace detail
{

/**
 * @brief	クラス選択
*/
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;
};

}	// end of namespace detail
#endif

//======================================================================
// function
/**
 * @ingroup		VALUE_PARAMETERIZED_TEST
 * @defgroup	PARAM_GENERATOR	Parameter Generator
 * @brief		パラメータ生成器
 * @details		IUTEST_INSTANTIATE_TEST_CASE_P に使用可能なパラメータ生成器
 * @{
*/

/**
 * @brief	範囲パラメータ
*/
template<typename T>
detail::iuParamGenerator<T> IUTEST_ATTRIBUTE_UNUSED_ Range(T begin, T end, T step=1)
{
	return new detail::iuRangeParamsGenerator<T>(begin, end, step);
}

/**
 * @brief	真偽値パラメータ
*/
inline detail::iuParamGenerator<bool> IUTEST_ATTRIBUTE_UNUSED_ Bool(void)
{
	return new detail::iuBoolParamsGenerator<bool>();
}

#if IUTEST_HAS_VALUESGEN

/**
 * @brief	ユーザー定義ジェネレータ利用パラメータ
*/
template<typename Generator>
inline detail::iuValuesParamsGeneratorHolder<Generator> IUTEST_ATTRIBUTE_UNUSED_ ValuesGen(size_t num, const Generator& gen)
{
	return detail::iuValuesParamsGeneratorHolder<Generator>(num, gen);
}

/**
 * @brief	乱数ジェネレータ
*/
template<typename T, typename F>
inline detail::iuRandomFilterParamGenerator<T, F> IUTEST_ATTRIBUTE_UNUSED_ RandomGenerator(const F& fn, unsigned int seed=0)
{
	if( seed == 0 )
	{
		seed = detail::GetIndefiniteValue();
	}
	return detail::iuRandomFilterParamGenerator<T, F>(fn, seed);
}

#endif

#if IUTEST_HAS_RANDOMVALUES
/**
 * @brief	乱数値パラメータ
*/
inline detail::iuRandomParamsHolder IUTEST_ATTRIBUTE_UNUSED_ RandomValues(size_t num, unsigned int seed=0)
{
	return detail::iuRandomParamsHolder(num, seed);
}
#endif

/**
 * @brief	値配列パラメータ
*/
template<typename Container>
inline detail::iuParamGenerator< typename Container::value_type > IUTEST_ATTRIBUTE_UNUSED_ ValuesIn(Container container)
{
	return new detail::iuValuesInParamsGenerator< typename Container::value_type >(container);
}

#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)

template<typename T, size_t SIZE>
inline detail::iuParamGenerator<T> IUTEST_ATTRIBUTE_UNUSED_ ValuesIn(const T (&v)[SIZE])
{
	return new detail::iuValuesInParamsGenerator<T>(v, v+SIZE);
}

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

template<typename Ite>
inline detail::iuParamGenerator< typename detail::IteratorTraits<Ite>::type > IUTEST_ATTRIBUTE_UNUSED_ ValuesIn(Ite begin, Ite end)
{
	return new detail::iuValuesInParamsGenerator< typename detail::IteratorTraits<Ite>::type >(begin, end);
}
#endif

#if IUTEST_HAS_INITIALIZER_LIST

template<typename T>
inline detail::iuParamGenerator<T> IUTEST_ATTRIBUTE_UNUSED_ ValuesIn(::std::initializer_list<T> l)
{
	return new detail::iuValuesInParamsGenerator<T>(l);
}
#endif

#endif

#if IUTEST_HAS_VARIADIC_VALUES
/**
 * @brief	値配列パラメータ
*/
template<typename ...Args>
inline detail::iuValueArray<Args...> IUTEST_ATTRIBUTE_UNUSED_ Values(Args... args)
{
	return detail::iuValueArray<Args...>(args...);
}

#else

#define IIUT_DECL_VALUES_(n)	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >					\
	inline detail::iuValueArray##n< IUTEST_PP_ENUM_PARAMS(n, T) >									\
	IUTEST_ATTRIBUTE_UNUSED_ Values( IUTEST_PP_ENUM_BINARY_PARAMS(n, T, t) )	{					\
	return detail::iuValueArray##n< IUTEST_PP_ENUM_PARAMS(n, T) >( IUTEST_PP_ENUM_PARAMS(n, t) );	\
	}

/**
 * @brief	値配列パラメータ
 * @note	50引数まで使用可能
*/
IIUT_DECL_VALUES_(1)
IIUT_DECL_VALUES_(2)
IIUT_DECL_VALUES_(3)
IIUT_DECL_VALUES_(4)
IIUT_DECL_VALUES_(5)
IIUT_DECL_VALUES_(6)
IIUT_DECL_VALUES_(7)
IIUT_DECL_VALUES_(8)
IIUT_DECL_VALUES_(9)
IIUT_DECL_VALUES_(10)
IIUT_DECL_VALUES_(11)
IIUT_DECL_VALUES_(12)
IIUT_DECL_VALUES_(13)
IIUT_DECL_VALUES_(14)
IIUT_DECL_VALUES_(15)
IIUT_DECL_VALUES_(16)
IIUT_DECL_VALUES_(17)
IIUT_DECL_VALUES_(18)
IIUT_DECL_VALUES_(19)
IIUT_DECL_VALUES_(20)
IIUT_DECL_VALUES_(21)
IIUT_DECL_VALUES_(22)
IIUT_DECL_VALUES_(23)
IIUT_DECL_VALUES_(24)
IIUT_DECL_VALUES_(25)
IIUT_DECL_VALUES_(26)
IIUT_DECL_VALUES_(27)
IIUT_DECL_VALUES_(28)
IIUT_DECL_VALUES_(29)
IIUT_DECL_VALUES_(30)
IIUT_DECL_VALUES_(31)
IIUT_DECL_VALUES_(32)
IIUT_DECL_VALUES_(33)
IIUT_DECL_VALUES_(34)
IIUT_DECL_VALUES_(35)
IIUT_DECL_VALUES_(36)
IIUT_DECL_VALUES_(37)
IIUT_DECL_VALUES_(38)
IIUT_DECL_VALUES_(39)
IIUT_DECL_VALUES_(40)
IIUT_DECL_VALUES_(41)
IIUT_DECL_VALUES_(42)
IIUT_DECL_VALUES_(43)
IIUT_DECL_VALUES_(44)
IIUT_DECL_VALUES_(45)
IIUT_DECL_VALUES_(46)
IIUT_DECL_VALUES_(47)
IIUT_DECL_VALUES_(48)
IIUT_DECL_VALUES_(49)
IIUT_DECL_VALUES_(50)

#undef IIUT_DECL_VALUES_

#endif

#if IUTEST_HAS_CONCAT
/**
 * @brief	パラメータの結合
*/
template<typename G1, typename G2>
detail::iuConcatParamHolder<G1, G2> Concat(const G1& g1, const G2& g2)
{
	return detail::iuConcatParamHolder<G1, G2>(g1, g2);
}
#endif

#if IUTEST_HAS_COMBINE

#if IUTEST_HAS_VARIADIC_COMBINE
/**
 * @brief	複合条件パラメータ化
*/
template<typename ...Generator>
detail::iuCartesianProductHolder<Generator...> Combine(const Generator&... generators)
{
	return detail::iuCartesianProductHolder<Generator...>(generators...);
}

#else

#define IIUT_DECL_COMBINE_(n)	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >				\
	inline IUTEST_PP_CAT(detail::iuCartesianProductHolder, n)< IUTEST_PP_ENUM_PARAMS(n, T) >	\
	Combine(IUTEST_PP_ENUM_BINARY_PARAMS(n, const T, &t)) {										\
		return IUTEST_PP_CAT(detail::iuCartesianProductHolder, n)								\
				< IUTEST_PP_ENUM_PARAMS(n, T) >(IUTEST_PP_ENUM_PARAMS(n, t));					\
	}

/**
 * @brief	複合条件パラメータ化
 * @note	9引数まで使用可能
*/
IIUT_DECL_COMBINE_(2)
IIUT_DECL_COMBINE_(3)
IIUT_DECL_COMBINE_(4)
IIUT_DECL_COMBINE_(5)
IIUT_DECL_COMBINE_(6)
IIUT_DECL_COMBINE_(7)
IIUT_DECL_COMBINE_(8)
IIUT_DECL_COMBINE_(9)

#undef IIUT_DECL_COMBINE_

#endif

#endif

#if IUTEST_HAS_PAIRWISE

#if IUTEST_HAS_VARIADIC_PAIRWISE

/**
 * @brief	複合条件パラメータ化(オールペア法)
*/
template<typename ...Generator>
detail::iuPairwiseHolder<Generator...> Pairwise(const Generator&... generators)
{
	return detail::iuPairwiseHolder<Generator...>(generators...);
}

#else

#define IIUT_DECL_PAIRWISE_(n)	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >			\
	inline IUTEST_PP_CAT(detail::iuPairwiseHolder, n)< IUTEST_PP_ENUM_PARAMS(n, T) >		\
	Pairwise(IUTEST_PP_ENUM_BINARY_PARAMS(n, const T, &t)) {								\
		return IUTEST_PP_CAT(detail::iuPairwiseHolder, n)									\
				< IUTEST_PP_ENUM_PARAMS(n, T) >(IUTEST_PP_ENUM_PARAMS(n, t));				\
	}

/**
 * @brief	複合条件パラメータ化(オールペア法)
 * @note	9引数まで使用可能
*/
IIUT_DECL_PAIRWISE_(2)
IIUT_DECL_PAIRWISE_(3)
IIUT_DECL_PAIRWISE_(4)
IIUT_DECL_PAIRWISE_(5)
IIUT_DECL_PAIRWISE_(6)
IIUT_DECL_PAIRWISE_(7)
IIUT_DECL_PAIRWISE_(8)
IIUT_DECL_PAIRWISE_(9)

#undef IIUT_DECL_PAIRWISE__

#endif

#endif

/**
 * @}
*/

}	// end of namespace iutest

#if IUTEST_HAS_ANY_PARAM_TEST
/**
 * @ingroup	VALUE_PARAMETERIZED_TEST
 * @brief	any param test fixture
*/
typedef ::iutest::TestWithAny iuTestWithAny;
#endif

#endif // IUTEST_HAS_PARAM_TEST

#endif // INCG_IRIS_IUTEST_PARAM_TESTS_HPP_3DBBF55E_A076_4207_B49E_34734EE333EE_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_typed_tests.hpp
 * @brief		iris unit test typed test
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_TYPED_TESTS_HPP_DA9562C6_8CAB_4242_9E9E_22FFB490DE30_
#define INCG_IRIS_IUTEST_TYPED_TESTS_HPP_DA9562C6_8CAB_4242_9E9E_22FFB490DE30_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_typed_util.hpp
 * @brief		iris unit test typed util
 *
 * @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_TYPED_UTIL_HPP_32A6F7CF_36C6_4EDE_AD19_04965FBFBB37_
#define INCG_IRIS_IUTEST_TYPED_UTIL_HPP_32A6F7CF_36C6_4EDE_AD19_04965FBFBB37_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_typelist.hpp
 * @brief		iris unit test type list
 *
 * @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_TYPELIST_HPP_0AC27A0F_3EFF_48AD_9075_E439B4190DA5_
#define INCG_IRIS_IUTEST_TYPELIST_HPP_0AC27A0F_3EFF_48AD_9075_E439B4190DA5_

namespace iutest {
namespace detail
{

//======================================================================
// define
#if !defined(IUTEST_NO_TEMPLATE_TEMPLATES)
#  define IUTEST_TEMPLATE_TPARAM1	template<typename T> class
#endif

//======================================================================
// struct
/**
 * @brief	TypeList
 * @{
*/

// TypeList から 型を取得
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;
};

// type list 終端
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 IIUT_DECL_TYPELIST_(n)	IIUT_DECL_TYPELIST_I(n, IUTEST_PP_DEC(n))
#define IIUT_DECL_TYPELIST_I(n, m)													\
	template<typename T0, IUTEST_PP_ENUM_SHIFTED_PARAMS(m, typename T)>				\
	struct IUTEST_PP_CAT(TypeList, n) { typedef T0 Head;							\
	typedef IUTEST_PP_CAT(TypeList, m)< IUTEST_PP_ENUM_SHIFTED_PARAMS(m, T) > Tail;	\
}

IIUT_DECL_TYPELIST_(2);
IIUT_DECL_TYPELIST_(3);
IIUT_DECL_TYPELIST_(4);
IIUT_DECL_TYPELIST_(5);
IIUT_DECL_TYPELIST_(6);
IIUT_DECL_TYPELIST_(7);
IIUT_DECL_TYPELIST_(8);
IIUT_DECL_TYPELIST_(9);
IIUT_DECL_TYPELIST_(10);
IIUT_DECL_TYPELIST_(11);
IIUT_DECL_TYPELIST_(12);
IIUT_DECL_TYPELIST_(13);
IIUT_DECL_TYPELIST_(14);
IIUT_DECL_TYPELIST_(15);
IIUT_DECL_TYPELIST_(16);
IIUT_DECL_TYPELIST_(17);
IIUT_DECL_TYPELIST_(18);
IIUT_DECL_TYPELIST_(19);
IIUT_DECL_TYPELIST_(20);
IIUT_DECL_TYPELIST_(21);
IIUT_DECL_TYPELIST_(22);
IIUT_DECL_TYPELIST_(23);
IIUT_DECL_TYPELIST_(24);
IIUT_DECL_TYPELIST_(25);
IIUT_DECL_TYPELIST_(26);
IIUT_DECL_TYPELIST_(27);
IIUT_DECL_TYPELIST_(28);
IIUT_DECL_TYPELIST_(29);
IIUT_DECL_TYPELIST_(30);
IIUT_DECL_TYPELIST_(31);
IIUT_DECL_TYPELIST_(32);
IIUT_DECL_TYPELIST_(33);
IIUT_DECL_TYPELIST_(34);
IIUT_DECL_TYPELIST_(35);
IIUT_DECL_TYPELIST_(36);
IIUT_DECL_TYPELIST_(37);
IIUT_DECL_TYPELIST_(38);
IIUT_DECL_TYPELIST_(39);
IIUT_DECL_TYPELIST_(40);
IIUT_DECL_TYPELIST_(41);
IIUT_DECL_TYPELIST_(42);
IIUT_DECL_TYPELIST_(43);
IIUT_DECL_TYPELIST_(44);
IIUT_DECL_TYPELIST_(45);
IIUT_DECL_TYPELIST_(46);
IIUT_DECL_TYPELIST_(47);
IIUT_DECL_TYPELIST_(48);
IIUT_DECL_TYPELIST_(49);
IIUT_DECL_TYPELIST_(50);

#undef IIUT_DECL_TYPELIST_

#endif

/**
 * @}
*/


#if !defined(IUTEST_NO_TEMPLATE_TEMPLATES)

/**
 * @brief	TemplateTypeListBind
*/
template<IUTEST_TEMPLATE_TPARAM1 U>
struct TemplateTypeSel
{
	template<typename T>
	struct bind
	{
		typedef U<T> type;
	};
};

/**
 * @brief	TemplateTypeList
 * @{
*/

// template type list 終端
struct TemplateTypeList0 {};

#if IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES

template<IUTEST_TEMPLATE_TPARAM1 T1, IUTEST_TEMPLATE_TPARAM1 ...Types>
struct VariadicTemplateTypeList
{
	typedef TemplateTypeSel<T1> Head;
	typedef VariadicTemplateTypeList<Types...> Tail;
};
template<IUTEST_TEMPLATE_TPARAM1 T1>
struct VariadicTemplateTypeList<T1>
{
	typedef TemplateTypeSel<T1> Head;
	typedef TemplateTypeList0 Tail;
};

#else

template<IUTEST_TEMPLATE_TPARAM1 T1>
struct TemplateTypeList1
{
	typedef TemplateTypeSel<T1> Head;
	typedef TemplateTypeList0 Tail;
};

#define IIUT_DECL_TEMPLATETYPELIST_(n)	IIUT_DECL_TEMPLATETYPELIST_I(n, IUTEST_PP_DEC(n))
#define IIUT_DECL_TEMPLATETYPELIST_I(n, m)																\
	template< IUTEST_TEMPLATE_TPARAM1 T0, IUTEST_PP_ENUM_SHIFTED_PARAMS(m, IUTEST_TEMPLATE_TPARAM1 T) >	\
	struct IUTEST_PP_CAT(TemplateTypeList, n) { typedef TemplateTypeSel<T0> Head;						\
	typedef IUTEST_PP_CAT(TemplateTypeList, m)< IUTEST_PP_ENUM_SHIFTED_PARAMS(m, T) > Tail;				\
}

IIUT_DECL_TEMPLATETYPELIST_(2);
IIUT_DECL_TEMPLATETYPELIST_(3);
IIUT_DECL_TEMPLATETYPELIST_(4);
IIUT_DECL_TEMPLATETYPELIST_(5);
IIUT_DECL_TEMPLATETYPELIST_(6);
IIUT_DECL_TEMPLATETYPELIST_(7);
IIUT_DECL_TEMPLATETYPELIST_(8);
IIUT_DECL_TEMPLATETYPELIST_(9);
IIUT_DECL_TEMPLATETYPELIST_(10);
IIUT_DECL_TEMPLATETYPELIST_(11);
IIUT_DECL_TEMPLATETYPELIST_(12);
IIUT_DECL_TEMPLATETYPELIST_(13);
IIUT_DECL_TEMPLATETYPELIST_(14);
IIUT_DECL_TEMPLATETYPELIST_(15);
IIUT_DECL_TEMPLATETYPELIST_(16);
IIUT_DECL_TEMPLATETYPELIST_(17);
IIUT_DECL_TEMPLATETYPELIST_(18);
IIUT_DECL_TEMPLATETYPELIST_(19);
IIUT_DECL_TEMPLATETYPELIST_(20);
IIUT_DECL_TEMPLATETYPELIST_(21);
IIUT_DECL_TEMPLATETYPELIST_(22);
IIUT_DECL_TEMPLATETYPELIST_(23);
IIUT_DECL_TEMPLATETYPELIST_(24);
IIUT_DECL_TEMPLATETYPELIST_(25);
IIUT_DECL_TEMPLATETYPELIST_(26);
IIUT_DECL_TEMPLATETYPELIST_(27);
IIUT_DECL_TEMPLATETYPELIST_(28);
IIUT_DECL_TEMPLATETYPELIST_(29);
IIUT_DECL_TEMPLATETYPELIST_(30);
IIUT_DECL_TEMPLATETYPELIST_(31);
IIUT_DECL_TEMPLATETYPELIST_(32);
IIUT_DECL_TEMPLATETYPELIST_(33);
IIUT_DECL_TEMPLATETYPELIST_(34);
IIUT_DECL_TEMPLATETYPELIST_(35);
IIUT_DECL_TEMPLATETYPELIST_(36);
IIUT_DECL_TEMPLATETYPELIST_(37);
IIUT_DECL_TEMPLATETYPELIST_(38);
IIUT_DECL_TEMPLATETYPELIST_(39);
IIUT_DECL_TEMPLATETYPELIST_(40);
IIUT_DECL_TEMPLATETYPELIST_(41);
IIUT_DECL_TEMPLATETYPELIST_(42);
IIUT_DECL_TEMPLATETYPELIST_(43);
IIUT_DECL_TEMPLATETYPELIST_(44);
IIUT_DECL_TEMPLATETYPELIST_(45);
IIUT_DECL_TEMPLATETYPELIST_(46);
IIUT_DECL_TEMPLATETYPELIST_(47);
IIUT_DECL_TEMPLATETYPELIST_(48);
IIUT_DECL_TEMPLATETYPELIST_(49);
IIUT_DECL_TEMPLATETYPELIST_(50);

#undef IIUT_DECL_TEMPLATETYPELIST_

#endif

/**
 * @}
*/

#endif

}	// end of namespace detail

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_TYPELIST_HPP_0AC27A0F_3EFF_48AD_9075_E439B4190DA5_

namespace iutest
{

//======================================================================
// struct
#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

/**
 * @ingroup	TYPED_TEST TYPE_PARAMETERIZED_TEST
 * @brief	Type List
 * @tparam	Args	= 型リスト
 * @{
*/
#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 IIUT_DECL_DEFAULT_ARG_(i, param)	IUTEST_PP_CAT(param,i)=detail::None

template< IUTEST_PP_ENUM(50, IIUT_DECL_DEFAULT_ARG_, typename T) >
struct Types
{
	typedef detail::TypeList50< IUTEST_PP_ENUM_PARAMS(50, T) > type;
	template<size_t N>struct get : public detail::typelist_get<type, N> {};
};

#undef IIUT_DECL_DEFAULT_ARG_

#define IIUT_DECL_SPEC_NONE_(i, param)	param
#define IIUT_DECL_TYPES_(n, m)								\
	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >		\
	struct Types< IUTEST_PP_ENUM_PARAMS(n, T)				\
		, IUTEST_PP_ENUM(m, IIUT_DECL_SPEC_NONE_, detail::None) > {	\
		typedef IUTEST_PP_CAT(detail::TypeList, n)<			\
			IUTEST_PP_ENUM_PARAMS(n, T) > type;				\
		template<size_t N>struct get : public detail::typelist_get<type, N> {};	\
	}

template<>
struct Types< IUTEST_PP_ENUM(50, IIUT_DECL_SPEC_NONE_, detail::None) >
{
	typedef detail::TypeList0 type;
};

IIUT_DECL_TYPES_( 1, 49);
IIUT_DECL_TYPES_( 2, 48);
IIUT_DECL_TYPES_( 3, 47);
IIUT_DECL_TYPES_( 4, 46);
IIUT_DECL_TYPES_( 5, 45);
IIUT_DECL_TYPES_( 6, 44);
IIUT_DECL_TYPES_( 7, 43);
IIUT_DECL_TYPES_( 8, 42);
IIUT_DECL_TYPES_( 9, 41);
IIUT_DECL_TYPES_(10, 40);
IIUT_DECL_TYPES_(11, 39);
IIUT_DECL_TYPES_(12, 38);
IIUT_DECL_TYPES_(13, 37);
IIUT_DECL_TYPES_(14, 36);
IIUT_DECL_TYPES_(15, 35);
IIUT_DECL_TYPES_(16, 34);
IIUT_DECL_TYPES_(17, 33);
IIUT_DECL_TYPES_(18, 32);
IIUT_DECL_TYPES_(19, 31);
IIUT_DECL_TYPES_(20, 30);
IIUT_DECL_TYPES_(21, 29);
IIUT_DECL_TYPES_(22, 28);
IIUT_DECL_TYPES_(23, 27);
IIUT_DECL_TYPES_(24, 26);
IIUT_DECL_TYPES_(25, 25);
IIUT_DECL_TYPES_(26, 24);
IIUT_DECL_TYPES_(27, 23);
IIUT_DECL_TYPES_(28, 22);
IIUT_DECL_TYPES_(29, 21);
IIUT_DECL_TYPES_(30, 20);
IIUT_DECL_TYPES_(31, 19);
IIUT_DECL_TYPES_(32, 18);
IIUT_DECL_TYPES_(33, 17);
IIUT_DECL_TYPES_(34, 16);
IIUT_DECL_TYPES_(35, 15);
IIUT_DECL_TYPES_(36, 14);
IIUT_DECL_TYPES_(37, 13);
IIUT_DECL_TYPES_(38, 12);
IIUT_DECL_TYPES_(39, 11);
IIUT_DECL_TYPES_(40, 10);
IIUT_DECL_TYPES_(41,  9);
IIUT_DECL_TYPES_(42,  8);
IIUT_DECL_TYPES_(43,  7);
IIUT_DECL_TYPES_(44,  6);
IIUT_DECL_TYPES_(45,  5);
IIUT_DECL_TYPES_(46,  4);
IIUT_DECL_TYPES_(47,  3);
IIUT_DECL_TYPES_(48,  2);
IIUT_DECL_TYPES_(49,  1);

#undef IIUT_DECL_SPEC_NONE_
#undef IIUT_DECL_TYPES_

#endif

/**
 * @}
*/

namespace detail
{

#if !defined(IUTEST_NO_TEMPLATE_TEMPLATES)

/**
 * @brief	Templates
 * @{
*/
#if IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES
template<IUTEST_TEMPLATE_TPARAM1 ...Types>
struct Templates
{
	typedef VariadicTemplateTypeList<Types...> type;
};

#else

#define IIUT_DECL_DEFAULT_ARG_(i, param)	IUTEST_PP_CAT(param,i)=detail::NoneT1

template< IUTEST_PP_ENUM(50, IIUT_DECL_DEFAULT_ARG_, IUTEST_TEMPLATE_TPARAM1 T) >
struct Templates
{
	typedef detail::TemplateTypeList50< IUTEST_PP_ENUM_PARAMS(50, T) > type;
};

#undef IIUT_DECL_DEFAULT_ARG_

#define IIUT_DECL_SPEC_NONE_(i, param)	param
#define IIUT_DECL_TEMPLATES_(n, m)										\
	template< IUTEST_PP_ENUM_PARAMS(n, IUTEST_TEMPLATE_TPARAM1 T) >		\
	struct Templates< IUTEST_PP_ENUM_PARAMS(n, T)						\
		, IUTEST_PP_ENUM(m, IIUT_DECL_SPEC_NONE_, detail::NoneT1) > {	\
		typedef IUTEST_PP_CAT(detail::TemplateTypeList, n)<				\
			IUTEST_PP_ENUM_PARAMS(n, T) > type;							\
	}

template<>
struct Templates< IUTEST_PP_ENUM(50, IIUT_DECL_SPEC_NONE_, detail::NoneT1) >
{
	typedef detail::TemplateTypeList0 type;
};

IIUT_DECL_TEMPLATES_( 1, 49);
IIUT_DECL_TEMPLATES_( 2, 48);
IIUT_DECL_TEMPLATES_( 3, 47);
IIUT_DECL_TEMPLATES_( 4, 46);
IIUT_DECL_TEMPLATES_( 5, 45);
IIUT_DECL_TEMPLATES_( 6, 44);
IIUT_DECL_TEMPLATES_( 7, 43);
IIUT_DECL_TEMPLATES_( 8, 42);
IIUT_DECL_TEMPLATES_( 9, 41);
IIUT_DECL_TEMPLATES_(10, 40);
IIUT_DECL_TEMPLATES_(11, 39);
IIUT_DECL_TEMPLATES_(12, 38);
IIUT_DECL_TEMPLATES_(13, 37);
IIUT_DECL_TEMPLATES_(14, 36);
IIUT_DECL_TEMPLATES_(15, 35);
IIUT_DECL_TEMPLATES_(16, 34);
IIUT_DECL_TEMPLATES_(17, 33);
IIUT_DECL_TEMPLATES_(18, 32);
IIUT_DECL_TEMPLATES_(19, 31);
IIUT_DECL_TEMPLATES_(20, 30);
IIUT_DECL_TEMPLATES_(21, 29);
IIUT_DECL_TEMPLATES_(22, 28);
IIUT_DECL_TEMPLATES_(23, 27);
IIUT_DECL_TEMPLATES_(24, 26);
IIUT_DECL_TEMPLATES_(25, 25);
IIUT_DECL_TEMPLATES_(26, 24);
IIUT_DECL_TEMPLATES_(27, 23);
IIUT_DECL_TEMPLATES_(28, 22);
IIUT_DECL_TEMPLATES_(29, 21);
IIUT_DECL_TEMPLATES_(30, 20);
IIUT_DECL_TEMPLATES_(31, 19);
IIUT_DECL_TEMPLATES_(32, 18);
IIUT_DECL_TEMPLATES_(33, 17);
IIUT_DECL_TEMPLATES_(34, 16);
IIUT_DECL_TEMPLATES_(35, 15);
IIUT_DECL_TEMPLATES_(36, 14);
IIUT_DECL_TEMPLATES_(37, 13);
IIUT_DECL_TEMPLATES_(38, 12);
IIUT_DECL_TEMPLATES_(39, 11);
IIUT_DECL_TEMPLATES_(40, 10);
IIUT_DECL_TEMPLATES_(41,  9);
IIUT_DECL_TEMPLATES_(42,  8);
IIUT_DECL_TEMPLATES_(43,  7);
IIUT_DECL_TEMPLATES_(44,  6);
IIUT_DECL_TEMPLATES_(45,  5);
IIUT_DECL_TEMPLATES_(46,  4);
IIUT_DECL_TEMPLATES_(47,  3);
IIUT_DECL_TEMPLATES_(48,  2);
IIUT_DECL_TEMPLATES_(49,  1);

#undef IIUT_DECL_SPEC_NONE_
#undef IIUT_DECL_TEMPLATES_

#endif

/**
 * @}
*/

#endif // #if !defined(IUTEST_NO_TEMPLATE_TEMPLATES)

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< IUTEST_PP_ENUM_PARAMS(50, typename T) >
struct TypeList< Types< IUTEST_PP_ENUM_PARAMS(50, T) > >
{
	typedef typename Types< IUTEST_PP_ENUM_PARAMS(50, T) >::type type;
};

#endif

}	// end of namespace detail

#endif // #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_TYPED_UTIL_HPP_32A6F7CF_36C6_4EDE_AD19_04965FBFBB37_

#if IUTEST_HAS_TYPED_TEST_P
#endif

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

#if IUTEST_HAS_TYPED_TEST
/**
 * @defgroup	TYPED_TEST	型付けテスト
*/

/**
 * @ingroup	TYPED_TEST
 * @def		IUTEST_TYPED_TEST_CASE(testcase_, types_)
 * @brief	型付けテストケースの登録
 * @param	testcase_	= テストケース名
 * @param	types_		= タイプリスト
*/
#if !defined(IUTEST_NO_VARIADIC_MACROS)
#  define IUTEST_TYPED_TEST_CASE(testcase_, ...)	IIUT_TYPED_TEST_CASE_(testcase_, __VA_ARGS__)
#else
#  define IUTEST_TYPED_TEST_CASE(testcase_, types_)	IIUT_TYPED_TEST_CASE_(testcase_, types_)
#endif

/**
 * @ingroup	TYPED_TEST
 * @def		IUTEST_TYPED_TEST(testcase_, testname_)
 * @brief	型付けテスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
*/
#define IUTEST_TYPED_TEST(testcase_, testname_)		IIUT_TYPED_TEST_(testcase_, testname_)

/**
 * @ingroup	TYPED_TEST
 * @def		IUTEST_T(testcase_, testname_)
 * @brief	型付けテスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
*/
#define IUTEST_T(testcase_, testname_)				IIUT_TYPED_TEST_(testcase_, testname_)


/**
 * @private
 * @{
*/
#define IUTEST_TYPED_TEST_PARAMS_(testcase_)		IIUT_TYPED_TEST_PARAMS_I(IIUT_TO_VARNAME_(testcase_))
#define IIUT_TYPED_TEST_PARAMS_I(testcase_)			IIUT_TYPED_TEST_PARAMS_I_(testcase_)
#define IIUT_TYPED_TEST_PARAMS_I_(testcase_)		iutest_types_params_##testcase_

#if !defined(IUTEST_NO_VARIADIC_MACROS)
#  define IIUT_TYPED_TEST_CASE_(testcase_, ...)		\
	typedef ::iutest::detail::TypeList< __VA_ARGS__ >::type	IUTEST_TYPED_TEST_PARAMS_(testcase_)
#else
#  define IIUT_TYPED_TEST_CASE_(testcase_, types_)		\
	typedef ::iutest::detail::TypeList< types_ >::type	IUTEST_TYPED_TEST_PARAMS_(testcase_)
#endif

#define IIUT_TYPED_TEST_(testcase_, testname_)										\
	template<typename iutest_TypeParam>												\
	class IUTEST_TEST_CLASS_NAME_(testcase_, testname_)								\
	: public IIUT_TO_VARNAME_(testcase_)<iutest_TypeParam> {						\
		typedef IIUT_TO_VARNAME_(testcase_)<iutest_TypeParam> TestFixture;			\
		typedef iutest_TypeParam TypeParam;											\
		protected: virtual void Body(void);											\
	};																				\
	::iutest::detail::TypeParamTestInstance< IUTEST_TEST_CLASS_NAME_(testcase_, testname_)			\
		, IUTEST_TYPED_TEST_PARAMS_(testcase_) > IUTEST_TEST_INSTANCE_NAME_(testcase_, testname_)(	\
		IUTEST_CONCAT_PACKAGE_(IIUT_TO_NAME_(testcase_)), IIUT_TO_NAME_STR_(testname_));		\
	template<typename iutest_TypeParam>												\
	void IUTEST_TEST_CLASS_NAME_(testcase_, testname_)<iutest_TypeParam>::Body(void)

#define IIUT_TYPED_TEST_IGNORE_(testcase_, testname_)								\
	template<typename iutest_TypeParam>												\
	class IUTEST_TEST_CLASS_NAME_(testcase_, testname_)								\
	: public IIUT_TO_VARNAME_(testcase_)<iutest_TypeParam> {						\
		typedef IIUT_TO_VARNAME_(testcase_)<iutest_TypeParam> TestFixture;			\
		typedef iutest_TypeParam TypeParam;											\
		protected: virtual void Body(void) { IUTEST_SKIP() << "ignored test..."; }	\
		template<typename T>void Body(void);										\
	};																				\
	::iutest::detail::TypeParamTestInstance< IUTEST_TEST_CLASS_NAME_(testcase_, testname_)			\
		, IUTEST_TYPED_TEST_PARAMS_(testcase_) > IUTEST_TEST_INSTANCE_NAME_(testcase_, testname_)(	\
		IUTEST_CONCAT_PACKAGE_(IIUT_TO_NAME_(testcase_)), IIUT_TO_NAME_STR_(testname_));		\
	template<typename iutest_TypeParam>												\
	template<typename T>void IUTEST_TEST_CLASS_NAME_(testcase_, testname_)<iutest_TypeParam>::Body(void)

/**
 * @}
*/

#endif

#if IUTEST_HAS_TYPED_TEST_P
/**
 * @defgroup	TYPE_PARAMETERIZED_TEST	型のパラメータ化テスト
*/

/**
 * @ingroup	TYPE_PARAMETERIZED_TEST
 * @def		IUTEST_TYPED_TEST_CASE_P(testcase_)
 * @brief	型パラメータテストケースの登録
 * @param	testcase_	= テストケース名
*/
#define IUTEST_TYPED_TEST_CASE_P(testcase_)				IIUT_TYPED_TEST_CASE_P_(testcase_)

/**
 * @ingroup	TYPE_PARAMETERIZED_TEST
 * @def		IUTEST_TYPED_TEST_P(testcase_, testname_)
 * @brief	型パラメータテスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
*/
#define IUTEST_TYPED_TEST_P(testcase_, testname_)		IIUT_TYPED_TEST_P_(testcase_, testname_)

/**
 * @ingroup	TYPE_PARAMETERIZED_TEST
 * @def		IUTEST_TP(testcase_, testname_)
 * @brief	型パラメータテスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
*/
#define IUTEST_TP(testcase_, testname_)					IIUT_TYPED_TEST_P_(testcase_, testname_)

/**
 * @ingroup	TYPE_PARAMETERIZED_TEST
 * @def		IUTEST_REGISTER_TYPED_TEST_CASE_P(testcase_, ...)
 * @brief	型パラメータテスト関数登録マクロ
 * @param	testcase_	= テストケース名
*/
#define IUTEST_REGISTER_TYPED_TEST_CASE_P(testcase_, ...)	IIUT_REGISTER_TYPED_TEST_CASE_P_(testcase_, __VA_ARGS__)

/**
 * @ingroup	TYPE_PARAMETERIZED_TEST
 * @def		IUTEST_INSTANTIATE_TYPED_TEST_CASE_P(prefix_, testcase_, types_)
 * @brief	型パラメータテスト登録マクロ
 * @param	prefix_		= インスタンス名
 * @param	testcase_	= テストケース名
 * @param	...			= タイプリスト
*/
#define IUTEST_INSTANTIATE_TYPED_TEST_CASE_P(prefix_, testcase_, ...)	IIUT_INSTANTIATE_TYPED_TEST_CASE_P_(prefix_, testcase_, __VA_ARGS__)


/**
 * @private
 * @{
*/

#define IUTEST_TYPED_TEST_CASE_PSTATE_NAME_(testcase_)	s_iutest_typed_test_case_p_state_##testcase_##_
#define IUTEST_TYPED_TEST_P_NAMESPACE_(testcase_)		iutest_typed_test_case_p_name_##testcase_##_

#define IIUT_TYPED_TEST_CASE_P_(testcase_)		\
	static ::iutest::detail::TypedTestCasePState	IUTEST_TYPED_TEST_CASE_PSTATE_NAME_(testcase_)

#define IIUT_TYPED_TEST_P_(testcase_, testname_)				\
	namespace IUTEST_TYPED_TEST_P_NAMESPACE_(testcase_) {		\
	template<typename iutest_TypeParam>							\
	class testname_ : public testcase_<iutest_TypeParam> {		\
		typedef testcase_<iutest_TypeParam> TestFixture;		\
		typedef iutest_TypeParam TypeParam;						\
		protected: virtual void Body(void);						\
	};															\
	static const int s_iutest_##testname_##_defined_dummy_ IUTEST_ATTRIBUTE_UNUSED_ =	\
	IUTEST_TYPED_TEST_CASE_PSTATE_NAME_(testcase_).AddTestName(__FILE__, __LINE__, #testcase_, #testname_);		\
	}															\
	template<typename iutest_TypeParam>							\
	void IUTEST_TYPED_TEST_P_NAMESPACE_(testcase_)::testname_<iutest_TypeParam>::Body(void)

#define IIUT_TYPED_TEST_P_IGNORE_(testcase_, testname_)			\
	namespace IUTEST_TYPED_TEST_P_NAMESPACE_(testcase_) {		\
	template<typename iutest_TypeParam>							\
	class testname_ : public testcase_<iutest_TypeParam> {		\
		typedef testcase_<iutest_TypeParam> TestFixture;		\
		typedef iutest_TypeParam TypeParam;						\
		protected: virtual void Body(void) { IUTEST_SKIP() << "ignored test..."; }		\
		template<typename T>void Body(void);					\
	};															\
	static const int s_iutest_##testname_##_defined_dummy_ IUTEST_ATTRIBUTE_UNUSED_ =	\
	IUTEST_TYPED_TEST_CASE_PSTATE_NAME_(testcase_).AddTestName(__FILE__, __LINE__, #testcase_, #testname_);		\
	}															\
	template<typename iutest_TypeParam>template<typename T>		\
	void IUTEST_TYPED_TEST_P_NAMESPACE_(testcase_)::testname_<iutest_TypeParam>::Body(void)

#define IIUT_REGISTER_TYPED_TEST_CASE_P_(testcase_, ...)								\
	namespace IUTEST_TYPED_TEST_P_NAMESPACE_(testcase_) {								\
		typedef ::iutest::detail::Templates< __VA_ARGS__ >::type iutest_AllTests_;		\
	}																					\
	static const bool s_iutest_##testcase_##_register_dummy_ IUTEST_ATTRIBUTE_UNUSED_ =	\
	IUTEST_TYPED_TEST_CASE_PSTATE_NAME_(testcase_).VerifyTestNames(__FILE__, __LINE__, #__VA_ARGS__)

#define IIUT_INSTANTIATE_TYPED_TEST_CASE_P_(prefix_, testcase_, ...)		\
	const bool iutest_##prefix_##_##testcase_ IUTEST_ATTRIBUTE_UNUSED_ =	\
		::iutest::detail::TypeParameterizedTestCase< testcase_				\
		, IUTEST_TYPED_TEST_P_NAMESPACE_(testcase_)::iutest_AllTests_		\
		, ::iutest::detail::TypeList< __VA_ARGS__ >::type >::Register(		\
			#prefix_, IIUT_TO_NAME_STR_(testcase_), IUTEST_GET_PACKAGENAME_()	\
		, IUTEST_TYPED_TEST_CASE_PSTATE_NAME_(testcase_).names())

/**
 * @}
*/

#endif

namespace iutest
{

//======================================================================
// class
namespace detail
{

#if IUTEST_HAS_TYPED_TEST
/**
 * @private
 * @internal
 * @brief	Typeパラメータ単体テストインスタンス
 * @tparam	Tester		= テストクラス
 * @tparam	TypeParams	= 型
*/
template<template <typename T> class Tester, typename TypeParams>
class TypeParamTestInstance
{
	/**
	 * @brief	各テストのインスタンス
	*/
	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, int 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, int index)
		{
#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
			return UnitTest::instance().AddTestCase<_MyTestCase>(
#else
			return UnitTest::instance().AddTestCase(
#endif
#if IUTEST_TYPED_TEST_APPEND_TYPENAME
				detail::MakeIndexTypedTestName<TypeParam>(testcase, index).c_str()
#else
				detail::MakeIndexTestName(testcase, index).c_str()
#endif
				, internal::GetTypeId<detail::None>()	// TypeId を統一するためダミー引数を渡す
				, TestBody::SetUpTestCase
				, TestBody::TearDownTestCase
#if defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
				, detail::explicit_type<_MyTestCase>()
#endif
				);
		}

	public:
		// テストの登録
		void AddTest(void)
		{
			// 順番通りになるように前から登録
			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* , int ) {}
		void AddTest(void) {}
	};

public:
	// コンストラクタ
	TypeParamTestInstance(const char* testcase, const char* name)
		: m_tests(testcase, name, 0)
	{
		m_tests.AddTest();
	}

private:
	EachTest<TypeParams, void> m_tests;

	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TypeParamTestInstance);
};

#endif

#if IUTEST_HAS_TYPED_TEST_P

/**
 * @private
 * @internal
 * @brief	Typed TestCase 設定保持
*/
class TypedTestCasePState
{
#if IUTEST_TYPED_TEST_P_STRICT
	typedef ::std::set<const char*> nameset_t;
#endif

public:
	TypedTestCasePState(void) : m_names(NULL) {}
public:
	const char* names(void) const { return m_names; }

public:
	bool AddTestName(const char* file, int line, const char* testcase_name, const char* test_name)
	{
		if( m_names != NULL )
		{
			IUTEST_LOG_(WARNING) << detail::FormatCompilerIndependentFileLocation(file, line)
				<< ": Test " << test_name << " must be defined before IUTEST_REGISTER_TYPED_TEST_CASE_P("
				<< testcase_name << ", ...).\n";
		}
#if IUTEST_TYPED_TEST_P_STRICT
		m_list.insert(test_name);
#endif
		return true;
	}
	bool VerifyTestNames(const char* file, int line, const char* test_names)
	{
		m_names = test_names;
		IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
#if IUTEST_TYPED_TEST_P_STRICT
		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 != NULL )
			{
				const size_t len = strlen(test_name);
				if( p[len] == '\0' || p[len] == ',' || detail::IsSpace(p[len]) )
				{
					continue;
				}
			}
			IUTEST_LOG_(WARNING) << detail::FormatCompilerIndependentFileLocation(file, line)
				<< ": Test " << test_name << " has not been registered.\n";
			ret = false;
		}
		return ret;
#else
		IUTEST_UNUSED_VAR(file);
		IUTEST_UNUSED_VAR(line);
		return true;
#endif
		IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
	}

private:
	const char* m_names;

#if IUTEST_TYPED_TEST_P_STRICT
	nameset_t m_list;
#endif

	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TypedTestCasePState);
};

/**
 * @private
 * @brief	型パラメータテストのインスタンス化クラス
*/
template<IUTEST_TEMPLATE_TPARAM1 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 char* 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_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
			const char* str = detail::SkipSpace(test_names);
			const char* comma = strchr(str, ',');
			::std::string test_name;
			if( comma == NULL )
			{
				test_name = str;
			}
			else
			{
				test_name.append(str, comma - str);
				++comma;
			}
			StripTrailingSpace(test_name);
			_Myt* test = new EachTest(testcase, test_name.c_str());
			// new オブジェクトを管理してもらう
			detail::iuPool::GetInstance().push(test);

			EachTest<TypeParam, typename TestsList::Tail>::Register(testcase, detail::SkipSpace(comma));
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
		}
	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:
	/**
	 * @brief	テストの登録
	*/
	static bool Register(const char* prefix, const char* testcase_name, const ::std::string& package_name, const char* names, int index=0)
	{
		typedef typename Types::Head	TypeParam;
		typedef typename Tests::Head	Head;
		typedef Fixture<Head>			FixtureClass;
		typedef TypedTestCase<TypeParam>	_MyTestCase;
		TestCase* testcase = 
#if !defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
			UnitTest::instance().AddTestCase<_MyTestCase>(
#else
			UnitTest::instance().AddTestCase(
#endif
#if IUTEST_TYPED_TEST_APPEND_TYPENAME
			(package_name + detail::MakePrefixedIndexTypedTestName<TypeParam>(prefix, testcase_name, index)).c_str()
#else
			(package_name + detail::MakePrefixedIndexTestName(prefix, testcase_name, index)).c_str()
#endif
			, internal::GetTypeId<FixtureClass>()
			, FixtureClass::SetUpTestCase, FixtureClass::TearDownTestCase
#if defined(IUTEST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS)
			, detail::explicit_type<_MyTestCase>()
#endif
			);

		EachTest<TypeParam, Tests>::Register(testcase, names);

		return TypeParameterizedTestCase<Fixture, Tests, typename Types::Tail>::Register(prefix, testcase_name, package_name, names, index + 1);
	}
};

/**
 * @private
 * @brief	型パラメータテストのインスタンス化クラス
 *			終端特殊化
*/
template<IUTEST_TEMPLATE_TPARAM1 Fixture, typename Tests>
class TypeParameterizedTestCase<Fixture, Tests, detail::TypeList0>
{
public:
	static bool Register(const char* , const char* , const ::std::string& , const char* , int index=0)
	{
		IUTEST_UNUSED_VAR(index);
		return true;
	}
};

#endif

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_TYPED_TESTS_HPP_DA9562C6_8CAB_4242_9E9E_22FFB490DE30_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_prod.hpp
 * @brief		iris unit test production code 対応用 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PROD_HPP_7A316C18_042D_4E48_BC31_E6AE8B6C2E28_
#define INCG_IRIS_IUTEST_PROD_HPP_7A316C18_042D_4E48_BC31_E6AE8B6C2E28_

//======================================================================
// define
/**
 * @brief	テストから見えるように fried 登録
*/
#define IUTEST_FRIEND_TEST(test_case_name, test_name)	\
	friend class IUTEST_TEST_CLASS_NAME_(test_case_name, test_name)

#if IUTEST_HAS_TYPED_TEST

#if !defined(_MSC_VER) || _MSC_VER > 1200

/**
 * @brief	テストから見えるように fried 登録(IUTEST_TYPED_TEST用)
*/
#define IUTEST_FRIEND_TYPED_TEST(test_case_name, test_name)	\
	template<typename T>IUTEST_FRIEND_TEST(test_case_name, test_name)

#endif

#endif

/**
 * @brief	private メンバーへのアクセス権を作成
 * @param	member_type	= 型
 * @param	class_name	= クラス
 * @param	member_name	= メンバー名
*/
#define IUTEST_MAKE_PEEP(member_type, class_name, member_name)		\
	IUTEST_MAKE_PEEP_TAG_(member_type, class_name, member_name)

/**
 * @brief	private	メンバーへのアクセス
 * @param	v			= オブジェクトインスタンス
 * @param	class_name	= クラス名
 * @param	member_name	= メンバー名
*/
#define IUTEST_PEEP_GET(v, class_name, member_name)		(v.*::iutest::detail::peep_tag< IUTEST_PEEP_TAG_NAME_(class_name, member_name)<class_name> >::value)

/**
 * @brief	static private	メンバーへのアクセス
 * @param	class_name	= クラス名
 * @param	member_name	= メンバー名
*/
#define IUTEST_PEEP_STATIC_GET(class_name, member_name)	(*::iutest::detail::peep_tag< IUTEST_PEEP_TAG_NAME_(class_name, member_name)<class_name> >::value)

#if IUTEST_HAS_PEEP_CLASS

/**
 * @brief	private メンバーへのアクセスクラス宣言
 * @param	class_name	= クラス名
 * @param	member_name	= メンバー名
*/
#define IUTEST_PEEP(class_name, member_name)	::iutest::Peep< class_name, IUTEST_PEEP_TAG_NAME_(class_name, member_name)<class_name> >::type

#endif

/**
 * @private
 * @{
*/
#define IUTEST_MAKE_PEEP_TAG_(member_type, class_name, member_name)															\
	template<typename T>struct IUTEST_PEEP_TAG_NAME_(class_name, member_name);												\
	template<>struct IUTEST_PEEP_TAG_NAME_(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 IUTEST_PEEP_SETTER_NAME_(class_name, member_name) {		\
	IUTEST_PEEP_SETTER_NAME_(class_name, member_name)(void) { ::iutest::detail::peep_tag<Tag>::value = X; }					\
	static IUTEST_PEEP_SETTER_NAME_(class_name, member_name) instance;														\
	};																														\
	template<typename T, typename Tag, typename Tag::type X>IUTEST_PEEP_SETTER_NAME_(class_name, member_name)<T, Tag, X>	\
	IUTEST_PEEP_SETTER_NAME_(class_name, member_name)<T, Tag, X>::instance;													\
	template struct IUTEST_PEEP_SETTER_NAME_(class_name, member_name)<class_name											\
		, IUTEST_PEEP_TAG_NAME_(class_name, member_name)<class_name>, &class_name::member_name>

#define IUTEST_PEEP_TAG_NAME_(class_name, member_name)			iu_peep_tag_##member_name
#define IUTEST_PEEP_SETTER_NAME_(class_name, member_name)		IUTEST_PP_CAT(IUTEST_PP_CAT(iu_peep_set_, member_name), __LINE__)

/**
 * @}
*/

namespace iutest {

//======================================================================
// struct
namespace detail
{

/**
 * @brief	private メンバー保持構造体
*/
template<typename Tag>
struct peep_tag
{
	static typename Tag::type value;
};
template<typename Tag>
typename Tag::type peep_tag<Tag>::value;

}	// end of namespace detail

#if IUTEST_HAS_PEEP_CLASS

/**
 * @brief	private	メンバーアクセスオブジェクト
*/
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 PEEP_DECL_MEMBER_FUNC_(n)	\
	template<IUTEST_PP_ENUM_PARAMS(n, typename T)>return_type operator () (		\
		IUTEST_PP_ENUM_BINARY_PARAMS(n, T, t)) {				\
		return ((*m_ptr).*detail::peep_tag<peep_tag>::value)(IUTEST_PP_ENUM_PARAMS(n, t)); }

		return_type operator () (void) { return ((*m_ptr).*detail::peep_tag<peep_tag>::value)(); }

		PEEP_DECL_MEMBER_FUNC_(1)
		PEEP_DECL_MEMBER_FUNC_(2)
		PEEP_DECL_MEMBER_FUNC_(3)
		PEEP_DECL_MEMBER_FUNC_(4)
		PEEP_DECL_MEMBER_FUNC_(5)
		PEEP_DECL_MEMBER_FUNC_(6)
		PEEP_DECL_MEMBER_FUNC_(7)
		PEEP_DECL_MEMBER_FUNC_(8)
		PEEP_DECL_MEMBER_FUNC_(9)
		PEEP_DECL_MEMBER_FUNC_(10)
		PEEP_DECL_MEMBER_FUNC_(11)
		PEEP_DECL_MEMBER_FUNC_(12)
		PEEP_DECL_MEMBER_FUNC_(13)
		PEEP_DECL_MEMBER_FUNC_(14)
		PEEP_DECL_MEMBER_FUNC_(15)
		PEEP_DECL_MEMBER_FUNC_(16)
		PEEP_DECL_MEMBER_FUNC_(17)
		PEEP_DECL_MEMBER_FUNC_(18)
		PEEP_DECL_MEMBER_FUNC_(19)
		PEEP_DECL_MEMBER_FUNC_(20)

#undef IUTEST_DECL_PEEP_MEMBER_FUNC_
#endif
	};
	template<typename U, typename Type, bool is_const>
	class peep_member_object_impl
	{
		typedef peep_member_object_impl<U, Type, false> _Myt;
		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 _Myt&);
	public:
		operator value_type (void) const { return (*m_ptr).*detail::peep_tag<peep_tag>::value; }
		_Myt& operator = (const value_type& value);
	};
	template<typename U, typename Type>
	class peep_member_object_impl<U, Type, false>
	{
		typedef peep_member_object_impl<U, Type, false> _Myt;
		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 _Myt&);
	public:
		operator value_type (void) const { return (*m_ptr).*detail::peep_tag<peep_tag>::value; }
		operator value_type& (void) { return (*m_ptr).*detail::peep_tag<peep_tag>::value; }
		_Myt& 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 peep_static_impl<U, Type, Func> _Myt;
		typedef typename type_traits::remove_pointer<Type>::type value_type;
	public:
		peep_static_impl(void) {}
		peep_static_impl(const value_type& value) { *detail::peep_tag<peep_tag>::value = value; }
		peep_static_impl(const _Myt&) {}
	public:
		operator value_type (void) const { return *detail::peep_tag<peep_tag>::value; }
		operator value_type& (void) { return *detail::peep_tag<peep_tag>::value; }
		_Myt& 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 (void) { 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;	//!< private メンバーアクセスオブジェクト型
};

#endif

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_PROD_HPP_7A316C18_042D_4E48_BC31_E6AE8B6C2E28_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_expression_assertion.hpp
 * @brief		iris unit test 式アサーション 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2014-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_EXPRESSION_ASSERTION_HPP_B9783316_33CF_4CA7_81D0_0BF44B048A4A_
#define INCG_IRIS_IUTEST_EXPRESSION_ASSERTION_HPP_B9783316_33CF_4CA7_81D0_0BF44B048A4A_

//======================================================================
// define
/**
 * @brief	式展開用 operand マクロ
 * @note	IUTEST_ASSERT(f() != 42 IUTEST_OPERAND(||) f() == 32 )
*/
#define IUTEST_OPERAND(op)		op IIUT_EXPRESSION_DECOMPOSE()

/**
 * @brief	式展開用マクロ
 * @note	IUTEST_ASSERT_TRUE(IUTEST_EXPRESSION(f() != 42) || IUTEST_EXPRESSION(f() == 10))
*/
#define IUTEST_EXPRESSION(expr)	(IIUT_EXPRESSION_DECOMPOSE() expr).GetResult()


/**
 * @private
 * @{
*/

#if IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE
#  define IIUT_EXPRESSION_DECOMPOSE()	::iutest::detail::ExpressionDecomposer()->*
#else
#  define IIUT_EXPRESSION_DECOMPOSE()	::iutest::detail::ExpressionDecomposer()>>
#endif

#define IUTEST_TEST_EXPRESSION_(expr, expected, on_failure)	\
	IUTEST_TEST_TRUE( ( IIUT_EXPRESSION_DECOMPOSE() expr ).GetResult(expected), #expr, on_failure )

#define IIUT_DECL_EXPRESSION_RESULT_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 IIUT_DECL_EXPRESSION_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_ARITHMETIC_EXPRESSION_DECOMPOSE || IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE

#if IUTEST_HAS_DECLTYPE

#define IIUT_DECL_EXPRESSION_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 IIUT_DECL_EXPRESSION_OP_LHS(op)	\
	template<typename RHS>ExpressionLHS<RHS> operator op (const RHS& rhs) const {	\
	return OperandResult(m_lhs op rhs) << " " #op " " << rhs;	\
	}

#endif

#endif

/**
 * @}
*/

namespace iutest {
namespace detail
{

//======================================================================
// class

/**
 * @brief	expression result
*/
class ExpressionResult
{
public:
	ExpressionResult(const AssertionResult& ar)
		: m_result(ar) {}

public:
	IIUT_DECL_EXPRESSION_RESULT_OP(||)
	IIUT_DECL_EXPRESSION_RESULT_OP(&&)

public:
	AssertionResult GetResult(bool expected) const 
	{
		return AssertionResult(result() == expected) << "expansion: " << m_result.message();
	}
	AssertionResult GetResult(void) const
	{
		return AssertionResult(result()) << m_result.message();
	}
private:
	bool result(void) const { return m_result.passed(); }
	const char* message(void) const { return m_result.message(); }
private:
	AssertionResult m_result;
};

namespace expression_op_helper
{
	template<typename T>
	T operand_result(const T&);
}

/**
 * @brief	expression lhs
 * @tparam	T=type
*/
template<typename T>
class ExpressionLHS
{
	typedef ExpressionLHS<T> _Myt;
public:
#if IUTEST_HAS_RVALUE_REFS
	ExpressionLHS(T&& lhs) : m_lhs( ::std::forward<T>(lhs) )
	{
		AppendMessage(m_lhs);
	}
#else
	ExpressionLHS(T lhs) : m_lhs(lhs)
	{
		AppendMessage(lhs);
	}
#endif
	ExpressionLHS(T lhs, const ::std::string& msg) : m_lhs(lhs), m_message(msg) {}

public:
	IIUT_DECL_EXPRESSION_OP(==)
	IIUT_DECL_EXPRESSION_OP(!=)
	IIUT_DECL_EXPRESSION_OP(<)
	IIUT_DECL_EXPRESSION_OP(<=)
	IIUT_DECL_EXPRESSION_OP(>)
	IIUT_DECL_EXPRESSION_OP(>=)
	IIUT_DECL_EXPRESSION_OP(&&)
	IIUT_DECL_EXPRESSION_OP(||)

#if IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE
	IIUT_DECL_EXPRESSION_OP_LHS(+)
	IIUT_DECL_EXPRESSION_OP_LHS(-)
	IIUT_DECL_EXPRESSION_OP_LHS(*)
	IIUT_DECL_EXPRESSION_OP_LHS(/)
	IIUT_DECL_EXPRESSION_OP_LHS(%)
#endif

#if IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE
	IIUT_DECL_EXPRESSION_OP_LHS(&)
	IIUT_DECL_EXPRESSION_OP_LHS(|)
	IIUT_DECL_EXPRESSION_OP_LHS(^)
	IIUT_DECL_EXPRESSION_OP_LHS(<<)
	IIUT_DECL_EXPRESSION_OP_LHS(>>)
#endif

private:
	template<typename U>
	ExpressionLHS<U> OperandResult(const U& lhs) const
	{
		return ExpressionLHS<U>(lhs, m_message);
	}

public:
	/**
	 * @brief	メッセージ追加
	*/
	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(void) 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:
	IUTEST_PP_DISALLOW_ASSIGN(ExpressionLHS);
private:
	T m_lhs;
	::std::string m_message;
};

#undef IIUT_DECL_EXPRESSION_RESULT_OP
#undef IIUT_DECL_EXPRESSION_OP
#ifdef IIUT_DECL_EXPRESSION_OP_LHS
#  undef IIUT_DECL_EXPRESSION_OP_LHS
#endif

/**
 * @brief	expression decomposer
*/
class ExpressionDecomposer
{
public:
#if IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE
#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
#else
	template<typename T>
	ExpressionLHS<const T&> operator >>(const T& expr)
	{
		return ExpressionLHS<const T&>(expr);
	}
#endif
};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_EXPRESSION_ASSERTION_HPP_B9783316_33CF_4CA7_81D0_0BF44B048A4A_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_matcher.hpp
 * @brief		iris unit test matcher 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2014-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_MATCHER_HPP_23746E00_1A4B_4778_91AD_45C6DEFEEFA7_
#define INCG_IRIS_IUTEST_MATCHER_HPP_23746E00_1A4B_4778_91AD_45C6DEFEEFA7_

#if IUTEST_HAS_MATCHERS

/**
 * @defgroup	MATCHERS 	MATCHERS
 * @brief		Matchers
*/

//======================================================================
// define
/**
 * @private
 * @{
*/
#define IUTEST_TEST_THAT(actual, matcher, on_failure)					\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_										\
	if( ::iutest::AssertionResult iutest_ar = matcher(actual) ) {		\
	} else																\
		on_failure(::iutest::detail::MatcherAssertionFailureMessage(	\
			::iutest::PrintToString(actual).c_str(), #matcher, iutest_ar))

/**
 * @}
*/

namespace iutest {
namespace detail
{

//======================================================================
// function
/**
 * @brief	Matcher Assertion Failure Message
*/
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();
}
	
//======================================================================
// class

/**
 * @brief	matcher interface
*/
class IMatcher
{
public:
	template<typename T>
	struct is_matcher : public iutest_type_traits::is_base_of<IMatcher, T> {};
public:
	virtual ~IMatcher(void) {}
	virtual ::std::string WhichIs(void) const = 0;
};

inline iu_ostream& operator << (iu_ostream& os, const IMatcher& msg)
{
	return os << msg.WhichIs();
}

/**
 * @private
 * @{
 */

#define DECL_COMPARE_MATCHER(name, op)	\
	template<typename T>class IUTEST_PP_CAT(name, Matcher): public IMatcher{\
	public:	IUTEST_PP_CAT(name, Matcher)(const T& v) : m_expected(v) {}		\
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE {					\
		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: IUTEST_PP_DISALLOW_ASSIGN(IUTEST_PP_CAT(name, Matcher));		\
	const T& m_expected;													\
	}

#define DECL_COMPARE_MATCHER2(name, op)	\
	class IUTEST_PP_CAT(Twofold, IUTEST_PP_CAT(name, Matcher)): public IMatcher{		\
	public:	IUTEST_PP_CAT(Twofold, IUTEST_PP_CAT(name, Matcher))() {}					\
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE { 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;	\
	} private:																			\
		IUTEST_PP_DISALLOW_ASSIGN(IUTEST_PP_CAT(Twofold, IUTEST_PP_CAT(name, Matcher)));\
	}


IUTEST_PARGMA_WARN_PUSH()
IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()

DECL_COMPARE_MATCHER(Ne, !=);
DECL_COMPARE_MATCHER(Le, <=);
DECL_COMPARE_MATCHER(Lt, < );
DECL_COMPARE_MATCHER(Ge, >=);
DECL_COMPARE_MATCHER(Gt, > );

DECL_COMPARE_MATCHER2(Eq, ==);
DECL_COMPARE_MATCHER2(Ne, !=);
DECL_COMPARE_MATCHER2(Le, <=);
DECL_COMPARE_MATCHER2(Lt, < );
DECL_COMPARE_MATCHER2(Ge, >=);
DECL_COMPARE_MATCHER2(Gt, > );

IUTEST_PARGMA_WARN_POP()

#undef DECL_COMPARE_MATCHER
#undef DECL_COMPARE_MATCHER2

#define DECL_STR_COMPARE_MATCHER(name)	\
	template<typename T>class IUTEST_PP_CAT(name, Matcher): public IMatcher {	\
	public: IUTEST_PP_CAT(name, Matcher)(const T& value) : m_expected(value) {}	\
	template<typename U>AssertionResult operator ()(const U& actual) const {	\
		if( internal::IUTEST_PP_CAT(name, Helper)::Compare(						\
			actual, m_expected) ) {	return AssertionSuccess(); }				\
		return AssertionFailure() << WhichIs();									\
	}																			\
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE {						\
		iu_global_format_stringstream strm; strm << #name ": " << m_expected;	\
		return strm.str();														\
	}																			\
	private: IUTEST_PP_DISALLOW_ASSIGN(IUTEST_PP_CAT(name, Matcher));			\
	const T& m_expected;														\
	}

DECL_STR_COMPARE_MATCHER(StrEq);
DECL_STR_COMPARE_MATCHER(StrNe);
DECL_STR_COMPARE_MATCHER(StrCaseEq);
DECL_STR_COMPARE_MATCHER(StrCaseNe);

#undef DECL_COMPARE_MATCHER

/**
 * @}
*/

/**
 * @brief	IsNull matcher
*/
class IsNullMatcher : public IMatcher
{
public:
	IsNullMatcher() {}
public:
	template<typename U>
	AssertionResult operator ()(const U* actual) const
	{
		if( actual == NULL ) return AssertionSuccess();
		return AssertionFailure() << WhichIs();
	}
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return "Is Null";
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(IsNullMatcher);
};

/**
 * @brief	NotNull matcher
*/
class NotNullMatcher : public IMatcher
{
public:
	NotNullMatcher() {}
public:
	template<typename U>
	AssertionResult operator ()(const U* actual) const
	{
		if( actual != NULL ) return AssertionSuccess();
		return AssertionFailure() << WhichIs();
	}
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return "Not Null";
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(NotNullMatcher);
};

/**
 * @brief	Floating point Eq matcher
*/
template<typename T>
class FloatingPointEqMatcher : public IMatcher
{
public:
	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(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "Eq: " << PrintToString(m_expected);
		return strm.str();
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(FloatingPointEqMatcher);

	floating_point<T> m_expected;
};

/**
 * @brief	Floating point Eq matcher (NanSensitive)
*/
template<typename T>
class NanSensitiveFloatingPointEqMatcher : public IMatcher
{
public:
	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(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "NanSensitive Eq: " << PrintToString(m_expected);
		return strm.str();
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(NanSensitiveFloatingPointEqMatcher);

	floating_point<T> m_expected;
};

/**
 * @brief	StartsWith matcher
*/
template<typename T>
class StartsWithMatcher : public IMatcher
{
public:
	StartsWithMatcher(T str) : m_str(str) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual) const
	{
		if( StartsWith(actual, m_str) ) return AssertionSuccess();
		return AssertionFailure() << WhichIs();
	}

public:
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "StartsWith: " << m_str;
		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:
	IUTEST_PP_DISALLOW_ASSIGN(StartsWithMatcher);

	T m_str;
};

/**
 * @brief	Has substr matcher
*/
template<typename T>
class HasSubstrMatcher : public IMatcher
{
public:
	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(void) const IUTEST_CXX_OVERRIDE
	{
		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) != NULL;
	}
	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:
	IUTEST_PP_DISALLOW_ASSIGN(HasSubstrMatcher);

	T m_expected;
};

/**
 * @brief	EndsWith matcher
*/
template<typename T>
class EndsWithMatcher : public IMatcher
{
public:
	EndsWithMatcher(T str) : m_str(str) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual) const
	{
		if( EndsWith(actual, m_str) ) return AssertionSuccess();
		return AssertionFailure() << WhichIs();
	}

public:
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "EndsWith: " << m_str;
		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:
	IUTEST_PP_DISALLOW_ASSIGN(EndsWithMatcher);

	T m_str;
};

/**
 * @brief	Equals matcher
*/
template<typename T>
class EqMatcher : public IMatcher
{
public:
	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(void) const IUTEST_CXX_OVERRIDE
	{
		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)
	{
IUTEST_PARGMA_WARN_PUSH()
IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()
		return actual == expected;
IUTEST_PARGMA_WARN_POP()
	}
	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:
	IUTEST_PP_DISALLOW_ASSIGN(EqMatcher);

	const T& m_expected;
};

/**
 * @brief	TypedEq matcher
*/
template<typename T>
class TypedEqMatcher : public EqMatcher<T>
{
public:
	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:
	IUTEST_PP_DISALLOW_ASSIGN(TypedEqMatcher);

	T m_expected;
};

/**
 * @brief	Cast to matcher
*/
#if !defined(IUTEST_NO_SFINAE)

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);
}

#else

template<typename T>
T& CastToMatcher(T& matcher)
{
	return matcher;
}

#endif


/**
 * @brief	Contains matcher
*/
template<typename T>
class ContainsMatcher : public IMatcher
{
public:
	ContainsMatcher(const T& expected) : m_expected(expected) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual)
	{
		if( Contains(actual, m_expected) ) return AssertionSuccess();
		return AssertionFailure() << WhichIs();
	}

public:
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "Contains: " << m_expected;
		return strm.str();
	}
private:
	template<typename TT, typename Container>
	bool Contains(const Container& actual, TT& expected)
	{
		return ContainsContainer(actual.begin(), actual.end(), expected);
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename TT, typename U, size_t SIZE>
	bool Contains(const U(&actual)[SIZE], TT& expected)
	{
		return ContainsContainer(actual, actual + SIZE, expected);
	}
#endif

	template<typename TT, typename Ite>
	bool ContainsContainer(Ite begin, Ite end, TT& expected)
	{
		for( Ite it = begin; it != end; ++it )
		{
			if( CastToMatcher(expected)(*it) )
			{
				return true;
			}
		}
		return false;
	}

private:
	IUTEST_PP_DISALLOW_ASSIGN(ContainsMatcher);

	T m_expected;
};

/**
 * @brief	Each matcher
*/
template<typename T>
class EachMatcher : public IMatcher
{
public:
	EachMatcher(const T& expected) : m_expected(expected) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual)
	{
		if( Each(actual) ) return AssertionSuccess();
		return AssertionFailure() << WhichIs();
	}

public:
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "Each: " << m_expected;
		return strm.str();
	}
private:
	template<typename Container>
	bool Each(const Container& actual)
	{
		return EachContainer(actual.begin(), actual.end());
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename U, size_t SIZE>
	bool Each(const U(&actual)[SIZE])
	{
		return EachContainer(actual, actual + SIZE);
	}
#endif

	template<typename Ite>
	bool EachContainer(Ite begin, Ite end)
	{
		for( Ite it = begin; it != end; ++it )
		{
			if( !CastToMatcher(m_expected)(*it) )
			{
				return false;
			}
		}
		return true;
	}

private:
	IUTEST_PP_DISALLOW_ASSIGN(EachMatcher);

	T m_expected;
};

/**
 * @brief	ContainerEq matcher
*/
template<typename T>
class ContainerEqMatcher : public IMatcher
{
public:
	ContainerEqMatcher(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(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "ContainerEq: " << PrintToString(m_expected);
		strm << " (" << m_whichIs << ")";
		return strm.str();
	}
private:
	template<typename Container>
	bool Check(const Container& actual)
	{
		return Check(m_expected, actual.begin(), actual.end());
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename U, size_t SIZE>
	bool Check(const U(&actual)[SIZE])
	{
		return Check(m_expected, actual, actual + SIZE);
	}
#endif

	template<typename Container, typename Ite>
	bool Check(const Container& expected, Ite b2, Ite e2)
	{
		return CheckContainer(expected.begin(), expected.end(), b2, e2);
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename U, size_t SIZE, typename Ite>
	bool Check(const U(&expected)[SIZE], Ite b2, Ite e2)
	{
		return CheckContainer(expected, expected + SIZE, b2, e2);
	}
#endif

	template<typename Ite1, typename Ite2>
	bool CheckContainer(Ite1 b1, Ite1 e1, Ite2 b2, Ite2 e2)
	{
		int elem=0;
		bool result = true;
		Message ar;
		for( elem=0; b1 != e1 && b2 != e2; ++b1, ++b2, ++elem )
		{
			if( !internal::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;
		}
		m_whichIs = ar.GetString();
		return result;
	}

private:
	IUTEST_PP_DISALLOW_ASSIGN(ContainerEqMatcher);

	const T& m_expected;
	::std::string m_whichIs;
};


/**
 * @brief	Pointwise matcher
*/
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)
	{
		if( Check(actual) ) return AssertionSuccess();
		return AssertionFailure() << WhichIs();
	}

public:
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "Pointwise: " << m_matcher << ": " << PrintToString(m_expected);
		strm << " (" << m_whichIs << ")";
		return strm.str();
	}
private:
	template<typename Container>
	bool Check(const Container& actual)
	{
		return Check(m_expected, actual.begin(), actual.end());
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename U, size_t SIZE>
	bool Check(const U(&actual)[SIZE])
	{
		return Check(m_expected, actual, actual + SIZE);
	}
#endif

	template<typename Container, typename Ite>
	bool Check(const Container& expected, Ite b2, Ite e2)
	{
		return CheckContainer(expected.begin(), expected.end(), b2, e2);
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename U, size_t SIZE, typename Ite>
	bool Check(const U(&expected)[SIZE], Ite b2, Ite e2)
	{
		return CheckContainer(expected, expected + SIZE, b2, e2);
	}
#endif

	template<typename Ite1, typename Ite2>
	bool CheckContainer(Ite1 b1, Ite1 e1, Ite2 b2, Ite2 e2)
	{
		int 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 )
		{
			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;
		}
		m_whichIs = ar.GetString();
		return result;
	}

private:
	IUTEST_PP_DISALLOW_ASSIGN(PointwiseMatcher);

	M m_matcher;
	const T& m_expected;
	::std::string m_whichIs;
};

/**
 * @brief	IsEmpty matcher
*/
class IsEmptyMatcher : public IMatcher
{
public:
	IsEmptyMatcher(void) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual)
	{
		if( (actual).empty() ) return AssertionSuccess();
		return AssertionFailure() << WhichIs();
	}

public:
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return "Is Empty";
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(IsEmptyMatcher);
};


/**
 * @brief	SizeIs matcher
*/
template<typename T>
class SizeIsMatcher : public IMatcher
{
public:
	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(void) const IUTEST_CXX_OVERRIDE
	{
		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()));
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename U, size_t SIZE>
	bool Check(const U(&)[SIZE])
	{
		return static_cast<bool>(CastToMatcher(m_expected)(SIZE));
	}
#endif

private:
	IUTEST_PP_DISALLOW_ASSIGN(SizeIsMatcher);

	T m_expected;
};

/**
 * @brief	At matcher
*/
template<typename T>
class AtMatcher : public IMatcher
{
public:
	AtMatcher(const 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(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "At " << m_index << ": " << m_expected;
		return strm.str();
	}

private:
	IUTEST_PP_DISALLOW_ASSIGN(AtMatcher);

	size_t m_index;
	T m_expected;
};

/**
 * @brief	ElementsAreArray matcher
*/
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)
	{
		return Check(actual);
	}

public:
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		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 Container>
	AssertionResult Check(const Container& actual)
	{
		return Check(actual.begin(), actual.end());
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<typename U, size_t SIZE>
	AssertionResult Check(const U(&actual)[SIZE])
	{
		return Check(actual, actual + SIZE);
	}
#endif

	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 a=actual_begin;
		typename ::std::vector<T>::iterator e=m_expected.begin();
		for( int i=0; e != m_expected.end(); ++e, ++a, ++i )
		{
			if( *a != *e )
			{
				return AssertionFailure() << WhichIs();
			}
		}
		return AssertionSuccess();
	}

private:
	IUTEST_PP_DISALLOW_ASSIGN(ElementsAreArrayMatcher);

	::std::vector<T> m_expected;
	bool m_expected_elem_count;
};

#if IUTEST_HAS_MATCHER_ELEMENTSARE

/**
 * @brief	ElementsAre matcher base class
*/
class ElementsAreMatcherBase : public IMatcher
{
protected:
	template<typename T, typename U>
	static AssertionResult Check(T& matchers, const U& actual)
	{
		return Check_<0, tuples::tuple_size<T>::value - 1>(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 Container, typename M>
	static AssertionResult Check_(const Container& actual, M& matchers)
	{
		return CheckSize<N, LAST>(actual.begin(), actual.end(), matchers);
	}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)
	template<int N, int LAST, typename U, size_t SIZE, typename M>
	static AssertionResult Check_(const U(&actual)[SIZE], M& matchers)
	{
		return CheckSize<N, LAST>(actual, actual + SIZE, matchers);
	}
#endif

	template<int N, int LAST, typename Ite, typename M>
	static AssertionResult CheckSize(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);
	}
	IUTEST_PP_DISALLOW_ASSIGN(ElementsAreMatcherBase);
};

#if IUTEST_HAS_VARIADIC_TEMPLATES

/**
* @brief	ElementsAre matcher
*/
template<typename ...T>
class ElementsAreMatcher : public ElementsAreMatcherBase
{
public:
	ElementsAreMatcher(T... t) : m_matchers(t...) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual)
	{
		return Check(m_matchers, actual);
	}
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return ElementsAreMatcherBase::WhichIs<0>(m_matchers);
	}

private:
	tuples::tuple<T...> m_matchers;
};

#else

/*
template<typename T0, typename T1>
class ElementsAreMatcher : public ElementsAreMatcherBase
{
public:
	ElementsAreMatcher(T0 m0, T1 m1) : m_matchers(m0, m1) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual)
	{
		return Check(m_matchers, actual);
	}
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return ElementsAreMatcherBase::WhichIs<0>(m_matchers);
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(ElementsAreMatcher);

	tuples::tuple<T0, T1> m_matchers;
};
*/

#define IIUT_DECL_ELEMENTSARE_MATCHER(n)												\
	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >									\
	class IUTEST_PP_CAT(ElementsAreMatcher, n) : public ElementsAreMatcherBase {		\
	public: IUTEST_PP_CAT(ElementsAreMatcher, n)(IUTEST_PP_ENUM_BINARY_PARAMS(n, T, m))	\
		: m_matchers(IUTEST_PP_ENUM_PARAMS(n, m)) {}									\
	template<typename U>AssertionResult operator ()(const U& actual) {					\
		return Check(m_matchers, actual); }												\
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE {								\
		return ElementsAreMatcherBase::WhichIs<0>(m_matchers); }						\
	private: IUTEST_PP_DISALLOW_ASSIGN(IUTEST_PP_CAT(ElementsAreMatcher, n));			\
	tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > m_matchers;							\
	}

IIUT_DECL_ELEMENTSARE_MATCHER(1);
IIUT_DECL_ELEMENTSARE_MATCHER(2);
IIUT_DECL_ELEMENTSARE_MATCHER(3);
IIUT_DECL_ELEMENTSARE_MATCHER(4);
IIUT_DECL_ELEMENTSARE_MATCHER(5);
IIUT_DECL_ELEMENTSARE_MATCHER(6);
IIUT_DECL_ELEMENTSARE_MATCHER(7);
IIUT_DECL_ELEMENTSARE_MATCHER(8);
IIUT_DECL_ELEMENTSARE_MATCHER(9);
IIUT_DECL_ELEMENTSARE_MATCHER(10);

#undef IIUT_DECL_ELEMENTSARE_MATCHER

#endif

#endif

/**
 * @brief	Field matcher
*/
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(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "Field: " << m_expected;
		//strm << "Field: (" << detail::GetTypeName<F>() << ") " << m_expected;
		return strm.str();
	}
private:

#if !defined(IUTEST_NO_SFINAE)
	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));
	}
#else
	template<typename U>
	bool Check(const U& actual)
	{
		return static_cast<bool>(CastToMatcher(m_expected)(actual->*m_field));
	}
#endif

private:
	IUTEST_PP_DISALLOW_ASSIGN(FieldMatcher);

	const F& m_field;
	T m_expected;
};

/**
 * @brief	Property matcher
*/
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(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "Property: " << m_expected;
		//strm << "Property: (" << detail::GetTypeName<F>() << ") " << m_expected;
		return strm.str();
	}
private:
#if !defined(IUTEST_NO_SFINAE)
	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)()));
	}
#else
	template<typename U>
	bool Check(const U& actual)
	{
		return static_cast<bool>(CastToMatcher(m_expected)((actual->*m_property)()));
	}
#endif

private:
	IUTEST_PP_DISALLOW_ASSIGN(PropertyMatcher);

	const F& m_property;
	T m_expected;
};

/**
 * @brief	Key matcher
*/
template<typename T>
class KeyMatcher : public IMatcher
{
public:
	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(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "Key: " << m_expected;
		return strm.str();
	}

private:
	IUTEST_PP_DISALLOW_ASSIGN(KeyMatcher);

	const T& m_expected;
};

/**
 * @brief	Pair matcher
*/
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(void) const IUTEST_CXX_OVERRIDE
	{
		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:
	IUTEST_PP_DISALLOW_ASSIGN(PairMatcher);

	T1 m_m1;
	T2 m_m2;
};

/**
 * @brief	ResultOf matcher
*/
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(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "Result of: " << m_expected;
		//strm << "Result of " << detail::GetTypeName<F>() << "(): " << 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:
	IUTEST_PP_DISALLOW_ASSIGN(ResultOfMatcher);

	F& m_func;
	T m_expected;
};

/**
 * @brief	Pointee matcher
*/
template<typename T>
class PointeeMatcher : public IMatcher
{
public:
	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(void) const IUTEST_CXX_OVERRIDE
	{
		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:
	IUTEST_PP_DISALLOW_ASSIGN(PointeeMatcher);

	T m_expected;
};

/**
 * @brief	Not matcher
*/
template<typename T>
class NotMatcher : public IMatcher
{
public:
	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(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "Not: (" << m_unexpected << ")";
		return strm.str();
	}

private:
	IUTEST_PP_DISALLOW_ASSIGN(NotMatcher);

	T m_unexpected;
};

/**
 * @brief	Any matcher
*/
template<typename T>
class AnyMatcher : public IMatcher
{
public:
	AnyMatcher(void) {}
public:
	AssertionResult operator ()(const T&) const
	{
		return AssertionSuccess();
	}
	template<typename U>
	AssertionResult operator ()(const U&) const;

public:
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		iu_global_format_stringstream strm;
		strm << "A: " << detail::GetTypeName<T>();
		return strm.str();
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(AnyMatcher);
};

/**
 * @brief	Anything matcher
*/
class AnythingMatcher : public IMatcher
{
public:
	AnythingMatcher(void) {}
public:
	template<typename U>
	AssertionResult operator ()(const U&) const
	{
		return AssertionSuccess();
	}

public:
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return "_";
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(AnythingMatcher);
};

#if IUTEST_HAS_MATCHER_REGEX

/**
 * @brief	Regex matcher
*/
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(void) const IUTEST_CXX_OVERRIDE
	{
		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:
	IUTEST_PP_DISALLOW_ASSIGN(RegexMatcher);

	detail::iuRegex m_expected;
	bool m_full_match;
};

#endif

#if IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF

/**
 * @brief	AllOf matcher base class
*/
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);
	}
	IUTEST_PP_DISALLOW_ASSIGN(AllOfMatcherBase);
};

#if IUTEST_HAS_VARIADIC_TEMPLATES

/**
 * @brief	AllOf matcher
*/
template<typename ...T>
class AllOfMatcher : public AllOfMatcherBase
{
public:
	AllOfMatcher(T... t) : m_matchers(t...) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual)
	{
		return Check(m_matchers, actual);
	}
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return AllOfMatcherBase::WhichIs<0>(m_matchers);
	}

private:
	tuples::tuple<T...> m_matchers;
};

#else

/*
template<typename T0, typename T1>
class AllOfMatcher : public AllOfMatcherBase
{
public:
	AllOfMatcher(T0 m0, T1 m1) : m_matchers(m0, m1) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual)
	{
		return Check(m_matchers, actual);
	}
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return AllOfMatcherBase::WhichIs<0>(m_matchers);
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(AllOfMatcher);

	tuples::tuple<T0, T1> m_matchers;
};
*/

#define IIUT_DECL_ALLOF_MATCHER(n)													\
	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >								\
	class IUTEST_PP_CAT(AllOfMatcher, n) : public AllOfMatcherBase {				\
	public: IUTEST_PP_CAT(AllOfMatcher, n)(IUTEST_PP_ENUM_BINARY_PARAMS(n, T, m))	\
		: m_matchers(IUTEST_PP_ENUM_PARAMS(n, m)) {}								\
	template<typename U>AssertionResult operator ()(const U& actual) {				\
		return Check(m_matchers, actual); }											\
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE {							\
		return AllOfMatcherBase::WhichIs<0>(m_matchers); }							\
	private: IUTEST_PP_DISALLOW_ASSIGN(IUTEST_PP_CAT(AllOfMatcher, n));				\
	tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > m_matchers;						\
	}

IIUT_DECL_ALLOF_MATCHER(2);
IIUT_DECL_ALLOF_MATCHER(3);
IIUT_DECL_ALLOF_MATCHER(4);
IIUT_DECL_ALLOF_MATCHER(5);
IIUT_DECL_ALLOF_MATCHER(6);
IIUT_DECL_ALLOF_MATCHER(7);
IIUT_DECL_ALLOF_MATCHER(8);
IIUT_DECL_ALLOF_MATCHER(9);
IIUT_DECL_ALLOF_MATCHER(10);

#undef IIUT_DECL_ALLOF_MATCHER

#endif

/**
 * @brief	AnyOf matcher base class
*/
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);
	}

	IUTEST_PP_DISALLOW_ASSIGN(AnyOfMatcherBase);
};

#if IUTEST_HAS_VARIADIC_TEMPLATES

/**
 * @brief	AnyOf matcher
*/
template<typename ...T>
class AnyOfMatcher : public AnyOfMatcherBase
{
public:
	AnyOfMatcher(T... t) : m_matchers(t...) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual)
	{
		return Check(m_matchers, actual);
	}
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return AnyOfMatcherBase::WhichIs<0>(m_matchers);
	}

private:
	tuples::tuple<T...> m_matchers;
};

#else

/*
template<typename T0, typename T1>
class AnyOfMatcher : public AnyOfMatcherBase
{
public:
	AnyOfMatcher(T0 m0, T1 m1) : m_matchers(m0, m1) {}

public:
	template<typename U>
	AssertionResult operator ()(const U& actual)
	{
		return Check(m_matchers, actual);
	}
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE
	{
		return AnyOfMatcherBase::WhichIs<0>(m_matchers);
	}
private:
	IUTEST_PP_DISALLOW_ASSIGN(AnyOfMatcher);

	tuples::tuple<T0, T1> m_matchers;
};
*/

#define IIUT_DECL_ANYOF_MATCHER(n)													\
	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >								\
	class IUTEST_PP_CAT(AnyOfMatcher, n) : public AnyOfMatcherBase {				\
	public: IUTEST_PP_CAT(AnyOfMatcher, n)(IUTEST_PP_ENUM_BINARY_PARAMS(n, T, m))	\
		: m_matchers(IUTEST_PP_ENUM_PARAMS(n, m)) {}								\
	template<typename U>AssertionResult operator ()(const U& actual) {				\
		return Check(m_matchers, actual); }											\
	::std::string WhichIs(void) const IUTEST_CXX_OVERRIDE {							\
		return AnyOfMatcherBase::WhichIs<0>(m_matchers); }							\
	private: IUTEST_PP_DISALLOW_ASSIGN(IUTEST_PP_CAT(AnyOfMatcher, n));				\
	tuples::tuple< IUTEST_PP_ENUM_PARAMS(n, T) > m_matchers;						\
	}

IIUT_DECL_ANYOF_MATCHER(2);
IIUT_DECL_ANYOF_MATCHER(3);
IIUT_DECL_ANYOF_MATCHER(4);
IIUT_DECL_ANYOF_MATCHER(5);
IIUT_DECL_ANYOF_MATCHER(6);
IIUT_DECL_ANYOF_MATCHER(7);
IIUT_DECL_ANYOF_MATCHER(8);
IIUT_DECL_ANYOF_MATCHER(9);
IIUT_DECL_ANYOF_MATCHER(10);

#undef IIUT_DECL_ANYOF_MATCHER

#endif

#endif

}	// end of namespace detail

namespace matchers
{

/**
 * @ingroup	MATCHERS
 * @brief	Make Equals matcher
 * @details	argument == expected
*/
template<typename T>
detail::EqMatcher<T> Equals(const T& expected) { return detail::EqMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Eq matcher
 * @details	argument == expected
*/
template<typename T>
detail::EqMatcher<T> Eq(const T& expected) { return detail::EqMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Ne matcher
 * @details	argument != expected
*/
template<typename T>
detail::NeMatcher<T> Ne(const T& expected) { return detail::NeMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Le matcher
 * @details	argument <= expected
*/
template<typename T>
detail::LeMatcher<T> Le(const T& expected) { return detail::LeMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Lt matcher
 * @details	argument < expected
*/
template<typename T>
detail::LtMatcher<T> Lt(const T& expected) { return detail::LtMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Ge matcher
 * @details	argument >= expected
*/
template<typename T>
detail::GeMatcher<T> Ge(const T& expected) { return detail::GeMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Gt matcher
 * @details	argument > expected
*/
template<typename T>
detail::GtMatcher<T> Gt(const T& expected) { return detail::GtMatcher<T>(expected); }


/**
 * @ingroup	MATCHERS
 * @brief	Make Twofold Eq matcher
 * @details	argument == expected
*/
inline detail::TwofoldEqMatcher Eq(void) { return detail::TwofoldEqMatcher(); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Twofold Ne matcher
 * @details	argument != expected
*/
inline detail::TwofoldNeMatcher Ne(void) { return detail::TwofoldNeMatcher(); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Twofold Le matcher
 * @details	argument <= expected
*/
inline detail::TwofoldLeMatcher Le(void) { return detail::TwofoldLeMatcher(); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Twofold Lt matcher
 * @details	argument < expected
*/
inline detail::TwofoldLtMatcher Lt(void) { return detail::TwofoldLtMatcher(); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Twofold Ge matcher
 * @details	argument >= expected
*/
inline detail::TwofoldGeMatcher Ge(void) { return detail::TwofoldGeMatcher(); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Twofold Gt matcher
 * @details	argument > expected
*/
inline detail::TwofoldGtMatcher Gt(void) { return detail::TwofoldGtMatcher(); }

/**
 * @ingroup	MATCHERS
 * @brief	Make IsNull matcher
 * @details	argument == nullptr
*/
inline detail::IsNullMatcher IsNull() { return detail::IsNullMatcher(); }

/**
 * @ingroup	MATCHERS
 * @brief	Make NotNull matcher
 * @details	argument != nullptr
*/
inline detail::NotNullMatcher NotNull() { return detail::NotNullMatcher(); }

/**
 * @ingroup	MATCHERS
 * @brief	Make TypedEq matcher
 * @details	argument == expected
*/
template<typename T, typename U>
detail::TypedEqMatcher<T> TypedEq(const U& expected) { return detail::TypedEqMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Float Eq matcher
 * @details	argument は expected とおよそ等しい
*/
inline detail::FloatingPointEqMatcher<float> FloatEq(float expected) { return detail::FloatingPointEqMatcher<float>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Double Eq matcher
 * @details	argument は expected とおよそ等しい
*/
inline detail::FloatingPointEqMatcher<double> DoubleEq(double expected) { return detail::FloatingPointEqMatcher<double>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make NanSensitive Float Eq matcher
 * @details	argument は expected とおよそ等しい（NaN 同士は等しいとされる）
*/
inline detail::NanSensitiveFloatingPointEqMatcher<float> NanSensitiveFloatEq(float expected) { return detail::NanSensitiveFloatingPointEqMatcher<float>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make NanSensitive Double Eq matcher
 * @details	argument は expected とおよそ等しい（NaN 同士は等しいとされる）
*/
inline detail::NanSensitiveFloatingPointEqMatcher<double> NanSensitiveDoubleEq(double expected) { return detail::NanSensitiveFloatingPointEqMatcher<double>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make StrEq matcher
 * @details	argument == expected
*/
template<typename T>
detail::StrEqMatcher<T> StrEq(const T& expected) { return detail::StrEqMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make StrNe matcher
 * @details	argument != expected
*/
template<typename T>
detail::StrNeMatcher<T> StrNe(const T& expected) { return detail::StrNeMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make StrCaseEq matcher
 * @details	argument == expected (ignore case)
*/
template<typename T>
detail::StrCaseEqMatcher<T> StrCaseEq(const T& expected) { return detail::StrCaseEqMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make StrCaseNe matcher
 * @details	argument != expected (ignore case)
*/
template<typename T>
detail::StrCaseNeMatcher<T> StrCaseNe(const T& expected) { return detail::StrCaseNeMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make StartsWith matcher
 * @details	argument の先頭が str である
*/
template<typename T>
detail::StartsWithMatcher<const T&> StartsWith(const T& str) { return detail::StartsWithMatcher<const T&>(str); }

/**
 * @ingroup	MATCHERS
 * @brief	Make HasSubstr matcher
 * @details	argument が str を含む
*/
template<typename T>
detail::HasSubstrMatcher<const T&> HasSubstr(const T& str) { return detail::HasSubstrMatcher<const T&>(str); }

/**
 * @ingroup	MATCHERS
 * @brief	Make EndsWith matcher
 * @details	argument の末尾が str である
*/
template<typename T>
detail::EndsWithMatcher<const T&> EndsWith(const T& str) { return detail::EndsWithMatcher<const T&>(str); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Contains matcher
 * @details	argument は expected にマッチする要素を含む
*/
template<typename T>
detail::ContainsMatcher<T> Contains(const T& expected) { return detail::ContainsMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Each matcher
 * @details	argument はすべての要素が expected にマッチする
*/
template<typename T>
detail::EachMatcher<T> Each(const T& expected) { return detail::EachMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make ContainerEq matcher
 * @details	argument コンテナは expected コンテナにマッチする
*/
template<typename T>
detail::ContainerEqMatcher<T> ContainerEq(const T& expected) { return detail::ContainerEqMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Pointwise matcher
 * @details	argument コンテナは expected コンテナの各要素と matcher にマッチする
*/
template<typename M, typename T>
detail::PointwiseMatcher<M, T> Pointwise(const M& matcher, const T& expected) { return detail::PointwiseMatcher<M, T>(matcher, expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make IsEmpty matcher
 * @details	argument.empty()
*/
inline detail::IsEmptyMatcher IsEmpty() { return detail::IsEmptyMatcher(); }

/**
 * @ingroup	MATCHERS
 * @brief	Make SizeIs matcher
 * @details	argument の要素数が expected にマッチする
*/
template<typename T>
detail::SizeIsMatcher<T> SizeIs(const T& expected) { return detail::SizeIsMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make At matcher
 * @details	argument[index] は expected にマッチする
*/
template<typename T>
detail::AtMatcher<T> At(size_t index, const T& expected) { return detail::AtMatcher<T>(index, expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make ElementsAreArray matcher
 * @details	argument はの各要素が a の要素とマッチする
*/
template<typename Container>
detail::ElementsAreArrayMatcher< typename Container::value_type > ElementsAreArray(Container container)
{
	return detail::ElementsAreArrayMatcher<typename Container::value_type>(container.begin(), container.end());
}

#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)

template<typename T, size_t SIZE>
detail::ElementsAreArrayMatcher<T> ElementsAreArray(const T(&v)[SIZE])
{
	return detail::ElementsAreArrayMatcher<T>(v, v + SIZE);
}

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

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);
}
#endif

#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

#endif

/**
 * @ingroup	MATCHERS
 * @brief	Make ElementsAreArray matcher
 * @details	argument は count 個の要素があり、 a の要素とマッチする
*/
template<typename T>
detail::ElementsAreArrayMatcher<T> ElementsAreArray(const T* a, int count)
{
	return detail::ElementsAreArrayMatcher<T>(a, a + count);
}

#if IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD

/**
 * @ingroup	MATCHERS
 * @brief	Make ElementsAreArrayForward matcher
 * @details	argument はの各要素が a の要素とマッチする
*/
template<typename Container>
detail::ElementsAreArrayMatcher< typename Container::value_type > ElementsAreArrayForward(Container container)
{
	return detail::ElementsAreArrayMatcher<typename Container::value_type>(container.begin(), container.end(), false);
}

#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)

template<typename T, size_t SIZE>
detail::ElementsAreArrayMatcher<T> ElementsAreArrayForward(const T(&v)[SIZE])
{
	return detail::ElementsAreArrayMatcher<T>(v, v + SIZE, false);
}

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

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);
}
#endif

#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

#endif

/**
 * @ingroup	MATCHERS
 * @brief	Make ElementsAreArrayForward matcher
 * @details	argument は count 個の以上の要素があり、 a の要素とマッチする
*/
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_VARIADIC_TEMPLATES

/**
 * @ingroup	MATCHERS
 * @brief	Make ElementsAre matcher
*/
template<typename ...T>
detail::ElementsAreMatcher<T...> ElementsAre(const T&... m) { return detail::ElementsAreMatcher<T...>(m...); }

#else

#define IIUT_ELEMENTSARE_MATCHER_NAME(n)	IUTEST_PP_CAT(ElementsAreMatcher, n)
#define IIUT_DECL_ELEMENTSARE(n)												\
	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >							\
	detail:: IIUT_ELEMENTSARE_MATCHER_NAME(n)< IUTEST_PP_ENUM_PARAMS(n, T) >	\
	ElementsAre( IUTEST_PP_ENUM_BINARY_PARAMS(n, const T, &m) ) { return		\
	detail:: IIUT_ELEMENTSARE_MATCHER_NAME(n)< IUTEST_PP_ENUM_PARAMS(n, T) >	\
		( IUTEST_PP_ENUM_PARAMS(n, m) ); }


IIUT_DECL_ELEMENTSARE(1)
IIUT_DECL_ELEMENTSARE(2)
IIUT_DECL_ELEMENTSARE(3)
IIUT_DECL_ELEMENTSARE(4)
IIUT_DECL_ELEMENTSARE(5)
IIUT_DECL_ELEMENTSARE(6)
IIUT_DECL_ELEMENTSARE(7)
IIUT_DECL_ELEMENTSARE(8)
IIUT_DECL_ELEMENTSARE(9)
IIUT_DECL_ELEMENTSARE(10)

#undef IIUT_ELEMENTSARE_MATCHER_NAME
#undef IIUT_DECL_ELEMENTSARE
#endif

#endif

/**
 * @ingroup	MATCHERS
 * @brief	Make Key matcher
 * @details	argument.first は expedted にマッチする 
*/
template<typename T>
detail::KeyMatcher<T> Key(const T& expected) { return detail::KeyMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Pair matcher
 * @details	argument.first は m1 にマッチし、arugment.second が m2 にマッチする 
*/
template<typename T1, typename T2>
detail::PairMatcher<T1, T2> Pair(const T1& m1, const T2& m2) { return detail::PairMatcher<T1, T2>(m1, m2); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Field matcher
 * @details	argument.*field は expedted にマッチする 
*/
template<typename F, typename T>
detail::FieldMatcher<F, T> Field(const F& field, const T& expected) { return detail::FieldMatcher<F, T>(field, expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Property matcher
 * @details	argument.*property() は expedted にマッチする 
*/
template<typename P, typename T>
detail::PropertyMatcher<P, T> Property(const P& prop, const T& expected) { return detail::PropertyMatcher<P, T>(prop, expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make ResultOf matcher
 * @details	func(argument) の戻り値は expedted にマッチする 
*/
template<typename F, typename T>
detail::ResultOfMatcher<F, T> ResultOf(const F& func, const T& expected) { return detail::ResultOfMatcher<F, T>(func, expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Pointee matcher
*/
template<typename T>
detail::PointeeMatcher<T> Pointee(const T& expected) { return detail::PointeeMatcher<T>(expected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Not matcher
*/
template<typename T>
detail::NotMatcher<T> Not(const T& unexpected) { return detail::NotMatcher<T>(unexpected); }

/**
 * @ingroup	MATCHERS
 * @brief	Make Any matcher
*/
template<typename T>
detail::AnyMatcher<T> A(void) { return detail::AnyMatcher<T>(); }


/**
 * @ingroup	MATCHERS
 * @brief	Anything matcher
*/
const detail::AnythingMatcher _;

#if IUTEST_HAS_MATCHER_REGEX

/**
 * @ingroup	MATCHERS
 * @brief	Make MatchesRegex matcher
*/
inline detail::RegexMatcher MatchesRegex(const ::std::string& str)
{
	return detail::RegexMatcher(detail::iuRegex(str), true);
}

/**
 * @ingroup	MATCHERS
 * @brief	Make ContainsRegex matcher
*/
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_VARIADIC_TEMPLATES

/**
 * @ingroup	MATCHERS
 * @brief	Make AllOf matcher
 * @details	argument が全ての matcher にマッチする
*/
template<typename ...T>
detail::AllOfMatcher<T...> AllOf(const T&... m) { return detail::AllOfMatcher<T...>(m...); }

/**
 * @ingroup	MATCHERS
 * @brief	Make AnyOf matcher
 * @details	argument がいずれかの matcher にマッチする
*/
template<typename ...T>
detail::AnyOfMatcher<T...> AnyOf(const T&... m) { return detail::AnyOfMatcher<T...>(m...); }

#else

#define IIUT_ANYOF_AND_ALLOF_MATCHER_NAME(name, n)	IUTEST_PP_CAT( IUTEST_PP_CAT(name, Matcher), n)
#define IIUT_DECL_ANYOF_AND_ALLOF(name, n)												\
	template< IUTEST_PP_ENUM_PARAMS(n, typename T) >									\
	detail:: IIUT_ANYOF_AND_ALLOF_MATCHER_NAME(name, n)< IUTEST_PP_ENUM_PARAMS(n, T) >	\
	name( IUTEST_PP_ENUM_BINARY_PARAMS(n, const T, &m) ) { return						\
	detail:: IIUT_ANYOF_AND_ALLOF_MATCHER_NAME(name, n)< IUTEST_PP_ENUM_PARAMS(n, T) >	\
		( IUTEST_PP_ENUM_PARAMS(n, m) ); }


IIUT_DECL_ANYOF_AND_ALLOF(AllOf, 2)
IIUT_DECL_ANYOF_AND_ALLOF(AllOf, 3)
IIUT_DECL_ANYOF_AND_ALLOF(AllOf, 4)
IIUT_DECL_ANYOF_AND_ALLOF(AllOf, 5)
IIUT_DECL_ANYOF_AND_ALLOF(AllOf, 6)
IIUT_DECL_ANYOF_AND_ALLOF(AllOf, 7)
IIUT_DECL_ANYOF_AND_ALLOF(AllOf, 8)
IIUT_DECL_ANYOF_AND_ALLOF(AllOf, 9)
IIUT_DECL_ANYOF_AND_ALLOF(AllOf, 10)

IIUT_DECL_ANYOF_AND_ALLOF(AnyOf, 2)
IIUT_DECL_ANYOF_AND_ALLOF(AnyOf, 3)
IIUT_DECL_ANYOF_AND_ALLOF(AnyOf, 4)
IIUT_DECL_ANYOF_AND_ALLOF(AnyOf, 5)
IIUT_DECL_ANYOF_AND_ALLOF(AnyOf, 6)
IIUT_DECL_ANYOF_AND_ALLOF(AnyOf, 7)
IIUT_DECL_ANYOF_AND_ALLOF(AnyOf, 8)
IIUT_DECL_ANYOF_AND_ALLOF(AnyOf, 9)
IIUT_DECL_ANYOF_AND_ALLOF(AnyOf, 10)

#undef IIUT_ANYOF_AND_ALLOF_MATCHER_NAME
#undef IIUT_DECL_ANYOF_AND_ALLOF

#endif

#endif

/**
 * @ingroup	MATCHERS
 * @brief	Value predicate
*/
template<typename T, typename M>
bool Value(const T& value, const M& expected) { return static_cast<bool>(detail::CastToMatcher(expected)(value)); }


}	// end of namespace matchers

using namespace matchers;

}	// end of namespace iutest

#endif	// IUTEST_HAS_MATCHERS

#endif // INCG_IRIS_IUTEST_MATCHER_HPP_23746E00_1A4B_4778_91AD_45C6DEFEEFA7_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_static_assertion.hpp
 * @brief		iris unit test static assertion 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_STATIC_ASSERTION_HPP_53842FD6_9E5D_40A6_905D_EC6DEBE5ED6A_
#define INCG_IRIS_IUTEST_STATIC_ASSERTION_HPP_53842FD6_9E5D_40A6_905D_EC6DEBE5ED6A_

//======================================================================
// define
#if IUTEST_HAS_STATIC_ASSERT_TYPEEQ

#if 0
/**
 * @ingroup	IUTEST_UTIL
 * @brief	型アサーション
*/
template<typename T1, typename T2>
static bool	StaticAssertTypeEq(void)
{
	(void)detail::StaticAssertTypeEqHelper<T1, T2>();
	return true;
}
#else

/**
 * @ingroup	IUTEST_UTIL
 * @brief	型アサーション
 * @note	マクロバージョン
 *			エラーが呼び出し位置に出る
*/
#define StaticAssertTypeEq	detail::StaticAssertTypeEqHelper

#endif

#endif

/**
 * @brief	static_assert
*/
#if IUTEST_HAS_STATIC_ASSERT
#if defined(_MSC_VER)
#  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 IUTEST_STATIC_ASSERT_MSG(B, Msg)	\
	typedef ::iutest::detail::static_assert_failure< sizeof(::iutest::detail::static_assert_failure< (bool)B >) > IUTEST_PP_CAT(iutest_static_assert_typedef_, IUTEST_PP_COUNTER)
#endif

/**
 * @brief	static_assert
*/
#ifdef IUTEST_STATIC_ASSERT_MSG
#  ifdef IUTEST_NO_VARIADIC_MACROS
#    define IUTEST_STATIC_ASSERT(B)		IUTEST_STATIC_ASSERT_MSG(B, #B)
#  else
#    define IUTEST_STATIC_ASSERT(...)	IUTEST_STATIC_ASSERT_MSG((__VA_ARGS__), #__VA_ARGS__)
#  endif
#endif

/**
 * @brief	static assert if exists
*/
#ifndef IUTEST_STATIC_ASSERT_IF_EXISTS
#  if IUTEST_HAS_IF_EXISTS
#    define IUTEST_STATIC_ASSERT_IF_EXISTS(identifier, msg)	\
		IUTEST_STATIC_ASSERT_MSG( IUTEST_IF_EXISTS(identifier, true) IUTEST_IF_NOT_EXISTS(identifier,false), msg)
#  else
#    define IUTEST_STATIC_ASSERT_IF_EXISTS(identifier, msg)
#  endif
#endif

/**
 * @brief	static assert if not exists
*/
#ifndef IUTEST_STATIC_ASSERT_IF_NOT_EXISTS
#  if IUTEST_HAS_IF_EXISTS
#    define IUTEST_STATIC_ASSERT_IF_NOT_EXISTS(identifier, msg)	\
		IUTEST_STATIC_ASSERT_MSG(IUTEST_IF_NOT_EXISTS(identifier, true) IUTEST_IF_EXISTS(identifier, false), msg)
#  else
#    define IUTEST_STATIC_ASSERT_IF_NOT_EXISTS(identifier, msg)
#  endif
#endif

//======================================================================
// function
namespace iutest
{

namespace detail
{


template<typename T1, typename T2>
struct StaticAssertTypeEqHelper;

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
namespace helper
{


template<bool b>struct static_assert_typeeq;

template<>struct static_assert_typeeq<true> { operator bool (void) const { return true; } };

}


template<typename T1, typename T2>
struct StaticAssertTypeEqHelper
	: public helper::static_assert_typeeq< iutest_type_traits::is_same<T1, T2>::value > {};

#endif


template<bool b>struct static_assert_failure;

template<> struct static_assert_failure<true> { enum { value = 1 }; };


template<int x>struct StaticAssertionTest {};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_STATIC_ASSERTION_HPP_53842FD6_9E5D_40A6_905D_EC6DEBE5ED6A_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_ignore.hpp
 * @brief		iris unit test ignore test ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2013-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_IGNORE_HPP_D87CADCE_110D_43CE_9E68_3B6BB0B91E66_
#define INCG_IRIS_IUTEST_IGNORE_HPP_D87CADCE_110D_43CE_9E68_3B6BB0B91E66_

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

#if IUTEST_HAS_IGNORE_TEST

/**
 * @ingroup	TESTDEF
 * @def		IUTEST_TEST_IGNORE(testcase_, testname_)
 * @brief	テスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
 * @note	ignore 版ではテストコードのコンパイルが通らなくても問題ない
*/
#define IUTEST_TEST_IGNORE(testcase_, testname_)	IUTEST_TEST_IGNORE_(testcase_, testname_, ::iutest::Test	\
														, ::iutest::internal::GetTestTypeId())

/**
 * @ingroup	TESTDEF
 * @def		IUTEST_TEST_IGNORE(testcase_, testname_)
 * @brief	テスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
 * @note	ignore 版ではテストコードのコンパイルが通らなくても問題ない
*/
#define IUTEST_IGNORE(testcase_, testname_)			IUTEST_TEST_IGNORE(testcase_, testname_)


/**
 * @ingroup	TESTDEF
 * @def		IUTEST_F_IGNORE(testfixture_, testname_)
 * @brief	ユーザー指定テスト関数定義マクロ
 * @param	testfixture_	= テストフィクスチャ名
 * @param	testname_		= テスト名
 * @note	ignore 版ではテストコードのコンパイルが通らなくても問題ない
*/
#define IUTEST_F_IGNORE(testfixture_, testname_)	IUTEST_TEST_F_IGNORE_(testfixture_, testname_)

#if IUTEST_HAS_PARAM_TEST

/**
 * @ingroup	TESTDEF
 * @def		IUTEST_P_IGNORE(testcase_, testname_)
 * @brief	パラメータユーザー指定テスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
 * @note	ignore 版ではテストコードのコンパイルが通らなくても問題ない
*/
#define IUTEST_P_IGNORE(testcase_, testname_)		IIUT_TEST_P_IGNORE_(testcase_, testname_)

#endif

#if IUTEST_HAS_TYPED_TEST

/**
 * @ingroup	TESTDEF
 * @def		IUTEST_TYPED_TEST(testcase_, testname_)
 * @brief	型付けテスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
 * @note	ignore 版ではテストコードのコンパイルが通らなくても問題ない
*/
#define IUTEST_TYPED_TEST_IGNORE(testcase_, testname_)		IIUT_TYPED_TEST_IGNORE_(testcase_, testname_)

#endif

#if IUTEST_HAS_TYPED_TEST_P

/**
 * @ingroup	TESTDEF
 * @def		IUTEST_TYPED_TEST_P(testcase_, testname_)
 * @brief	型パラメータテスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
 * @note	ignore 版ではテストコードのコンパイルが通らなくても問題ない
*/
#define IUTEST_TYPED_TEST_P_IGNORE(testcase_, testname_)	IIUT_TYPED_TEST_P_IGNORE_(testcase_, testname_)

#endif

#endif

#endif // INCG_IRIS_IUTEST_IGNORE_HPP_D87CADCE_110D_43CE_9E68_3B6BB0B91E66_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_default_printer.hpp
 * @brief		iris unit test デフォルト出力イベントリスナー ファイル
 *
 * @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_DEFAULT_PRINTER_HPP_77055C2B_AAE1_4944_A61C_26C58B04B37B_
#define INCG_IRIS_IUTEST_DEFAULT_PRINTER_HPP_77055C2B_AAE1_4944_A61C_26C58B04B37B_

namespace iutest
{

//======================================================================
// class
/**
 * @brief	デフォルト出力イベントリスナー
*/
class DefalutResultPrintListener : public TestEventListener
{
public:
	DefalutResultPrintListener(void) {}

	virtual ~DefalutResultPrintListener(void)
	{
		TestEnv::event_listeners().set_default_result_printer(NULL);
	}
public:
	virtual void OnTestProgramStart(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnTestIterationStart(const UnitTest& test
									, int iteration) IUTEST_CXX_OVERRIDE;
	virtual void OnEnvironmentsSetUpStart(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnEnvironmentsSetUpEnd(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnTestCaseStart(const TestCase& test_case) IUTEST_CXX_OVERRIDE;
	virtual void OnTestStart(const TestInfo& test_info) IUTEST_CXX_OVERRIDE;
	virtual void OnTestPartResult(const TestPartResult& test_part_result) IUTEST_CXX_OVERRIDE;
	virtual void OnTestRecordProperty(const TestProperty& test_property) IUTEST_CXX_OVERRIDE;
	virtual void OnTestEnd(const TestInfo& test_info) IUTEST_CXX_OVERRIDE;
	virtual void OnTestCaseEnd(const TestCase& test_case) IUTEST_CXX_OVERRIDE;
	virtual void OnEnvironmentsTearDownStart(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnEnvironmentsTearDownEnd(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnTestIterationEnd(const UnitTest& test
									, int iteration) IUTEST_CXX_OVERRIDE;
	virtual void OnTestProgramEnd(const UnitTest& test) IUTEST_CXX_OVERRIDE;
};

}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_default_printer.ipp
 * @brief		iris unit test デフォルト出力イベントリスナー ファイル
 *
 * @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_DEFAULT_PRINTER_IPP_77055C2B_AAE1_4944_A61C_26C58B04B37B_
#define INCG_IRIS_IUTEST_DEFAULT_PRINTER_IPP_77055C2B_AAE1_4944_A61C_26C58B04B37B_

//======================================================================
// include

namespace iutest
{

IUTEST_IPP_INLINE void DefalutResultPrintListener::OnTestProgramStart(const UnitTest& test)
{
	IUTEST_UNUSED_VAR(test);
	// フィルタリング
	if( TestFlag::IsEnableFlag(TestFlag::FILTERING_TESTS) )
	{
		detail::iuConsole::color_output(detail::iuConsole::yellow, "Note: iutest filter = %s\n", TestEnv::test_filter());
	}
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnTestIterationStart(const UnitTest& test
								, int iteration)
{
	if( IUTEST_FLAG(repeat) != 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() );
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnEnvironmentsSetUpStart(const UnitTest& test)
{
	IUTEST_UNUSED_VAR(test);

	detail::iuConsole::color_output(detail::iuConsole::green, "[----------] ");
	detail::iuConsole::output("Global test environment set-up.\n" );
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnEnvironmentsSetUpEnd(const UnitTest& test)
{
	IUTEST_UNUSED_VAR(test);
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::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.testcase_name_with_where().c_str() );
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::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());
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnTestPartResult(const TestPartResult& test_part_result)
{
	//if( test_part_result.type() == TestPartResult::kSuccess ) return;
	detail::iuConsole::output(test_part_result.make_newline_message().c_str());
#if defined(_MSC_VER) && !defined(IUTEST_OS_WINDOWS_MOBILE)
	OutputDebugStringA(test_part_result.make_newline_message().c_str());
#endif
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnTestRecordProperty(const TestProperty& test_property)
{
	detail::iuConsole::output("iutest record property:\n  %s=%s\n", test_property.key(), test_property.value());
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnTestEnd(const TestInfo& test_info)
{
	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());
	}
	else 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());
	}
	else
	{
		detail::iuConsole::color_output(detail::iuConsole::green, "[       OK ] ");
		detail::iuConsole::output("%s.%s", test_info.test_case_name(), test_info.name());
	}
	if( TestFlag::IsEnableFlag(TestFlag::PRINT_TIME) )
	{
#if defined(IUTEST_NOT_SUPPORT_STOPWATCH)
		detail::iuConsole::output(" (--ms)\n" );
#else
		detail::iuConsole::output(" (%dms)\n", test_info.elapsed_time());
#endif
	}
	else
	{
		detail::iuConsole::output("\n");
	}
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnTestCaseEnd(const TestCase& test_case)
{
	detail::iuConsole::color_output(detail::iuConsole::green, "[----------] ");
#if !defined(IUTEST_NOT_SUPPORT_STOPWATCH)
	if( TestFlag::IsEnableFlag(TestFlag::PRINT_TIME) )
	{
		detail::iuConsole::output("%d tests from %s (%dms total)\n\n", test_case.test_to_run_count(), test_case.name(), test_case.elapsed_time() );
	}
	else
#endif
	{
		detail::iuConsole::output("%d tests from %s\n\n", test_case.test_to_run_count(), test_case.name() );
	}
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnEnvironmentsTearDownStart(const UnitTest& test)
{
	IUTEST_UNUSED_VAR(test);

	detail::iuConsole::color_output(detail::iuConsole::green, "[----------] ");
	detail::iuConsole::output("Global test environment tear-down.\n" );
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnEnvironmentsTearDownEnd(const UnitTest& test)
{
	IUTEST_UNUSED_VAR(test);
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnTestIterationEnd(const UnitTest& test
								, int iteration)
{
	IUTEST_UNUSED_VAR(iteration);

	detail::iuConsole::color_output(detail::iuConsole::green, "[==========] ");
#if !defined(IUTEST_NOT_SUPPORT_STOPWATCH)
	if( TestFlag::IsEnableFlag(TestFlag::PRINT_TIME) )
	{
		detail::iuConsole::output("%d tests from %d testcase ran. (%dms total)\n", test.test_to_run_count(), test.test_case_to_run_count(), test.elapsed_time() );
	}
	else
#endif
	{
		detail::iuConsole::output("%d tests from %d testcase ran.\n", test.test_to_run_count(), test.test_case_to_run_count() );
	}

	{
		{
			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_testresult()->Failed() )
				{
					detail::iuConsole::color_output(detail::iuConsole::red, "[  FAILED  ] ");
					detail::iuConsole::output("%s at SetUpTestCase/TearDownTestCase\n", testcase->name());
				}
			}

			if( test.ad_hoc_testresult()->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" );
		}
	}
}
IUTEST_IPP_INLINE void DefalutResultPrintListener::OnTestProgramEnd(const UnitTest& test)
{
	IUTEST_UNUSED_VAR(test);
}

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_DEFAULT_PRINTER_IPP_77055C2B_AAE1_4944_A61C_26C58B04B37B_
#endif

#endif // INCG_IRIS_IUTEST_DEFAULT_PRINTER_HPP_77055C2B_AAE1_4944_A61C_26C58B04B37B_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_junit_xml_generator.hpp
 * @brief		output junit xml event listener
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_JUNIT_XML_GENERATOR_HPP_C6AD11BD_BDA4_45F3_A736_53B09DD6A7BD_
#define INCG_IRIS_IUTEST_JUNIT_XML_GENERATOR_HPP_C6AD11BD_BDA4_45F3_A736_53B09DD6A7BD_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_default_xml_generator.hpp
 * @brief		iris unit test xml 出力イベントリスナー ファイル
 *
 * @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_DEFAULT_XML_GENERATOR_HPP_791DCB98_05CC_49BA_8518_0EC9CA2B5450_
#define INCG_IRIS_IUTEST_DEFAULT_XML_GENERATOR_HPP_791DCB98_05CC_49BA_8518_0EC9CA2B5450_

namespace iutest
{

//======================================================================
// class
/**
 * @brief	xml出力イベントリスナー
*/
class DefaultXmlGeneratorListener : public EmptyTestEventListener
{
	::std::string m_output_path;
	IFile* m_fp;
public:
	/**
	 * @brief	コンストラクタ
	 * @param [in] path = 出力パス
	*/
	DefaultXmlGeneratorListener(const ::std::string& path)
		: m_fp(NULL)
	{
		SetFilePath(path);
	}
	virtual ~DefaultXmlGeneratorListener(void)
	{
		FileClose();
		TestEnv::event_listeners().set_default_xml_generator(NULL);
	}
public:
	/**
	 * @brief	出力ファイルパスの取得
	*/
	const ::std::string& GetFilePath(void) const { return m_output_path; }

private:
	/**
	 * @brief	出力ファイルの設定
	*/
	void SetFilePath(const ::std::string& path)
	{
		if( path.empty() )
		{
			m_output_path = detail::kStrings::DefaultXmlReportFileName;
		}
		else
		{
			m_output_path = path;
			const ::std::string::size_type pos = path.find('.');
			if( pos == ::std::string::npos
				|| pos == path.length()-1 )
			{
				m_output_path += detail::GetPathSeparator();
				m_output_path += detail::kStrings::DefaultXmlReportFileName;
			}
		}
	}

public:
	virtual void OnTestProgramStart(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnTestProgramEnd(const UnitTest& test) IUTEST_CXX_OVERRIDE;

private:
	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:
	bool FileOpen(const char* path);
	void FileClose(void);

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);
	}
	/**
	 * @brief	xml で使えない文字を置き換え
	*/
	static ::std::string EscapeXml(const char* str, bool is_attribute);

	/**
	 * @brief	空白かどうか
	 * @return	真偽値
	*/
	static IUTEST_CXX_CONSTEXPR bool IsWhitespace(char c)
	{
		return c == 0x9 || c == 0xA || c == 0xD;
	}
	/**
	 * @brief	xml に利用可能な文字かどうか
	 * @return	真偽値
	*/
	static IUTEST_CXX_CONSTEXPR bool IsValidXmlCharacter(char c)
	{
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
		return IsWhitespace(c) || c >= 0x20;
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
	}

public:
	
	static void SetUp(void)
	{
		::std::string xmlpath = TestEnv::get_report_xml_filepath();
		if(!xmlpath.empty())
		{
			TestEnv::event_listeners().set_default_xml_generator(new DefaultXmlGeneratorListener(xmlpath));
		}
	}
};

}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_default_xml_generator.ipp
 * @brief		output xml event listener implementation
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_DEFAULT_XML_GENERATOR_IPP_791DCB98_05CC_49BA_8518_0EC9CA2B5450_
#define INCG_IRIS_IUTEST_DEFAULT_XML_GENERATOR_IPP_791DCB98_05CC_49BA_8518_0EC9CA2B5450_

//======================================================================
// include

namespace iutest
{

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

IUTEST_IPP_INLINE void DefaultXmlGeneratorListener::OnTestProgramStart(const UnitTest& test)
{
	IUTEST_UNUSED_VAR(test);
	FileOpen(m_output_path.c_str());
}

IUTEST_IPP_INLINE void DefaultXmlGeneratorListener::OnTestProgramEnd(const UnitTest& test)
{
	if( m_fp == NULL )
	{
		FileOpen(m_output_path.c_str());
		if( m_fp == NULL )
		{
			return;
		}
	}
	OnReportTest(m_fp, test);

	FileClose();
}

IUTEST_IPP_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()
		);
#if IUTEST_HAS_REPORT_SKIPPED
	file->Printf("skip=\"%d\" ", test.reportable_skip_test_count());
#endif
	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\"");

	// propertys
	OnReportTestProperty(file, *test.ad_hoc_testresult(), 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");
}

IUTEST_IPP_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.testcase_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()
		);
#if IUTEST_HAS_REPORT_SKIPPED
	file->Printf("skip=\"%d\" ", test_case.reportable_skip_test_count() );
#endif
	file->Printf("errors=\"0\" time=\"%s\" timestamp=\"%s\""
		, detail::FormatTimeInMillisecAsSecond(test_case.elapsed_time()).c_str()
		, detail::FormatTimeInMillisecAsIso8601(test_case.start_timestamp()).c_str()
		);

	// propertys
	OnReportTestProperty(file, *test_case.ad_hoc_testresult(), 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");
}

IUTEST_IPP_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 != NULL )
		{
			OutputXmlAttribute(file, "type_param"
				, EscapeXmlAttribute(type_param).c_str() );
		}
	}
	{
		const char* value_param = test_info.value_param();
		if( value_param != NULL )
		{
			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.testcase_name_with_default_package_name()).c_str());

	// propertys
	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
	{
#if IUTEST_HAS_REPORT_SKIPPED
		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
#endif
		{
			file->Printf(" />\n");
		}
	}
}

IUTEST_IPP_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() )
		{
#if 0
			OutputXmlAttribute(file, "message"
				, EscapeXmlAttribute(part.summary()).c_str());
			::std::string message = detail::FormatCompilerIndependentFileLocation(part.file_name(), part.line_number());
			file->Printf(">\n");
			message += "\n";
			message += detail::MultiByteStringToUTF8(part.summary());
			OutputXmlCDataSection(file, message.c_str());
			file->Printf("\n      </skipped>\n");
#else
			::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");
#endif
			return;
		}
	}
	if( test_info.is_disabled_test() )
	{
		OutputXmlAttribute(file, "message", "disabled test.");
	}

	file->Printf("/>\n");
}

IUTEST_IPP_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()
				);
		}
	}
}

IUTEST_IPP_INLINE bool DefaultXmlGeneratorListener::FileOpen(const char* path)
{
	m_fp = detail::IFileSystem::New();
	if( m_fp == NULL )
	{
		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 = NULL;
		return false;
	}
	return true;
}

IUTEST_IPP_INLINE void DefaultXmlGeneratorListener::FileClose(void)
{
	if( m_fp == NULL )
	{
		return;
	}
	m_fp->Close();
	detail::IFileSystem::Free(m_fp);
	m_fp = NULL;
}

IUTEST_IPP_INLINE void DefaultXmlGeneratorListener::OutputXmlCDataSection(IFile* file, const char* data)
{
	file->Printf("<![CDATA[");
	file->Write(data, strlen(data), 1);
	file->Printf("]]>");
}
IUTEST_IPP_INLINE void DefaultXmlGeneratorListener::OutputXmlAttribute(IFile* file, const char* name, const char* value)
{
	file->Printf("%s=\"", name);
	file->Write(value, strlen(value), 1 );
	file->Printf("\" ");
}

IUTEST_IPP_INLINE ::std::string DefaultXmlGeneratorListener::EscapeXml(const char* str, bool is_attribute)
{
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
	::std::string msg;
	if( str != NULL )
	{
		for( const char* src = str; *src; ++src )
		{
			switch(*src)
			{
			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:
				{
#if !defined(IUTEST_OS_WINDOWS_MOBILE)
					wchar_t wc = 0;
					const int len = detail::iu_mbtowc(&wc, src, MB_CUR_MAX);
					if( len > 1 )
					{
						msg += detail::WideStringToUTF8(&wc, 1);
						src += len-1;
					}
					else if( IsValidXmlCharacter(*src) )
#else
					if( IsValidXmlCharacter(*src) )
#endif
					{
						if( is_attribute
							&& IsWhitespace(*src) )
						{
							char tmp[8];
							sprintf(tmp, "&#x%02X;", *src);
							msg += tmp;
						}
						else
						{
							msg += *src;
						}
					}
				}
				break;
			}
		}
	}
	return msg;
IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
}

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_DEFAULT_XML_GENERATOR_IPP_791DCB98_05CC_49BA_8518_0EC9CA2B5450_
#endif

#endif // INCG_IRIS_IUTEST_DEFAULT_XML_GENERATOR_HPP_791DCB98_05CC_49BA_8518_0EC9CA2B5450_

namespace iutest
{

//======================================================================
// class
/**
 * @brief	xml出力イベントリスナー
*/
class JunitXmlGeneratorListener : public DefaultXmlGeneratorListener
{
public:
	/**
	 * @brief	コンストラクタ
	 * @param [in] path = 出力パス
	*/
	JunitXmlGeneratorListener(const ::std::string& path)
		: DefaultXmlGeneratorListener(path)
	{
	}
	virtual ~JunitXmlGeneratorListener(void)
	{
	}
public:
	virtual void OnReportTest(IFile* file, const UnitTest& test) IUTEST_CXX_OVERRIDE;

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 void SetUp(void)
	{
		::std::string xmlpath = TestEnv::get_report_junit_xml_filepath();
		if( !xmlpath.empty() )
		{
			TestEnv::event_listeners().set_default_xml_generator(new JunitXmlGeneratorListener(xmlpath));
		}
	}
};

}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_junit_xml_generator.ipp
 * @brief		output junit xml event listener implementation
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_JUNIT_XML_GENERATOR_IPP_960DA82F_ED4B_438A_9828_D5CD034A454A_
#define INCG_IRIS_IUTEST_JUNIT_XML_GENERATOR_IPP_960DA82F_ED4B_438A_9828_D5CD034A454A_

//======================================================================
// include

namespace iutest
{

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

IUTEST_IPP_INLINE void JunitXmlGeneratorListener::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("errors=\"0\" time=\"%s\" "
		, detail::FormatTimeInMillisecAsSecond(test.elapsed_time()).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");
}

IUTEST_IPP_INLINE void JunitXmlGeneratorListener::OnReportTestCase(IFile* file, const TestCase& test_case)
{
	if( test_case.reportable_test_count() == 0 )
	{
		return;
	}

	file->Printf("  <testsuite ");
	OutputXmlAttribute(file, "name"
		, EscapeXmlAttribute(test_case.testcase_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("skipped=\"%d\" ", test_case.reportable_skip_test_count() );
	file->Printf("errors=\"0\" time=\"%s\">\n"
		, detail::FormatTimeInMillisecAsSecond(test_case.elapsed_time()).c_str()
	);

	file->Printf("    <properties>\n");

	{
		const char* type_param = test_case.type_param();
		if( type_param != NULL )
		{
			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 != NULL )
			{
				OnReportProperty(file, test_info.name(), EscapeXmlAttribute(value_param).c_str());
			}
		}
	}

	// propertys
	OnReportTestProperty(file, *test_case.ad_hoc_testresult());

	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");
}

IUTEST_IPP_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.testcase_name_with_default_package_name()).c_str());
	file->Printf(">\n");

	// propertys
	//OnReportTestProperty(file, *test_info.result());

	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");
}


IUTEST_IPP_INLINE void JunitXmlGeneratorListener::OnReportProperty(IFile* file, const char* name, const char* value)
{
	file->Printf("      <property name=\"%s\" value=\"%s\" />\n", name, value);
}

IUTEST_IPP_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()
			);
	}
}

IUTEST_IPP_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");
}

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_JUNIT_XML_GENERATOR_IPP_960DA82F_ED4B_438A_9828_D5CD034A454A_
#endif

#endif // INCG_IRIS_IUTEST_JUNIT_XML_GENERATOR_HPP_C6AD11BD_BDA4_45F3_A736_53B09DD6A7BD_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_streaming_listener.hpp
 * @brief		iris unit test stream result
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2013-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_IUTEST_STREAMING_LISTENER_HPP_1187A63F_E99B_4289_A562_3C87B9739B7D_
#define INCG_IRIS_IUTEST_IUTEST_STREAMING_LISTENER_HPP_1187A63F_E99B_4289_A562_3C87B9739B7D_

//======================================================================
// include
#if IUTEST_HAS_STREAM_RESULT
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_socket.hpp
 * @brief		iris unit test soket
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2013-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SOCKET_HPP_77654A63_0A08_43CA_950E_61232690163B_
#define INCG_IRIS_IUTEST_SOCKET_HPP_77654A63_0A08_43CA_950E_61232690163B_

//======================================================================
// include

#ifdef IUTEST_HAS_SOCKET

#ifdef IUTEST_OS_WINDOWS
#  include <winsock2.h>
#  include <ws2tcpip.h>
#else
#  include <arpa/inet.h>
#  include <netdb.h>
#endif

#if defined(_MSC_VER)
#  if defined(IUTEST_OS_WINDOWS_MOBILE)
#    pragma comment(lib, "ws2.lib")
#  else
#    pragma comment(lib, "ws2_32.lib")
#  endif
#endif

namespace iutest {
namespace detail
{

//======================================================================
// class
/**
 * @brief	ソケットベースクラス
*/
class BasicSocket
{
public:
#ifdef IUTEST_OS_WINDOWS
	typedef SOCKET descriptor_t;

#if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
	static const descriptor_t INVALID_DESCRIPTOR = INVALID_SOCKET;
#else
	enum { INVALID_DESCRIPTOR = INVALID_SOCKET };
#endif

#else
	typedef int descriptor_t;

#if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
	static const descriptor_t INVALID_DESCRIPTOR = -1;
#else
	enum { INVALID_DESCRIPTOR = -1 };
#endif

#endif
public:
	BasicSocket(void) : m_socket(INVALID_DESCRIPTOR)
	{
#ifdef IUTEST_OS_WINDOWS
		WSADATA wsaData;
		(void)WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
	}
	~BasicSocket(void)
	{
		Close();
#ifdef IUTEST_OS_WINDOWS
		WSACleanup();
#endif
	}
public:
	bool Open(const char* host, const char* port)
	{
		if( m_socket != INVALID_DESCRIPTOR )
		{
			return true;
		}
		addrinfo* servinfo = NULL;
		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 != NULL; 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, curr->ai_addrlen) != -1 )
				{
					m_socket = fd;
					break;
				}
				Close(fd);
			}
		}
		freeaddrinfo(servinfo);
		return (m_socket != INVALID_DESCRIPTOR);
	}
	void Close(void)
	{
		Close(m_socket);
		m_socket = INVALID_DESCRIPTOR;
	};
	void CheckLastError(void)
	{
#ifdef IUTEST_OS_WINDOWS
		const int le = WSAGetLastError();
		IUTEST_LOG_(WARNING) << "WSAGetLastError:" << le;
#endif
	}
public:
	static int Close(descriptor_t d)
	{
#ifdef IUTEST_OS_WINDOWS
		return closesocket(d);
#else
		return close(d);
#endif
	}

public:
	bool IsValid(void) const
	{
		return m_socket != INVALID_DESCRIPTOR;
	}
protected:
	descriptor_t m_socket;

	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(BasicSocket);
};

/**
 * @brief	ソケット書き込みクラス
*/
class SocketWriter : virtual public BasicSocket
	, public IOutStream
{
public:
	SocketWriter(void) {}
public:
	bool Send(const ::std::string& message)
	{
		return Write(message.c_str(), message.length(), 1u);
	}
	bool SendLn(const ::std::string& message)
	{
#ifdef IUTEST_OS_WINDOWS
		return Send(message + "\r\n");
#else
		return Send(message + "\r\n");
		//return Send(message + "\n");
#endif
	}
public:
	virtual bool Write(const void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
	{
		if( !IsValid() )
		{
			return false;
		}
		const int size_ = static_cast<int>(size);
		for( size_t i=0; i < cnt; ++i )
		{
#ifdef IUTEST_OS_WINDOWS
			if( send(m_socket, static_cast<const char*>(buf), size_, 0) == SOCKET_ERROR )
			{
				CheckLastError();
				return false;
			}
#else
			if( write(m_socket, buf, size_) == -1 )
			{
				return false;
			}
#endif
		}
		return true;
	}
private:
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(SocketWriter);
};

/*
 * @brief	ソケット読み込みクラス
*/
class SocketReader : virtual public BasicSocket
{
public:
	SocketReader(void) {}
public:
	bool Read(void* buf, size_t size)
	{
		if( !IsValid() )
		{
			return false;
		}
		const int size_ = static_cast<int>(size);
#ifdef IUTEST_OS_WINDOWS
		if( recv(m_socket, static_cast<char*>(buf), size_, 0) == SOCKET_ERROR )
		{
			CheckLastError();
			return false;
		}
#else
		if( read(m_socket, buf, size_) == -1 )
		{
			return false;
		}
#endif
		return true;
	}
private:
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(SocketReader);
};

/*
 * @brief	ソケット読み込みクラス
*/
class Socket : public SocketWriter, public SocketReader
{
public:
	Socket(void) {}
};

}	// end of namespace detail
}	// end of namespace iutest

#endif

#endif // INCG_IRIS_IUTEST_SOCKET_HPP_77654A63_0A08_43CA_950E_61232690163B_

namespace iutest
{

//======================================================================
// class
/**
 * @brief	stream result
*/
class StreamResultListener : public EmptyTestEventListener
{
public:
	StreamResultListener(const char* host, const char* port);

public:
	virtual void OnTestProgramStart(const UnitTest& test) IUTEST_CXX_OVERRIDE;
	virtual void OnTestIterationStart(const UnitTest& test
									, int iteration) IUTEST_CXX_OVERRIDE;
	virtual void OnTestCaseStart(const TestCase& test_case) IUTEST_CXX_OVERRIDE;
	virtual void OnTestStart(const TestInfo& test_info) IUTEST_CXX_OVERRIDE;
	virtual void OnTestPartResult(const TestPartResult& test_part_result) IUTEST_CXX_OVERRIDE;
	virtual void OnTestRecordProperty(const TestProperty& test_property) IUTEST_CXX_OVERRIDE;
	virtual void OnTestEnd(const TestInfo& test_info) IUTEST_CXX_OVERRIDE;
	virtual void OnTestCaseEnd(const TestCase& test_case) IUTEST_CXX_OVERRIDE;
	virtual void OnTestIterationEnd(const UnitTest& test
									, int iteration) IUTEST_CXX_OVERRIDE;
	virtual void OnTestProgramEnd(const UnitTest& test) IUTEST_CXX_OVERRIDE;
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;

	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(StreamResultListener);

public:
	/**
	* @brief	stream reuslt listener のセットアップ
	*/
	static TestEventListener* SetUp(void)
	{
		::std::string addr = TestEnv::get_stream_result_to();
		if( !addr.empty() )
		{
			const size_t pos = addr.find(':');
			if( pos != ::std::string::npos )
			{
				TestEventListener* p = new StreamResultListener(addr.substr(0, pos).c_str(), addr.substr(pos+1).c_str());
				UnitTest::GetInstance()->listeners().Append(p);
				return p;
			}
		}
		return NULL;
	}
};

}	// end of namespace iutest

#if !IUTEST_HAS_LIB
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_streaming_listener.ipp
 * @brief		iris unit test stream result ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2013-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_IUTEST_STREAMING_LISTENER_IPP_1187A63F_E99B_4289_A562_3C87B9739B7D_
#define INCG_IRIS_IUTEST_IUTEST_STREAMING_LISTENER_IPP_1187A63F_E99B_4289_A562_3C87B9739B7D_

//======================================================================
// include

#if IUTEST_HAS_STREAM_RESULT

namespace iutest
{

IUTEST_IPP_INLINE StreamResultListener::StreamResultListener(const char* host, const char* port)
{
	if( !m_socket.Open(host, port) )
	{
		IUTEST_LOG_(WARNING) << "StreamResultListener: failed connect to " << host << ":" << port;
	}
}

IUTEST_IPP_INLINE void StreamResultListener::OnTestProgramStart(const UnitTest& test)
{
	IUTEST_UNUSED_VAR(test);
	Start();
	SendLn("event=TestProgramStart");
}
IUTEST_IPP_INLINE void StreamResultListener::OnTestIterationStart(const UnitTest& test
								, int iteration)
{
	IUTEST_UNUSED_VAR(test);
	SendLn("event=TestIterationStart&iteration=" + StreamableToString(iteration));
}
IUTEST_IPP_INLINE void StreamResultListener::OnTestCaseStart(const TestCase& test_case)
{
	SendLn("event=TestCaseStart&name=" + StreamableToString(test_case.name()));
}
IUTEST_IPP_INLINE void StreamResultListener::OnTestStart(const TestInfo& test_info)
{
	SendLn("event=TestStart&name=" + StreamableToString(test_info.name()));
}
IUTEST_IPP_INLINE void StreamResultListener::OnTestPartResult(const TestPartResult& test_part_result)
{
	const char* filename = test_part_result.file_name();
	if( filename == NULL )
	{
		filename = "";
	}
	SendLn("event=TestPartResult&file=" + UrlEncode(filename)
		+ "&line=" + StreamableToString(test_part_result.line_number())
		+ "&message=" + UrlEncode(test_part_result.message()));
}
IUTEST_IPP_INLINE void StreamResultListener::OnTestRecordProperty(const TestProperty& test_property)
{
	SendLn("event=TestRecordProperty&name=" + UrlEncode(test_property.key())
		+ "&value=" + UrlEncode(test_property.value()));
}
IUTEST_IPP_INLINE void StreamResultListener::OnTestEnd(const TestInfo& test_info)
{
	SendLn("event=TestEnd&passed="
		+ FormatBool(test_info.Passed())
		+ "&elapsed_time=" + StreamableToString(test_info.elapsed_time()) + "ms"
		);
}
IUTEST_IPP_INLINE void StreamResultListener::OnTestCaseEnd(const TestCase& test_case)
{
	SendLn("event=TestCaseEnd&passed="
		+ FormatBool(test_case.Passed())
		+ "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + "ms"
		);
}
IUTEST_IPP_INLINE void StreamResultListener::OnTestIterationEnd(const UnitTest& test
								, int iteration)
{
	IUTEST_UNUSED_VAR(iteration);
	SendLn("event=TestIterationEnd&passed="
		+ FormatBool(test.Passed())
		+ "&elapsed_time=" + StreamableToString(test.elapsed_time()) + "ms"
		);
}
IUTEST_IPP_INLINE void StreamResultListener::OnTestProgramEnd(const UnitTest& test)
{
	SendLn("event=TestProgramEnd&passd=" + FormatBool(test.Passed()));
	m_socket.Close();
}

IUTEST_IPP_INLINE ::std::string StreamResultListener::UrlEncode(const char* str)
{
	::std::string result;
	if( str != NULL )
	{
		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;
}

IUTEST_IPP_INLINE ::std::string StreamResultListener::FormatBool(bool b)
{
	return b ? "1" : "0";
}

IUTEST_IPP_INLINE void StreamResultListener::Start()
{
	SendLn("iutest_streaming_protocol_version=1.0");
}

IUTEST_IPP_INLINE void StreamResultListener::SendLn(const ::std::string& message)
{
	m_socket.SendLn(message);
}

}	// end of namespace iutest

#endif // #if IUTEST_HAS_STREAM_RESULT

#endif // INCG_IRIS_IUTEST_IUTEST_STREAMING_LISTENER_IPP_1187A63F_E99B_4289_A562_3C87B9739B7D_
#endif

#endif

#endif // INCG_IRIS_IUTEST_IUTEST_STREAMING_LISTENER_HPP_1187A63F_E99B_4289_A562_3C87B9739B7D_

#if defined(__AFX_H__)
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_mfc.hpp
 * @brief		MFC support
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_MFC_HPP_43CC925C_BED2_4D9D_8502_78204B69B675_
#define INCG_IRIS_IUTEST_MFC_HPP_43CC925C_BED2_4D9D_8502_78204B69B675_

//======================================================================
// include
#include <iterator>

namespace iutest {
namespace mfc
{

template<typename T, typename U>
class mfc_iterator : public ::std::iterator < ::std::input_iterator_tag, U >
{
	typedef typename iutest_type_traits::add_const_to_pointer<U>::type Item;
public:
	mfc_iterator(const T& container, POSITION pos) : m_container(container), m_pos(pos) {}
	mfc_iterator(const mfc_iterator& rhs) : m_container(rhs.m_container), m_pos(rhs.m_pos) {}
	
	mfc_iterator& operator ++ ()    { advance(); return *this; }
	mfc_iterator& operator ++ (int) { mfc_iterator r(*this); advance(); return r; }

	Item operator *  () const { return m_container.GetAt(m_pos); }
	Item operator -> () const { return m_container.GetAt(m_pos); }

	bool operator == (mfc_iterator& rhs) { return rhs.m_pos == m_pos; }
	bool operator != (mfc_iterator& rhs) { return rhs.m_pos != m_pos; }
private:
	void advance()
	{
		__if_exists(T::GetNext) {
			m_container.GetNext(m_pos);
		}
		__if_not_exists(T::GetNext) {
			m_pos++;
		}
	}
private:
	const T& m_container;
	POSITION m_pos;
};

template<typename T, typename Key, typename Value>
class mfc_map_iterator : public ::std::iterator < ::std::input_iterator_tag, ::std::pair<Key, Value> >
{
	typedef ::std::pair<Key, Value> Item;
public:
	mfc_map_iterator(const T& container, POSITION pos) : m_container(container), m_pos(pos) {}
	mfc_map_iterator(const mfc_map_iterator& rhs) : m_container(rhs.m_container), m_pos(rhs.m_pos) {}

	mfc_map_iterator& operator ++ ()    { advance(); return *this; }
	mfc_map_iterator& operator ++ (int) { mfc_iterator r(*this); advance(); return r; }

	Item operator *  () const { return m_pair; }
	Item operator -> () const { return m_pair; }

	bool operator == (mfc_map_iterator& rhs) { return rhs.m_pos == m_pos; }
	bool operator != (mfc_map_iterator& rhs) { return rhs.m_pos != m_pos; }
private:
	void advance()
	{
		__if_exists(T::GetNextAssoc) {
			m_container.GetNextAssoc(m_pos, m_pair.first, m_pair.second);
		}
	}

private:
	const T& m_container;
	POSITION m_pos;
	::std::pair<Key, Value> m_pair;
};

template<typename T, typename U>
mfc_iterator<CList<T, U>, T> begin(CList<T, U>& list)
{
	return mfc_iterator<CList<T, U>, T>(list, list.GetHeadPosition());
}
template<typename T, typename U>
mfc_iterator<CList<T, U>, T> end(CList<T, U>& list)
{
	return mfc_iterator<CList<T, U>, T>(list, NULL);
}

template<typename T, typename U>
T* begin(CArray<T, U>& ar)
{
	return ar.GetData();
}
template<typename T, typename U>
T* end(CArray<T, U>& ar)
{
	return ar.GetData() + ar.GetCount();
}

template<typename T, typename TA, typename U, typename UA>
mfc_map_iterator< CMap<T, TA, U, UA>, T, U > begin(CMap<T, TA, U, UA>& map)
{
	return mfc_map_iterator< CMap<T, TA, U, UA>, T, U >(map, map.GetStartPosition());
}

template<typename T, typename TA, typename U, typename UA>
mfc_map_iterator< CMap<T, TA, U, UA>, T, U > end(CMap<T, TA, U, UA>& map)
{
	return mfc_map_iterator< CMap<T, TA, U, UA>, T, U >(map, NULL);
}

namespace peep
{

template<typename T>
struct base_type : public T
{ 
	__if_exists(T::BASE_TYPE)
	{
		using T::BASE_TYPE;
		typedef typename T::BASE_TYPE BASE_KEY;
		typedef typename T::BASE_TYPE BASE_VALUE;
	}

	__if_not_exists(T::BASE_TYPE)
	{
		__if_exists(T::BASE_KEY)
		{
			__if_exists(T::BASE_VALUE)
			{
				using T::BASE_KEY;
				using T::BASE_VALUE;
				typedef ::std::pair<T::BASE_KEY, T::BASE_VALUE> BASE_TYPE;
			}
		}
	}
};
template<typename T, typename U>
struct base_type< CArray<T, U> >
{
	typedef T BASE_TYPE;
	typedef T BASE_KEY;
	typedef T BASE_VALUE;
};
template<typename BASE_CLASS, typename T>
struct base_type< CTypedPtrArray<BASE_CLASS, T> >
{
	typedef T BASE_TYPE;
	typedef T BASE_KEY;
	typedef T BASE_VALUE;
};
template<typename T, typename U>
struct base_type< CList<T, U> >
{
	typedef T BASE_TYPE;
	typedef T BASE_KEY;
	typedef T BASE_VALUE;
};
template<typename BASE_CLASS, typename T>
struct base_type< CTypedPtrList<BASE_CLASS, T> >
{
	typedef T BASE_TYPE;
	typedef T BASE_KEY;
	typedef T BASE_VALUE;
};
template<typename T, typename TA, typename U, typename UA>
struct base_type< CMap<T, TA, U, UA> >
{
	typedef ::std::pair<T, U> BASE_TYPE;
	typedef T BASE_KEY;
	typedef U BASE_VALUE;
};
template<typename BASE_CLASS, typename KEY, typename VALUE>
struct base_type< CTypedPtrMap<BASE_CLASS, KEY, VALUE> >
{
	typedef ::std::pair<KEY, VALUE> BASE_TYPE;
	typedef KEY BASE_KEY;
	typedef VALUE BASE_VALUE;
};

}

template<typename T>
struct mfc_iterator_traits
{
	typedef typename peep::base_type<T>::BASE_TYPE BASE_TYPE;
	typedef typename peep::base_type<T>::BASE_KEY BASE_KEY;
	typedef typename peep::base_type<T>::BASE_VALUE BASE_VALUE;
	template<typename U, bool isArray, bool isList>
	struct type_select
	{
		typedef mfc_map_iterator<T, BASE_KEY, BASE_VALUE> type;
	};
	template<typename U>
	struct type_select<U, true, false>
	{
		typedef U* type;
	};
	template<typename U>
	struct type_select<U, false, true>
	{
		typedef mfc_iterator<T, U> type;
	};
	typedef typename type_select<BASE_TYPE
		, IUTEST_STATIC_EXISTS(T::GetData)
		, IUTEST_STATIC_EXISTS(T::GetHeadPosition)
	>::type type;
};

template<typename T>
typename peep::base_type<T>::BASE_TYPE* begin(T& ar
	, typename detail::enable_if< IUTEST_STATIC_EXISTS(T::GetData), void>::type*& = detail::enabler::value)
{
	return reinterpret_cast<typename peep::base_type<T>::BASE_TYPE*>(ar.GetData());
}
template<typename T>
typename peep::base_type<T>::BASE_TYPE* end(T& ar
	, typename detail::enable_if< IUTEST_STATIC_EXISTS(T::GetData), void>::type*& = detail::enabler::value)
{
	return reinterpret_cast<typename peep::base_type<T>::BASE_TYPE*>(ar.GetData() + ar.GetCount());
}

template<typename T>
mfc_iterator<T, typename peep::base_type<T>::BASE_TYPE> begin(T& list
	, typename detail::enable_if< IUTEST_STATIC_EXISTS(T::GetHeadPosition), void>::type*& = detail::enabler::value)
{
	return mfc_iterator<T, peep::base_type<T>::BASE_TYPE>(list, list.GetHeadPosition());
}
template<typename T>
mfc_iterator<T, typename peep::base_type<T>::BASE_TYPE> end(T& list
	, typename detail::enable_if< IUTEST_STATIC_EXISTS(T::GetHeadPosition), void>::type*& = detail::enabler::value)
{
	return mfc_iterator<T, peep::base_type<T>::BASE_TYPE>(list, NULL);
}

template<typename T>
typename mfc_iterator_traits<T>::type begin(T& map
	, typename detail::enable_if< IUTEST_STATIC_EXISTS(T::GetStartPosition), void>::type*& = detail::enabler::value)
{
	return typename mfc_iterator_traits<T>::type(map, map.GetStartPosition());
}
template<typename T>
typename mfc_iterator_traits<T>::type end(T& map
	, typename detail::enable_if< IUTEST_STATIC_EXISTS(T::GetStartPosition), void>::type*& = detail::enabler::value)
{
	return typename mfc_iterator_traits<T>::type(map, NULL);
}

template<typename T>
class CContainer
{
public:
	typedef typename peep::base_type<T>::BASE_TYPE BASE_TYPE;
	typedef typename peep::base_type<T>::BASE_KEY BASE_KEY;
	typedef typename peep::base_type<T>::BASE_VALUE BASE_VALUE;
	typedef typename mfc_iterator_traits<T>::type iterator_type;
public:
	CContainer(T& container) : m_container(container) {}

	iterator_type begin() const { return mfc::begin(m_container); }
	iterator_type end() const { return mfc::end(m_container); }

private:
	T& m_container;
};

template<typename T>
CContainer<T> make_container(T& obj) { return CContainer<T>(obj); }

}	// end of namespace mfc
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_MFC_HPP_43CC925C_BED2_4D9D_8502_78204B69B675_
#endif

//======================================================================
// define
/**
 * @defgroup	TESTDEF		テスト定義マクロ
 * @brief		テスト定義マクロ
*/

/**
 * @ingroup	TESTDEF
 * @def		IUTEST_TEST(testcase_, testname_)
 * @brief	テスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
*/
#define IUTEST_TEST(testcase_, testname_)			IUTEST_TEST_STRICT_(testcase_, testname_, ::iutest::Test	\
														, ::iutest::internal::GetTestTypeId())

/**
 * @ingroup	TESTDEF
 * @def		IUTEST(testcase_, testname_)
 * @brief	テスト関数定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
*/
#define IUTEST(testcase_, testname_)				IUTEST_TEST(testcase_, testname_)

/**
 * @ingroup	TESTDEF
 * @def		IUTEST_F(testfixture_, testname_)
 * @brief	ユーザー指定テスト関数定義マクロ
 * @param	testfixture_	= テストフィクスチャ名
 * @param	testname_		= テスト名
*/
#define IUTEST_F(testfixture_, testname_)			IUTEST_TEST_F_(testfixture_, testname_)

#if IUTEST_HAS_PARAM_METHOD_TEST
/**
 * @ingroup	VALUE_PARAMETERIZED_TEST
 * @def		IUTEST_PMZ(testcase_, testname_, method_, ...)
 * @brief	パラメタライズ関数コールテスト定義マクロ
 * @param	testcase_	= テストケース名
 * @param	testname_	= テスト名
 * @param	method_		= 関数
*/
#define IUTEST_PMZ(testcase_, testname_, method_, ...)	IIUT_TEST_PMZ_(testcase_, testname_, method_, ::iutest::Test	\
														, ::iutest::internal::GetTestTypeId(), __VA_ARGS__)

/**
 * @ingroup	VALUE_PARAMETERIZED_TEST
 * @def		IUTEST_PMZ_F(testfixture_, testname_, method_, ...)
 * @brief	パラメタライズ関数コールテスト定義マクロ
 * @param	testfixture_	= テストフィクスチャ名
 * @param	testname_		= テスト名
 * @param	method_			= 関数
*/
#define IUTEST_PMZ_F(testfixture_, testname_, method_, ...)	IIUT_TEST_PMZ_(testfixture_, testname_, method_, testfixture_	\
														, ::iutest::internal::GetTypeId< testfixture_ >(), __VA_ARGS__)

#endif

#if IUTEST_HAS_TESTNAME_ALIAS

/**
 * @ingroup	TESTDEF
 * @brief	テストの別名
 * @param	testname_		= テスト名
*/
#define IUTEST_ALIAS_TESTNAME(testname_)					IUTEST_ALIAS_TESTNAME_(testname_)

/**
 * @ingroup	TESTDEF
 * @brief	テストフィクスチャ用テストの別名
 * @param	testfixture_	= テストフィクスチャ名
 * @param	testname_		= テスト名
*/
#define IUTEST_ALIAS_TESTNAME_F(testfixture_, testname_)	IUTEST_ALIAS_TESTNAME_F_(testfixture_, testname_)

#if IUTEST_HAS_TESTNAME_ALIAS_JP

/**
 * @ingroup	TESTDEF
 * @brief	日本語テスト名
 * @param	testname_		= テスト名
*/
#define IUTEST_JAPANESE_NAME(testname_)						IUTEST_ALIAS_TESTNAME(testname_)

/**
 * @ingroup	TESTDEF
 * @brief	テストフィクスチャ用日本語テスト名
 * @param	testfixture_	= テストフィクスチャ名
 * @param	testname_		= テスト名
*/
#define IUTEST_JAPANESE_NAME_F(testfixture_, testname_)		IUTEST_ALIAS_TESTNAME_F(testfixture_, testname_)

#endif

#endif

/**
 * @ingroup	TESTDEF
 * @brief	iutest の初期化処理
 * @param	argc_	= コマンドライン引数の総数
 * @param	argv_	= コマンドライン引数
*/
#define IUTEST_INIT(argc_, argv_)					::iutest::InitIrisUnitTest(argc_, argv_)

/**
 * @ingroup	TESTDEF
 * @brief	すべてのテストを実行する
*/
#define IUTEST_RUN_ALL_TESTS()						::iutest::UnitTestSource::GetInstance().Run()


/**
 * @defgroup	IUTEST_UTIL		テスト記述補助
 * @brief		テスト記述補助マクロ
*/

/**
 * @ingroup		IUTEST_UTIL
 * @brief		スコープ内のテストメッセージへのメッセージ追加
 * @param		msg	= メッセージ
*/
#define IUTEST_SCOPED_TRACE(msg)					IIUT_SCOPED_MESSAGE(msg)

/**
 * @ingroup		IUTEST_UTIL
 * @brief		明示的な成功
 * @details		明示的に成功を報告します
*/
#ifndef IUTEST_SUCCEED
#  define IUTEST_SUCCEED()							IIUT_SUCCEED()
#endif

/**
 * @ingroup		IUTEST_UTIL
 * @brief		明示的な失敗
 * @details		明示的に致命的な失敗を報告します
*/
#ifndef IUTEST_FAIL
#  define IUTEST_FAIL()								IIUT_FAIL()
#endif

/**
 * @ingroup		IUTEST_UTIL
 * @brief		明示的な失敗
 * @details		明示的に致命的でない失敗を報告します
*/
#ifndef IUTEST_ADD_FAILURE
#  define IUTEST_ADD_FAILURE()						IIUT_ADD_FAILURE()
#endif

/**
 * @ingroup		IUTEST_UTIL
 * @brief		明示的な失敗
 * @details		明示的に致命的でない失敗を報告します
 * @param		file	= ファイルパス
 * @param		line	= 行番号
*/
#ifndef IUTEST_ADD_FAILURE_AT
#  define IUTEST_ADD_FAILURE_AT(file, line)			IIUT_ADD_FAILURE_AT(file, line)
#endif

/**
 * @ingroup		IUTEST_UTIL
 * @brief		テストの明示的なスキップ
 * @details		明示的にスキップを報告します
*/
#ifndef IUTEST_SKIP
#  define IUTEST_SKIP()								IUTEST_TEST_SKIP()
#endif

/**
 * @defgroup	IUTEST_ASSERTION_	アサーション
*/

/**
 * @ingroup		IUTEST_ASSERTION_
 * @{
*/

/**
 * @defgroup	IUTEST_ASSERT_	ASSERT
 * @brief		致命的エラーフレーバー
 * @details		失敗した場合、その時点でテストから抜けます。
*/

/**
 * @}
*/

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	式アサーション
 * @param	expression	= 式
*/
#ifndef IUTEST_ASSERT
#  define	IUTEST_ASSERT(expression)				IUTEST_TEST_EXPRESSION_(expression, true, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	式アサーション
 * @param	expression	= 式
*/
#ifndef IUTEST_ASSERT_NOT
#  define	IUTEST_ASSERT_NOT(expression)			IUTEST_TEST_EXPRESSION_(expression, false, IUTEST_ASSERT_FAILURE)
#endif

#if IUTEST_HAS_MATCHERS
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	matcher テスト
 * @param	actual	= 検査対象
 * @param	matcher	= matcher
*/
#ifndef IUTEST_ASSERT_THAT
#  define IUTEST_ASSERT_THAT(actual, matcher)		IUTEST_TEST_THAT(actual, matcher, IUTEST_ASSERT_FAILURE)
#endif

#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	== テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSERT_EQ
#  define	IUTEST_ASSERT_EQ(expected, actual)		IUTEST_TEST_EQ(expected, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	!= テスト
 * @details	v1 と v2 が等しくないことを検証します
*/
#ifndef IUTEST_ASSERT_NE
#  define	IUTEST_ASSERT_NE(v1, v2)				IUTEST_TEST_NE(v1, v2, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	<= テスト
 * @details	v1 <= v2 が成り立つことを検証します
*/
#ifndef IUTEST_ASSERT_LE
#  define	IUTEST_ASSERT_LE(v1, v2)				IUTEST_TEST_LE(v1, v2, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	< テスト
 * @details	v1 < v2 が成り立つことを検証します
*/
#ifndef IUTEST_ASSERT_LT
#  define	IUTEST_ASSERT_LT(v1, v2)				IUTEST_TEST_LT(v1, v2, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	>= テスト
 * @details	v1 >= v2 が成り立つことを検証します
*/
#ifndef IUTEST_ASSERT_GE
#  define	IUTEST_ASSERT_GE(v1, v2)				IUTEST_TEST_GE(v1, v2, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	\> テスト
 * @details	v1 > v2 が成り立つことを検証します
*/
#ifndef IUTEST_ASSERT_GT
#  define	IUTEST_ASSERT_GT(v1, v2)				IUTEST_TEST_GT(v1, v2, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	TRUE テスト
 * @details	v が真であることを検証します
*/
#ifndef IUTEST_ASSERT_TRUE
#  ifndef IUTEST_NO_VARIADIC_MACROS
#    define	IUTEST_ASSERT_TRUE(...)					IUTEST_TEST_TRUE((__VA_ARGS__), #__VA_ARGS__, IUTEST_ASSERT_FAILURE)
#  else
#    define	IUTEST_ASSERT_TRUE(v)					IUTEST_TEST_TRUE(v, #v, IUTEST_ASSERT_FAILURE)
#  endif
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	FALSE テスト
 * @details	v が偽であることを検証します
*/
#ifndef IUTEST_ASSERT_FALSE
#  ifndef IUTEST_NO_VARIADIC_MACROS
#    define	IUTEST_ASSERT_FALSE(...)				IUTEST_TEST_FALSE((__VA_ARGS__), #__VA_ARGS__, IUTEST_ASSERT_FAILURE)
#  else
#    define	IUTEST_ASSERT_FALSE(v)					IUTEST_TEST_FALSE(v, #v, IUTEST_ASSERT_FAILURE)
#  endif
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	NULL テスト
 * @details	v が NULL であることを検証します
*/
#ifndef IUTEST_ASSERT_NULL
#  define	IUTEST_ASSERT_NULL(v)					IUTEST_TEST_NULL(v, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	NOT NULL テスト
 * @details	v が NULL でないことを検証します
*/
#ifndef IUTEST_ASSERT_NOTNULL
#  define	IUTEST_ASSERT_NOTNULL(v)				IUTEST_TEST_NOTNULL(v, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	アドレス一致 テスト
 * @details	v1 と v2 のアドレスが同じであることを検証します
*/
#ifndef IUTEST_ASSERT_SAME
#  define	IUTEST_ASSERT_SAME(v1, v2)				IUTEST_TEST_SAME(v1, v2, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	float の比較 テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSERT_FLOAT_EQ
#  define	IUTEST_ASSERT_FLOAT_EQ(expected, actual)	IUTEST_TEST_FLOAT_EQ(expected, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	double の比較 テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSERT_DOUBLE_EQ
#  define	IUTEST_ASSERT_DOUBLE_EQ(expected, actual)	IUTEST_TEST_DOUBLE_EQ(expected, actual, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	２値の差の範囲 テスト
 * @param	v1		= 値1
 * @param	v2		= 値2
 * @param	abs_v	= v1 と v2 の差分の期待値
*/
#ifndef IUTEST_ASSERT_NEAR
#  define	IUTEST_ASSERT_NEAR(v1, v2, abs_v)		IUTEST_TEST_NEAR(v1, v2, abs_v, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列の一致 テスト
 * @param	expected_str	= 期待値
 * @param	actual_str		= 検査対象
*/
#ifndef IUTEST_ASSERT_STREQ
#  define	IUTEST_ASSERT_STREQ(expected_str, actual_str)	IUTEST_TEST_STREQ(expected_str, actual_str, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列の不一致 テスト
 * @details	v1 と v2 文字列が異なることを検証します
*/
#ifndef IUTEST_ASSERT_STRNE
#  define	IUTEST_ASSERT_STRNE(v1, v2)				IUTEST_TEST_STRNE(v1, v2, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列の一致（大文字小文字区別なし） テスト
 * @param	expected_str	= 期待値
 * @param	actual_str		= 検査対象
*/
#ifndef IUTEST_ASSERT_STRCASEEQ
#  define	IUTEST_ASSERT_STRCASEEQ(expected_str, actual_str)	IUTEST_TEST_STRCASEEQ(expected_str, actual_str, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列の不一致（大文字小文字区別なし） テスト
 * @details	v1 と v2 文字列が異なることを検証します（大文字小文字区別なし）
*/
#ifndef IUTEST_ASSERT_STRCASENE
#  define	IUTEST_ASSERT_STRCASENE(v1, v2)			IUTEST_TEST_STRCASENE(v1, v2, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	HRESULT の成功 テスト
 * @details	HRESULT が成功であることを検証します
*/
#ifndef IUTEST_ASSERT_HRESULT_SUCCEEDED
#  define IUTEST_ASSERT_HRESULT_SUCCEEDED(hr)		IUTEST_TEST_HRESULT_SUCCEEDED(hr, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	HRESULT の失敗 テスト
 * @details	HRESULT が失敗であることを検証します
*/
#ifndef IUTEST_ASSERT_HRESULT_FAILED
#  define IUTEST_ASSERT_HRESULT_FAILED(hr)			IUTEST_TEST_HRESULT_FAILED(hr, IUTEST_ASSERT_FAILURE)
#endif

#if IUTEST_HAS_EXCEPTIONS

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	throw テスト
 * @details	statement が expected_exception を throw することを検証します
 * @param	statement	= ステートメント
 * @param	expected_exception = 期待する例外
*/
#ifndef IUTEST_ASSERT_THROW
#  define IUTEST_ASSERT_THROW(statement, expected_exception)	\
													IUTEST_TEST_THROW_(statement, expected_exception, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	throw value == テスト
 * @details	statement が expected_exception を throw し、その値が expected_value と等しいことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_value		= 期待値
*/
#ifndef IUTEST_ASSERT_THROW_VALUE_EQ
#  define IUTEST_ASSERT_THROW_VALUE_EQ(statement, expected_exception, expected_value)	\
													IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_value, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	throw value != テスト
 * @details	statement が expected_exception を throw し、その値が v と等しくないことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	v					= 値
*/
#ifndef IUTEST_ASSERT_THROW_VALUE_NE
#  define IUTEST_ASSERT_THROW_VALUE_NE(statement, expected_exception, v)	\
													IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, v, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	throw value 文字列一致 テスト
 * @details	statement が expected_exception を throw し、その文字列が expected_str と等しいことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_str		= 期待文字列
*/
#ifndef IUTEST_ASSERT_THROW_VALUE_STREQ
#  define IUTEST_ASSERT_THROW_VALUE_STREQ(statement, expected_exception, expected_str)	\
													IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_str, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	throw value 文字列一致（大文字小文字区別なし） テスト
 * @details	statement が expected_exception を throw し、その文字列が expected_str と等しいことを検証します（大文字小文字区別なし）
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_str		= 期待文字列
*/
#ifndef IUTEST_ASSERT_THROW_VALUE_STRCASEEQ
#  define IUTEST_ASSERT_THROW_VALUE_STRCASEEQ(statement, expected_exception, expected_str)	\
													IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_str, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	any throw テスト
 * @details	statement が何らかの例外を投げることを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_ASSERT_ANY_THROW
#  define IUTEST_ASSERT_ANY_THROW(statement)		IUTEST_TEST_ANY_THROW_(statement, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	no throw テスト
 * @details	statement が例外を投げないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_ASSERT_NO_THROW
#  define IUTEST_ASSERT_NO_THROW(statement)			IUTEST_TEST_NO_THROW_(statement, IUTEST_ASSERT_FAILURE)
#endif

#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	no new failure テスト
 * @details	statement で失敗がないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_ASSERT_NO_FAILURE
#  define IUTEST_ASSERT_NO_FAILURE(statement)		IUTEST_TEST_NO_FAILURE_(statement, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	no new fatal failure テスト
 * @details	statement で致命的な失敗がないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_ASSERT_NO_FATAL_FAILURE
#  define IUTEST_ASSERT_NO_FATAL_FAILURE(statement)	IUTEST_TEST_NO_FATAL_FAILURE_(statement, IUTEST_ASSERT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	明示的な失敗
 * @details		明示的に致命的な失敗を報告します
*/
#ifndef IUTEST_ASSERT_FAIL
#  define IUTEST_ASSERT_FAIL()						IIUT_FAIL()
#endif

/**
 * @ingroup		IUTEST_ASSERTION_
 * @{
*/

/**
 * @defgroup	IUTEST_EXPECT_	EXPECT
 * @brief		致命的ではないエラーフレーバー
 * @details		失敗した場合でも、テストを続行します。
*/

/**
 * @}
*/

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	式アサーション
 * @param	expression	= 式
*/
#ifndef IUTEST_EXPECT
#  define	IUTEST_EXPECT(expression)				IUTEST_TEST_EXPRESSION_(expression, true, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	式アサーション
 * @param	expression	= 式
*/
#ifndef IUTEST_EXPECT_NOT
#  define	IUTEST_EXPECT_NOT(expression)			IUTEST_TEST_EXPRESSION_(expression, false, IUTEST_EXPECT_FAILURE)
#endif

#if IUTEST_HAS_MATCHERS
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	matcher テスト
 * @param	actual	= 検査対象
 * @param	matcher	= matcher
*/
#ifndef IUTEST_EXPECT_THAT
#  define IUTEST_EXPECT_THAT(actual, matcher)		IUTEST_TEST_THAT(actual, matcher, IUTEST_EXPECT_FAILURE)
#endif

#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	== テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_EXPECT_EQ
#  define	IUTEST_EXPECT_EQ(expected, actual)		IUTEST_TEST_EQ(expected, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	!= テスト
 * @details	v1 と v2 が等しくないことを検証します
*/
#ifndef IUTEST_EXPECT_NE
#  define	IUTEST_EXPECT_NE(v1, v2)				IUTEST_TEST_NE(v1, v2, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	<= テスト
 * @details	v1 <= v2 が成り立つことを検証します
*/
#ifndef IUTEST_EXPECT_LE
#  define	IUTEST_EXPECT_LE(v1, v2)				IUTEST_TEST_LE(v1, v2, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	< テスト
 * @details	v1 < v2 が成り立つことを検証します
*/
#ifndef IUTEST_EXPECT_LT
#  define	IUTEST_EXPECT_LT(v1, v2)				IUTEST_TEST_LT(v1, v2, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	>= テスト
 * @details	v1 >= v2 が成り立つことを検証します
*/
#ifndef IUTEST_EXPECT_GE
#  define	IUTEST_EXPECT_GE(v1, v2)				IUTEST_TEST_GE(v1, v2, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	\> テスト
 * @details	v1 > v2 が成り立つことを検証します
*/
#ifndef IUTEST_EXPECT_GT
#  define	IUTEST_EXPECT_GT(v1, v2)				IUTEST_TEST_GT(v1, v2, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	TRUE テスト
 * @details	v が真であることを検証します
*/
#ifndef IUTEST_EXPECT_TRUE
#  ifndef IUTEST_NO_VARIADIC_MACROS
#    define	IUTEST_EXPECT_TRUE(...)					IUTEST_TEST_TRUE((__VA_ARGS__), #__VA_ARGS__, IUTEST_EXPECT_FAILURE)
#  else
#    define	IUTEST_EXPECT_TRUE(v)					IUTEST_TEST_TRUE(v, #v, IUTEST_EXPECT_FAILURE)
#  endif
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	FALSE テスト
 * @details	v が偽であることを検証します
*/
#ifndef IUTEST_EXPECT_FALSE
#  ifndef IUTEST_NO_VARIADIC_MACROS
#    define	IUTEST_EXPECT_FALSE(...)				IUTEST_TEST_FALSE((__VA_ARGS__), #__VA_ARGS__, IUTEST_EXPECT_FAILURE)
#  else
#    define	IUTEST_EXPECT_FALSE(v)					IUTEST_TEST_FALSE(v, #v, IUTEST_EXPECT_FAILURE)
#  endif
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	NULL テスト
 * @details	v が NULL であることを検証します
*/
#ifndef IUTEST_EXPECT_NULL
#  define	IUTEST_EXPECT_NULL(v)					IUTEST_TEST_NULL(v, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	NOT NULL テスト
 * @details	v が NULL でないことを検証します
*/
#ifndef IUTEST_EXPECT_NOTNULL
#  define	IUTEST_EXPECT_NOTNULL(v)				IUTEST_TEST_NOTNULL(v, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	アドレス一致 テスト
 * @details	v1 と v2 のアドレスが同じであることを検証します
*/
#ifndef IUTEST_EXPECT_SAME
#  define	IUTEST_EXPECT_SAME(v1, v2)				IUTEST_TEST_SAME(v1, v2, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	float の比較 テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_EXPECT_FLOAT_EQ
#  define	IUTEST_EXPECT_FLOAT_EQ(expected, actual)	IUTEST_TEST_FLOAT_EQ(expected, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	double の比較 テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_EXPECT_DOUBLE_EQ
#  define	IUTEST_EXPECT_DOUBLE_EQ(expected, actual)	IUTEST_TEST_DOUBLE_EQ(expected, actual, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	２値の差の範囲 テスト
 * @param	v1		= 値1
 * @param	v2		= 値2
 * @param	abs_v	= v1 と v2 の差分の期待値
*/
#ifndef IUTEST_EXPECT_NEAR
#  define	IUTEST_EXPECT_NEAR(v1, v2, abs_v)		IUTEST_TEST_NEAR(v1, v2, abs_v, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列の一致 テスト
 * @param	expected_str	= 期待値
 * @param	actual_str		= 検査対象
*/
#ifndef IUTEST_EXPECT_STREQ
#  define	IUTEST_EXPECT_STREQ(expected_str, actual_str)	IUTEST_TEST_STREQ(expected_str, actual_str, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列の不一致 テスト
 * @details	v1 と v2 文字列が異なることを検証します
*/
#ifndef IUTEST_EXPECT_STRNE
#  define	IUTEST_EXPECT_STRNE(v1, v2)				IUTEST_TEST_STRNE(v1, v2, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列の一致（大文字小文字区別なし） テスト
 * @param	expected_str	= 期待値
 * @param	actual_str		= 検査対象
*/
#ifndef IUTEST_EXPECT_STRCASEEQ
#  define	IUTEST_EXPECT_STRCASEEQ(expected_str, actual_str)	IUTEST_TEST_STRCASEEQ(expected_str, actual_str, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列の不一致（大文字小文字区別なし） テスト
 * @details	v1 と v2 文字列が異なることを検証します（大文字小文字区別なし）
*/
#ifndef IUTEST_EXPECT_STRCASENE
#  define	IUTEST_EXPECT_STRCASENE(v1, v2)			IUTEST_TEST_STRCASENE(v1, v2, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	HRESULT の成功 テスト
 * @details	HRESULT が成功であることを検証します
*/
#ifndef IUTEST_EXPECT_HRESULT_SUCCEEDED
#  define IUTEST_EXPECT_HRESULT_SUCCEEDED(hr)		IUTEST_TEST_HRESULT_SUCCEEDED(hr, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	HRESULT の失敗 テスト
 * @details	HRESULT が失敗であることを検証します
*/
#ifndef IUTEST_EXPECT_HRESULT_FAILED
#  define IUTEST_EXPECT_HRESULT_FAILED(hr)			IUTEST_TEST_HRESULT_FAILED(hr, IUTEST_EXPECT_FAILURE)
#endif

#if IUTEST_HAS_EXCEPTIONS

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	throw テスト
 * @details	statement が expected_exception を throw することを検証します
 * @param	statement	= ステートメント
 * @param	expected_exception = 期待する例外
*/
#ifndef IUTEST_EXPECT_THROW
#  define IUTEST_EXPECT_THROW(statement, expected_exception)	\
													IUTEST_TEST_THROW_(statement, expected_exception, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	throw value == テスト
 * @details	statement が expected_exception を throw し、その値が expected_value と等しいことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_value		= 期待値
*/
#ifndef IUTEST_EXPECT_THROW_VALUE_EQ
#  define IUTEST_EXPECT_THROW_VALUE_EQ(statement, expected_exception, expected_value)	\
													IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_value, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	throw value != テスト
 * @details	statement が expected_exception を throw し、その値が v と等しくないことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	v					= 値
*/
#ifndef IUTEST_EXPECT_THROW_VALUE_NE
#  define IUTEST_EXPECT_THROW_VALUE_NE(statement, expected_exception, v)	\
													IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, v, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	throw value 文字列一致 テスト
 * @details	statement が expected_exception を throw し、その文字列が expected_str と等しいことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_str		= 期待文字列
*/
#ifndef IUTEST_EXPECT_THROW_VALUE_STREQ
#  define IUTEST_EXPECT_THROW_VALUE_STREQ(statement, expected_exception, expected_str)	\
													IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_str, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	throw value 文字列一致（大文字小文字区別なし） テスト
 * @details	statement が expected_exception を throw し、その文字列が expected_str と等しいことを検証します（大文字小文字区別なし）
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_str		= 期待文字列
*/
#ifndef IUTEST_EXPECT_THROW_VALUE_STRCASEEQ
#  define IUTEST_EXPECT_THROW_VALUE_STRCASEEQ(statement, expected_exception, expected_str)	\
													IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_str, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	any throw テスト
 * @details	statement が何らかの例外を投げることを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_EXPECT_ANY_THROW
#  define IUTEST_EXPECT_ANY_THROW(statement)		IUTEST_TEST_ANY_THROW_(statement, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	no throw テスト
 * @details	statement が例外を投げないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_EXPECT_NO_THROW
#  define IUTEST_EXPECT_NO_THROW(statement)			IUTEST_TEST_NO_THROW_(statement, IUTEST_EXPECT_FAILURE)
#endif

#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	no new failure テスト
 * @details	statement で失敗がないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_EXPECT_NO_FAILURE
#  define IUTEST_EXPECT_NO_FAILURE(statement)		IUTEST_TEST_NO_FAILURE_(statement, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	no new fatal failure テスト
 * @details	statement で致命的な失敗がないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_EXPECT_NO_FATAL_FAILURE
#  define IUTEST_EXPECT_NO_FATAL_FAILURE(statement)	IUTEST_TEST_NO_FATAL_FAILURE_(statement, IUTEST_EXPECT_FAILURE)
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	明示的な失敗
 * @details	明示的に致命的でない失敗を報告します
*/
#ifndef IUTEST_EXPECT_FAIL
#  define IUTEST_EXPECT_FAIL()						IIUT_ADD_FAILURE()
#endif

/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	明示的な失敗
 * @details	明示的に致命的でない失敗を報告します
*/
#ifndef IUTEST_EXPECT_FAIL_AT
#  define IUTEST_EXPECT_FAIL_AT(file, line)			IIUT_ADD_FAILURE_AT(file, line)
#endif


/**
 * @ingroup		IUTEST_ASSERTION_
 * @{
*/

/**
 * @defgroup	IUTEST_INFORM_	INFORM
 * @brief		警告フレーバー
 * @details		失敗した場合でも、テスト失敗として記録しません。また、テストは続行します。
*/

/**
 * @}
*/

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	式アサーション
 * @param	expression	= 式
*/
#ifndef IUTEST_INFORM
#  define	IUTEST_INFORM(expression)				IUTEST_TEST_EXPRESSION_(expression, true, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	式アサーション
 * @param	expression	= 式
*/
#ifndef IUTEST_INFORM_NOT
#  define	IUTEST_INFORM_NOT(expression)			IUTEST_TEST_EXPRESSION_(expression, false, IUTEST_INFORM_FAILURE)
#endif

#if IUTEST_HAS_MATCHERS
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	matcher テスト
 * @param	actual	= 検査対象
 * @param	matcher	= matcher
*/
#ifndef IUTEST_INFORM_THAT
#  define IUTEST_INFORM_THAT(actual, matcher)		IUTEST_TEST_THAT(actual, matcher, IUTEST_INFORM_FAILURE)
#endif

#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	== テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_INFORM_EQ
#  define	IUTEST_INFORM_EQ(expected, actual)		IUTEST_TEST_EQ(expected, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	!= テスト
 * @details	v1 と v2 が等しくないことを検証します
*/
#ifndef IUTEST_INFORM_NE
#  define	IUTEST_INFORM_NE(v1, v2)				IUTEST_TEST_NE(v1, v2, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	<= テスト
 * @details	v1 <= v2 が成り立つことを検証します
*/
#ifndef IUTEST_INFORM_LE
#  define	IUTEST_INFORM_LE(v1, v2)				IUTEST_TEST_LE(v1, v2, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	< テスト
 * @details	v1 < v2 が成り立つことを検証します
*/
#ifndef IUTEST_INFORM_LT
#  define	IUTEST_INFORM_LT(v1, v2)				IUTEST_TEST_LT(v1, v2, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	>= テスト
 * @details	v1 >= v2 が成り立つことを検証します
*/
#ifndef IUTEST_INFORM_GE
#  define	IUTEST_INFORM_GE(v1, v2)				IUTEST_TEST_GE(v1, v2, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	\> テスト
 * @details	v1 > v2 が成り立つことを検証します
*/
#ifndef IUTEST_INFORM_GT
#  define	IUTEST_INFORM_GT(v1, v2)				IUTEST_TEST_GT(v1, v2, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	TRUE テスト
 * @details	v が真であることを検証します
*/
#ifndef IUTEST_INFORM_TRUE
#  ifndef IUTEST_NO_VARIADIC_MACROS
#    define	IUTEST_INFORM_TRUE(...)					IUTEST_TEST_TRUE((__VA_ARGS__), #__VA_ARGS__, IUTEST_INFORM_FAILURE)
#  else
#    define	IUTEST_INFORM_TRUE(v)					IUTEST_TEST_TRUE(v, #v, IUTEST_INFORM_FAILURE)
#  endif
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	FALSE テスト
 * @details	v が偽であることを検証します
*/
#ifndef IUTEST_INFORM_FALSE
#  ifndef IUTEST_NO_VARIADIC_MACROS
#    define	IUTEST_INFORM_FALSE(...)				IUTEST_TEST_FALSE((__VA_ARGS__), #__VA_ARGS__, IUTEST_INFORM_FAILURE)
#  else
#    define	IUTEST_INFORM_FALSE(v)					IUTEST_TEST_FALSE(v, #v, IUTEST_INFORM_FAILURE)
#  endif
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	NULL テスト
 * @details	v が NULL であることを検証します
*/
#ifndef IUTEST_INFORM_NULL
#  define	IUTEST_INFORM_NULL(v)					IUTEST_TEST_NULL(v, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	NOT NULL テスト
 * @details	v が NULL でないことを検証します
*/
#ifndef IUTEST_INFORM_NOTNULL
#  define	IUTEST_INFORM_NOTNULL(v)				IUTEST_TEST_NOTNULL(v, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	アドレス一致 テスト
 * @details	v1 と v2 のアドレスが同じであることを検証します
*/
#ifndef IUTEST_INFORM_SAME
#  define	IUTEST_INFORM_SAME(v1, v2)				IUTEST_TEST_SAME(v1, v2, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	float の比較 テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_INFORM_FLOAT_EQ
#  define	IUTEST_INFORM_FLOAT_EQ(expected, actual)	IUTEST_TEST_FLOAT_EQ(expected, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	double の比較 テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_INFORM_DOUBLE_EQ
#  define	IUTEST_INFORM_DOUBLE_EQ(expected, actual)	IUTEST_TEST_DOUBLE_EQ(expected, actual, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	２値の差の範囲 テスト
 * @param	v1		= 値1
 * @param	v2		= 値2
 * @param	abs_v	= v1 と v2 の差分の期待値
*/
#ifndef IUTEST_INFORM_NEAR
#  define	IUTEST_INFORM_NEAR(v1, v2, abs_v)		IUTEST_TEST_NEAR(v1, v2, abs_v, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	文字列の一致 テスト
 * @param	expected_str	= 期待値
 * @param	actual_str		= 検査対象
*/
#ifndef IUTEST_INFORM_STREQ
#  define	IUTEST_INFORM_STREQ(expected_str, actual_str)	IUTEST_TEST_STREQ(expected_str, actual_str, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	文字列の不一致 テスト
 * @details	v1 と v2 文字列が異なることを検証します
*/
#ifndef IUTEST_INFORM_STRNE
#  define	IUTEST_INFORM_STRNE(v1, v2)				IUTEST_TEST_STRNE(v1, v2, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	文字列の一致（大文字小文字区別なし） テスト
 * @param	expected_str	= 期待値
 * @param	actual_str		= 検査対象
*/
#ifndef IUTEST_INFORM_STRCASEEQ
#  define	IUTEST_INFORM_STRCASEEQ(expected_str, actual_str)	IUTEST_TEST_STRCASEEQ(expected_str, actual_str, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	文字列の不一致（大文字小文字区別なし） テスト
 * @details	v1 と v2 文字列が異なることを検証します（大文字小文字区別なし）
*/
#ifndef IUTEST_INFORM_STRCASENE
#  define	IUTEST_INFORM_STRCASENE(v1, v2)			IUTEST_TEST_STRCASENE(v1, v2, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	HRESULT の成功 テスト
 * @details	HRESULT が成功であることを検証します
*/
#ifndef IUTEST_INFORM_HRESULT_SUCCEEDED
#  define IUTEST_INFORM_HRESULT_SUCCEEDED(hr)		IUTEST_TEST_HRESULT_SUCCEEDED(hr, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	HRESULT の失敗 テスト
 * @details	HRESULT が失敗であることを検証します
*/
#ifndef IUTEST_INFORM_HRESULT_FAILED
#  define IUTEST_INFORM_HRESULT_FAILED(hr)			IUTEST_TEST_HRESULT_FAILED(hr, IUTEST_INFORM_FAILURE)
#endif

#if IUTEST_HAS_EXCEPTIONS

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	throw テスト
 * @details	statement が expected_exception を throw することを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
*/
#ifndef IUTEST_INFORM_THROW
#  define IUTEST_INFORM_THROW(statement, expected_exception)	\
													IUTEST_TEST_THROW_(statement, expected_exception, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	throw value == テスト
 * @details	statement が expected_exception を throw し、その値が expected_value と等しいことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_value		= 期待値
*/
#ifndef IUTEST_INFORM_THROW_VALUE_EQ
#  define IUTEST_INFORM_THROW_VALUE_EQ(statement, expected_exception, expected_value)	\
													IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_value, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	throw value != テスト
 * @details	statement が expected_exception を throw し、その値が v と等しくないことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	v					= 値
*/
#ifndef IUTEST_INFORM_THROW_VALUE_NE
#  define IUTEST_INFORM_THROW_VALUE_NE(statement, expected_exception, v)	\
													IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, v, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	throw value 文字列一致 テスト
 * @details	statement が expected_exception を throw し、その文字列が expected_str と等しいことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_str		= 期待文字列
*/
#ifndef IUTEST_INFORM_THROW_VALUE_STREQ
#  define IUTEST_INFORM_THROW_VALUE_STREQ(statement, expected_exception, expected_str)	\
													IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_str, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	throw value 文字列一致（大文字小文字区別なし） テスト
 * @details	statement が expected_exception を throw し、その文字列が expected_str と等しいことを検証します（大文字小文字区別なし）
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_str		= 期待文字列
*/
#ifndef IUTEST_INFORM_THROW_VALUE_STRCASEEQ
#  define IUTEST_INFORM_THROW_VALUE_STRCASEEQ(statement, expected_exception, expected_str)	\
													IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_str, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	any throw テスト
 * @details	statement が何らかの例外を投げることを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_INFORM_ANY_THROW
#  define IUTEST_INFORM_ANY_THROW(statement)		IUTEST_TEST_ANY_THROW_(statement, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	no throw テスト
 * @details	statement が例外を投げないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_INFORM_NO_THROW
#  define IUTEST_INFORM_NO_THROW(statement)			IUTEST_TEST_NO_THROW_(statement, IUTEST_INFORM_FAILURE)
#endif

#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	no new failure テスト
 * @details	statement で失敗がないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_INFORM_NO_FAILURE
#  define IUTEST_INFORM_NO_FAILURE(statement)		IUTEST_TEST_NO_FAILURE_(statement, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup	IUTEST_INFORM_
 * @brief	no new fatal failure テスト
 * @details	statement で致命的な失敗がないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_INFORM_NO_FATAL_FAILURE
#  define IUTEST_INFORM_NO_FATAL_FAILURE(statement)	IUTEST_TEST_NO_FATAL_FAILURE_(statement, IUTEST_INFORM_FAILURE)
#endif

/**
 * @ingroup		IUTEST_ASSERTION_
 * @{
*/

/**
 * @defgroup	IUTEST_ASSUME_	ASSUME
 * @brief		前提条件フレーバー
 * @details		テストの前提検証用マクロです。失敗した場合、以降の処理を行わずテストはスキップされます。
*/

/**
 * @}
*/

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	式アサーション
 * @param	expression	= 式
*/
#ifndef IUTEST_ASSUME
#  define	IUTEST_ASSUME(expression)				IUTEST_TEST_EXPRESSION_(expression, true, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	式アサーション
 * @param	expression	= 式
*/
#ifndef IUTEST_ASSUME_NOT
#  define	IUTEST_ASSUME_NOT(expression)			IUTEST_TEST_EXPRESSION_(expression, false, IUTEST_ASSUME_FAILURE)
#endif

#if IUTEST_HAS_MATCHERS

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	matcher テスト
 * @param	actual	= 検査対象
 * @param	matcher	= matcher
*/
#ifndef IUTEST_ASSUME_THAT
#  define IUTEST_ASSUME_THAT(actual, matcher)		IUTEST_TEST_THAT(actual, matcher, IUTEST_ASSUME_FAILURE)
#endif

#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	== テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSUME_EQ
#  define	IUTEST_ASSUME_EQ(expected, actual)		IUTEST_TEST_EQ(expected, actual, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	!= テスト
 * @details	v1 と v2 が等しくないことを検証します
*/
#ifndef IUTEST_ASSUME_NE
#  define	IUTEST_ASSUME_NE(v1, v2)				IUTEST_TEST_NE(v1, v2, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	<= テスト
 * @details	v1 <= v2 が成り立つことを検証します
*/
#ifndef IUTEST_ASSUME_LE
#  define	IUTEST_ASSUME_LE(v1, v2)				IUTEST_TEST_LE(v1, v2, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	< テスト
 * @details	v1 < v2 が成り立つことを検証します
*/
#ifndef IUTEST_ASSUME_LT
#  define	IUTEST_ASSUME_LT(v1, v2)				IUTEST_TEST_LT(v1, v2, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	>= テスト
 * @details	v1 >= v2 が成り立つことを検証します
*/
#ifndef IUTEST_ASSUME_GE
#  define	IUTEST_ASSUME_GE(v1, v2)				IUTEST_TEST_GE(v1, v2, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	\> テスト
 * @details	v1 > v2 が成り立つことを検証します
*/
#ifndef IUTEST_ASSUME_GT
#  define	IUTEST_ASSUME_GT(v1, v2)				IUTEST_TEST_GT(v1, v2, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	TRUE テスト
 * @details	v が真であることを検証します
*/
#ifndef IUTEST_ASSUME_TRUE
#  ifndef IUTEST_NO_VARIADIC_MACROS
#    define	IUTEST_ASSUME_TRUE(...)					IUTEST_TEST_TRUE((__VA_ARGS__), #__VA_ARGS__, IUTEST_ASSUME_FAILURE)
#  else
#    define	IUTEST_ASSUME_TRUE(v)					IUTEST_TEST_TRUE(v, #v, IUTEST_ASSUME_FAILURE)
#  endif
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	FALSE テスト
 * @details	v が偽であることを検証します
*/
#ifndef IUTEST_ASSUME_FALSE
#  ifndef IUTEST_NO_VARIADIC_MACROS
#    define	IUTEST_ASSUME_FALSE(...)				IUTEST_TEST_FALSE((__VA_ARGS__), #__VA_ARGS__, IUTEST_ASSUME_FAILURE)
#  else
#    define	IUTEST_ASSUME_FALSE(v)					IUTEST_TEST_FALSE(v, #v, IUTEST_ASSUME_FAILURE)
#  endif
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	NULL テスト
 * @details	v が NULL であることを検証します
*/
#ifndef IUTEST_ASSUME_NULL
#  define	IUTEST_ASSUME_NULL(v)					IUTEST_TEST_NULL(v, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	NOT NULL テスト
 * @details	v が NULL でないことを検証します
*/
#ifndef IUTEST_ASSUME_NOTNULL
#  define	IUTEST_ASSUME_NOTNULL(v)				IUTEST_TEST_NOTNULL(v, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	アドレス一致 テスト
 * @details	v1 と v2 のアドレスが同じであることを検証します
*/
#ifndef IUTEST_ASSUME_SAME
#  define	IUTEST_ASSUME_SAME(v1, v2)				IUTEST_TEST_SAME(v1, v2, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	float の比較 テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSUME_FLOAT_EQ
#  define	IUTEST_ASSUME_FLOAT_EQ(expected, actual)	IUTEST_TEST_FLOAT_EQ(expected, actual, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	double の比較 テスト
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSUME_DOUBLE_EQ
#  define	IUTEST_ASSUME_DOUBLE_EQ(expected, actual)	IUTEST_TEST_DOUBLE_EQ(expected, actual, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	２値の差の範囲 テスト
 * @param	v1		= 値1
 * @param	v2		= 値2
 * @param	abs_v	= v1 と v2 の差分の期待値
*/
#ifndef IUTEST_ASSUME_NEAR
#  define	IUTEST_ASSUME_NEAR(v1, v2, abs_v)		IUTEST_TEST_NEAR(v1, v2, abs_v, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	文字列の一致 テスト
 * @param	expected_str	= 期待値
 * @param	actual_str		= 検査対象
*/
#ifndef IUTEST_ASSUME_STREQ
#  define	IUTEST_ASSUME_STREQ(expected_str, actual_str)	IUTEST_TEST_STREQ(expected_str, actual_str, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	文字列の不一致 テスト
 * @details	v1 と v2 文字列が異なることを検証します
*/
#ifndef IUTEST_ASSUME_STRNE
#  define	IUTEST_ASSUME_STRNE(v1, v2)				IUTEST_TEST_STRNE(v1, v2, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	文字列の一致（大文字小文字区別なし） テスト
 * @param	expected_str	= 期待値
 * @param	actual_str		= 検査対象
*/
#ifndef IUTEST_ASSUME_STRCASEEQ
#  define	IUTEST_ASSUME_STRCASEEQ(expected_str, actual_str)	IUTEST_TEST_STRCASEEQ(expected_str, actual_str, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	文字列の不一致（大文字小文字区別なし） テスト
 * @details	v1 と v2 文字列が異なることを検証します（大文字小文字区別なし）
*/
#ifndef IUTEST_ASSUME_STRCASENE
#  define	IUTEST_ASSUME_STRCASENE(v1, v2)			IUTEST_TEST_STRCASENE(v1, v2, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	HRESULT の成功 テスト
 * @details	HRESULT が成功であることを検証します
*/
#ifndef IUTEST_ASSUME_HRESULT_SUCCEEDED
#  define IUTEST_ASSUME_HRESULT_SUCCEEDED(hr)		IUTEST_TEST_HRESULT_SUCCEEDED(hr, IUTEST_ASSUME_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	HRESULT の失敗 テスト
 * @details	HRESULT が失敗であることを検証します
*/
#ifndef IUTEST_ASSUME_HRESULT_FAILED
#  define IUTEST_ASSUME_HRESULT_FAILED(hr)			IUTEST_TEST_HRESULT_FAILED(hr, IUTEST_ASSUME_FAILURE)
#endif

#if IUTEST_HAS_EXCEPTIONS

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	throw テスト
 * @details	statement が expected_exception を throw することを検証します
 * @param	statement	= ステートメント
 * @param	expected_exception = 期待する例外
*/
#ifndef IUTEST_ASSUME_THROW
#  define IUTEST_ASSUME_THROW(statement, expected_exception)	\
													IUTEST_TEST_THROW_(statement, expected_exception, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	throw value == テスト
 * @details	statement が expected_exception を throw し、その値が expected_value と等しいことを検証します
 * @param	statement	= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_value		= 期待値
*/
#ifndef IUTEST_ASSUME_THROW_VALUE_EQ
#  define IUTEST_ASSUME_THROW_VALUE_EQ(statement, expected_exception, expected_value)	\
													IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_value, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	throw value != テスト
 * @details	statement が expected_exception を throw し、その値が v と等しくないことを検証します
 * @param	statement	= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	v			= 値
*/
#ifndef IUTEST_ASSUME_THROW_VALUE_NE
#  define IUTEST_ASSUME_THROW_VALUE_NE(statement, expected_exception, v)	\
													IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, v, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	throw value 文字列一致 テスト
 * @details	statement が expected_exception を throw し、その文字列が expected_str と等しいことを検証します
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_str		= 期待文字列
*/
#ifndef IUTEST_ASSUME_THROW_VALUE_STREQ
#  define IUTEST_ASSUME_THROW_VALUE_STREQ(statement, expected_exception, expected_str)	\
													IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_str, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	throw value 文字列一致（大文字小文字区別なし） テスト
 * @details	statement が expected_exception を throw し、その文字列が expected_str と等しいことを検証します（大文字小文字区別なし）
 * @param	statement			= ステートメント
 * @param	expected_exception	= 期待する例外
 * @param	expected_str		= 期待文字列
*/
#ifndef IUTEST_ASSUME_THROW_VALUE_STRCASEEQ
#  define IUTEST_ASSUME_THROW_VALUE_STRCASEEQ(statement, expected_exception, expected_str)	\
													IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_str, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	any throw テスト
 * @details	statement が何らかの例外を投げることを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_ASSUME_ANY_THROW
#  define IUTEST_ASSUME_ANY_THROW(statement)		IUTEST_TEST_ANY_THROW_(statement, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	no throw テスト
 * @details	statement が例外を投げないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_ASSUME_NO_THROW
#  define IUTEST_ASSUME_NO_THROW(statement)			IUTEST_TEST_NO_THROW_(statement, IUTEST_ASSUME_FAILURE)
#endif

#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	no new failure テスト
 * @details	statement で失敗がないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_ASSUME_NO_FAILURE
#  define IUTEST_ASSUME_NO_FAILURE(statement)		IUTEST_TEST_NO_FAILURE_(statement, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	no new fatal failure テスト
 * @details	statement で致命的な失敗がないことを検証します
 * @param	statement = ステートメント
*/
#ifndef IUTEST_ASSUME_NO_FATAL_FAILURE
#  define IUTEST_ASSUME_NO_FATAL_FAILURE(statement)	IUTEST_TEST_NO_FATAL_FAILURE_(statement, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @brief iutest root namespace
*/
namespace iutest
{

//======================================================================
// class
/**
 * @brief	単体テスト起点
*/
class UnitTestSource
{
public:
	
	static UnitTestSource& GetInstance(void) { static UnitTestSource inst; return inst; }

private:
	UnitTestSource(void)
	{
#if defined(_IUTEST_DEBUG)
		detail::iuDebugInitialize();
#else
		IUTEST_UNUSED_VAR(&detail::iuDebugInitialize);
		IUTEST_UNUSED_VAR(&detail::iuDebugBreakAlloc);
#endif
		TestEnv::event_listeners().set_default_result_printer(new DefalutResultPrintListener());
	}
public:
	
	~UnitTestSource(void)
	{
		TestEnv::event_listeners().set_default_result_printer(NULL);
		TestEnv::event_listeners().set_default_xml_generator(NULL);
	}

public:
	/**
	 * @brief	初期化
	*/
	void Initialize(void)
	{
		UnitTest::instance().Initialize();
	}

	/**
	 * @brief	テストの実行
	*/
	int	Run(void)
	{
		DefaultXmlGeneratorListener::SetUp();
		JunitXmlGeneratorListener::SetUp();

#if IUTEST_HAS_STREAM_RESULT
		StreamResultListener::SetUp();
#endif

		return UnitTest::instance().Run();
	}
};

//======================================================================
// function
namespace detail
{

template<typename T>
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, T argv)
{
	UnitTestSource::GetInstance().Initialize();
	TestEnv::ParseCommandLine(pargc, argv);
	TestEnv::LoadFlagFile();
}

}

/**
 * @brief	初期化
 * @details	コマンドラインオプションの解析をします。
 *			使用した引数は削除され pargc, argv を書き換えます
*/
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, char** argv)		{ detail::InitIrisUnitTest(pargc, argv); }
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, wchar_t** argv)	{ detail::InitIrisUnitTest(pargc, argv); }		//!< @overload
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, const char** argv)	{ detail::InitIrisUnitTest(pargc, argv); }	//!< @overload
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, const wchar_t** argv)	{ detail::InitIrisUnitTest(pargc, argv); }	//!< @overload
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(void) { detail::InitIrisUnitTest<char**>(NULL, NULL); }	//!< @overload

#if IUTEST_HAS_NULLPTR
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, ::std::nullptr_t)	{ detail::InitIrisUnitTest<char**>(pargc, NULL); }	//!< @overload
#endif


template<typename CharType>
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(::std::vector< ::std::basic_string<CharType> >& argv)
{
	UnitTestSource::GetInstance().Initialize();
	TestEnv::ParseCommandLine(argv);
	TestEnv::LoadFlagFile();
}

/**
 * @brief	グローバル環境セットクラスの追加
 * @param [in]	env	= 環境セットクラスアドレス
 * @return	登録されたクラスアドレス
 * @note	メモリ管理はしない。new した Environment はユーザーが解放する
*/
inline Environment* IUTEST_ATTRIBUTE_UNUSED_ AddGlobalTestEnvironment(Environment* env)
{
	return TestEnv::AddGlobalTestEnvironment(env);
}

}

#if defined(IUTEST_USE_GTEST)
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch.hpp
 * @brief		switching to iutest from gtest / gtest from iutest
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_HPP_
#define INCG_IRIS_IUTEST_SWITCH_HPP_

#if !defined(IUTEST_USE_GTEST)

#ifdef GTEST_USE_OWN_TR1_TUPLE
#  define IUTEST_USE_EXTERNAL_TR1_TUPLE	1	// gtest の tuple を使用する
#endif

//======================================================================
// include

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

#if defined(GTEST_INCLUDE_GTEST_GTEST_H_)

#undef SUCCEED
#undef FAIL
#undef ADD_FAILURE
#undef ADD_FAILURE_AT

#undef GTEST_HAS_DEATH_TEST
#undef GTEST_HAS_PARAM_TEST
#undef GTEST_HAS_COMBINE
#undef GTEST_HAS_TYPED_TEST
#undef GTEST_HAS_TYPED_TEST_P

#undef GTEST_CAN_STREAM_RESULTS_

#undef GTEST_HAS_EXCEPTIONS
#undef GTEST_HAS_RTTI
#undef GTEST_HAS_SEH

#endif

#define SUCCEED				IUTEST_SUCCEED
#define FAIL				IUTEST_FAIL
#define ADD_FAILURE			IUTEST_ADD_FAILURE
#define ADD_FAILURE_AT		IUTEST_ADD_FAILURE_AT

#define GTEST_HAS_DEATH_TEST	0
#define GTEST_HAS_PARAM_TEST	IUTEST_HAS_PARAM_TEST
#define GTEST_HAS_COMBINE		IUTEST_HAS_COMBINE
#define GTEST_HAS_TYPED_TEST	IUTEST_HAS_TYPED_TEST
#define GTEST_HAS_TYPED_TEST_P	IUTEST_HAS_TYPED_TEST_P

#define GTEST_CAN_STREAM_RESULTS_	0

#define GTEST_HAS_EXCEPTIONS	IUTEST_HAS_EXCEPTIONS
#define GTEST_HAS_RTTI			IUTEST_HAS_RTTI
#define GTEST_HAS_SEH			IUTEST_HAS_SEH

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_port.hpp
 * @brief		portable 定義切り替え ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_PORT_HPP_2B432CD6_18CE_4D0C_B0CD_4E4D5B8E34F4_
#define INCG_IRIS_IUTEST_SWITCH_PORT_HPP_2B432CD6_18CE_4D0C_B0CD_4E4D5B8E34F4_

#if !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#ifdef GTEST_INCLUDE_GTEST_GTEST_H_

#ifdef GTEST_OS_CYGWIN
#  undef GTEST_OS_CYGWIN
#endif
#ifdef GTEST_OS_WINDOWS
#  undef GTEST_OS_WINDOWS
#  ifdef GTEST_OS_WINDOWS_MOBILE
#	 undef GTEST_OS_WINDOWS_MOBILE
#  endif
#  ifdef GTEST_OS_WINDOWS_MINGW
#	 undef GTEST_OS_WINDOWS_MINGW
#  endif
#  ifdef GTEST_OS_WINDOWS_DESKTOP
#	 undef GTEST_OS_WINDOWS_DESKTOP
#  endif
#endif
#ifdef GTEST_OS_MAC
#  undef GTEST_OS_MAC
#  ifdef GTEST_OS_IOS
#    undef GTEST_OS_IOS
#  endif
#endif
#ifdef GTEST_OS_FREEBSD
#  undef GTEST_OS_FREEBSD
#endif
#ifdef GTEST_OS_SOLARIS
#  undef GTEST_OS_SOLARIS
#endif
#ifdef GTEST_OS_LINUX
#  undef GTEST_OS_LINUX
#  ifdef GTEST_OS_LINUX_ANDROID
#	 undef GTEST_OS_LINUX_ANDROID
#  endif
#endif
#ifdef IUTEST_OS_NACL
#  undef IUTEST_OS_NACL
#endif

#endif

//======================================================================
// define
#ifdef IUTEST_OS_CYGWIN
#  define GTEST_OS_CYGWIN				IUTEST_OS_CYGWIN
#endif
#ifdef IUTEST_OS_WINDOWS
#  define GTEST_OS_WINDOWS				IUTEST_OS_WINDOWS
#  ifdef IUTEST_OS_WINDOWS_MOBILE
#	 define GTEST_OS_WINDOWS_MOBILE		IUTEST_OS_WINDOWS_MOBILE
#  endif
#  ifdef IUTEST_OS_WINDOWS_MINGW
#	 define GTEST_OS_WINDOWS_MINGW		IUTEST_OS_WINDOWS_MINGW
#  endif
#  ifdef IUTEST_OS_WINDOWS_DESKTOP
#	 define GTEST_OS_WINDOWS_DESKTOP	IUTEST_OS_WINDOWS_DESKTOP
#  endif
#  ifdef IUTEST_OS_WINDOWS_PHONE
#	 define GTEST_OS_WINDOWS_PHONE		IUTEST_OS_WINDOWS_PHONE
#  endif
#  ifdef IUTEST_OS_WINDOWS_RT
#	 define GTEST_OS_WINDOWS_RT			IUTEST_OS_WINDOWS_RT
#  endif
#  ifdef IUTEST_OS_WINDOWS_WINE
#	 define GTEST_OS_WINDOWS_WINE		IUTEST_OS_WINDOWS_WINE
#  endif
#endif
#ifdef IUTEST_OS_MAC
#  define GTEST_OS_MAC					IUTEST_OS_MAC
#  ifdef IUTEST_OS_IOS
#    define GTEST_OS_IOS				IUTEST_OS_IOS
#  endif
#endif
#ifdef IUTEST_OS_FREEBSD
#  define GTEST_OS_FREEBSD				IUTEST_OS_FREEBSD
#endif
#ifdef IUTEST_OS_SOLARIS
#  define GTEST_OS_SOLARIS				IUTEST_OS_SOLARIS
#endif
#ifdef IUTEST_OS_LINUX
#  define GTEST_OS_LINUX				IUTEST_OS_LINUX
#  ifdef IUTEST_OS_LINUX_ANDROID
#	 define GTEST_OS_LINUX_ANDROID		IUTEST_OS_LINUX_ANDROID
#  endif
#endif
#ifdef IUTEST_OS_NACL
#  define GTEST_OS_NACL					IUTEST_OS_NACL
#endif

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#ifdef IUTEST_OS_CYGWIN
#  undef IUTEST_OS_CYGWIN
#endif
#ifdef IUTEST_OS_WINDOWS
#  undef IUTEST_OS_WINDOWS
#  ifdef IUTEST_OS_WINDOWS_PHONE
#	 undef IUTEST_OS_WINDOWS_PHONE
#  endif
#  ifdef IUTEST_OS_WINDOWS_RT
#	 undef IUTEST_OS_WINDOWS_RT
#  endif
#  ifdef IUTEST_OS_WINDOWS_MOBILE
#	 undef IUTEST_OS_WINDOWS_MOBILE
#  endif
#  ifdef IUTEST_OS_WINDOWS_MINGW
#	 undef IUTEST_OS_WINDOWS_MINGW
#  endif
#  ifdef IUTEST_OS_WINDOWS_DESKTOP
#	 undef IUTEST_OS_WINDOWS_DESKTOP
#  endif
#endif
#ifdef IUTEST_OS_MAC
#  undef IUTEST_OS_MAC
#  ifdef IUTEST_OS_IOS
#    undef IUTEST_OS_IOS
#  endif
#endif
#ifdef IUTEST_OS_FREEBSD
#  undef IUTEST_OS_FREEBSD
#endif
#ifdef IUTEST_OS_SOLARIS
#  undef IUTEST_OS_SOLARIS
#endif
#ifdef IUTEST_OS_LINUX
#  undef IUTEST_OS_LINUX
#  ifdef IUTEST_OS_LINUX_ANDROID
#	 undef IUTEST_OS_LINUX_ANDROID
#  endif
#endif
#ifdef IUTEST_OS_NACL
#  undef IUTEST_OS_NACL
#endif

#endif

//======================================================================
// define
#ifdef GTEST_OS_CYGWIN
#  define IUTEST_OS_CYGWIN		GTEST_OS_CYGWIN
#endif
#ifdef GTEST_OS_WINDOWS
#  include <windows.h>
#  define IUTEST_OS_WINDOWS				GTEST_OS_WINDOWS
#  ifdef GTEST_OS_WINDOWS_PHONE
#	 define IUTEST_OS_WINDOWS_PHONE		GTEST_OS_WINDOWS_PHONE
#  endif
#  ifdef GTEST_OS_WINDOWS_RT
#	 define IUTEST_OS_WINDOWS_RT		GTEST_OS_WINDOWS_RT
#  endif
#  ifdef GTEST_OS_WINDOWS_MOBILE
#	 define IUTEST_OS_WINDOWS_MOBILE	GTEST_OS_WINDOWS_MOBILE
#  endif
#  ifdef GTEST_OS_WINDOWS_MINGW
#	 define IUTEST_OS_WINDOWS_MINGW		GTEST_OS_WINDOWS_MINGW
#  endif
#  ifdef GTEST_OS_WINDOWS_DESKTOP
#	 define IUTEST_OS_WINDOWS_DESKTOP	GTEST_OS_WINDOWS_DESKTOP
#  endif
#  ifdef GTEST_OS_WINDOWS_PHONE
#	 define IUTEST_OS_WINDOWS_PHONE		GTEST_OS_WINDOWS_PHONE
#  endif
#  ifdef GTEST_OS_WINDOWS_RT
#	 define IUTEST_OS_WINDOWS_RT		GTEST_OS_WINDOWS_RT
#  endif
#endif
#ifdef GTEST_OS_MAC
#  define IUTEST_OS_MAC					GTEST_OS_MAC
#  ifdef GTEST_OS_IOS
#    define IUTEST_OS_IOS				GTEST_OS_IOS
#  endif
#endif
#ifdef GTEST_OS_FREEBSD
#  define IUTEST_OS_FREEBSD				GTEST_OS_FREEBSD
#endif
#ifdef GTEST_OS_SOLARIS
#  define IUTEST_OS_SOLARIS				GTEST_OS_SOLARIS
#endif
#ifdef GTEST_OS_LINUX
#  define IUTEST_OS_LINUX				GTEST_OS_LINUX
#  ifdef GTEST_OS_LINUX_ANDROID
#	 define IUTEST_OS_LINUX_ANDROID		GTEST_OS_LINUX_ANDROID
#  endif
#endif
#ifdef GTEST_OS_NACL
#  define IUTEST_OS_NACL				GTEST_OS_NACL
#endif

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()

//======================================================================
// function
namespace testing {
namespace internal {
namespace posix
{

inline int PutEnv(const char* expr)
{
#if defined(IUTEST_OS_WINDOWS_MOBILE) || defined(IUTEST_NO_PUTENV) || defined(__STRICT_ANSI__)
	(void)(expr);
	return -1;
#else
	return putenv(const_cast<char*>(expr));
#endif
}

}	// end of namespace posix
}	// end of namespace internal

inline int iu_wcsicmp(const wchar_t * str1, const wchar_t * str2)
{
#if   defined(_MSC_VER)
	return _wcsicmp(str1, str2);
#elif defined(IUTEST_OS_LINUX) && !defined(IUTEST_OS_LINUX_ANDROID)
	return wcscasecmp(str1, str2);
#else
	const wchar_t* l = str1;
	const wchar_t* r = str2;
	while(*l)
	{
		wchar_t ul = towupper(*l);
		wchar_t ur = towupper(*r);
		if( ul < ur ) return -1;
		if( ul > ur ) return 1;
		++l;
		++r;
	}
	if( *l < *r ) return -1;
	if( *l > *r ) return 1;
	return 0;
#endif
}

}	// end of namespace testing

IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_PORT_HPP_2B432CD6_18CE_4D0C_B0CD_4E4D5B8E34F4_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_core.hpp
 * @brief		コア機能定義切り替え ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_CORE_HPP_0385C393_90D3_4B06_A027_4B07A17A33CB_
#define INCG_IRIS_IUTEST_SWITCH_CORE_HPP_0385C393_90D3_4B06_A027_4B07A17A33CB_

#if !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#ifdef GTEST_INCLUDE_GTEST_GTEST_H_

#undef RUN_ALL_TESTS

#undef TEST
#undef GTEST_TEST
#undef TEST_F
#undef TEST_P
#undef INSTANTIATE_TEST_CASE_P

#undef FRIEND_TEST
#undef SCOPED_TRACE
#undef GTEST_FLAG

#undef TYPED_TEST_CASE
#undef TYPED_TEST
#undef TYPED_TEST_CASE_P
#undef TYPED_TEST_P
#undef REGISTER_TYPED_TEST_CASE_P
#undef INSTANTIATE_TYPED_TEST_CASE_P

#undef GTEST_ATTRIBUTE_UNUSED_
#undef GTEST_AMBIGUOUS_ELSE_BLOCKER_

#undef GTEST_TEST_CLASS_NAME_
#undef GTEST_TEST_

#endif

//======================================================================
// define
#define RUN_ALL_TESTS	IUTEST_RUN_ALL_TESTS

#define TEST		IUTEST
#define GTEST_TEST	IUTEST_TEST
#define TEST_F		IUTEST_F
#define TEST_P		IUTEST_P
#define INSTANTIATE_TEST_CASE_P	IUTEST_INSTANTIATE_TEST_CASE_P

#define FRIEND_TEST			IUTEST_FRIEND_TEST
#define SCOPED_TRACE		IUTEST_SCOPED_TRACE
#define GTEST_FLAG			IUTEST_FLAG

#define TYPED_TEST_CASE		IUTEST_TYPED_TEST_CASE
#define TYPED_TEST			IUTEST_TYPED_TEST
#define TYPED_TEST_CASE_P	IUTEST_TYPED_TEST_CASE_P
#define TYPED_TEST_P		IUTEST_TYPED_TEST_P
#define REGISTER_TYPED_TEST_CASE_P		IUTEST_REGISTER_TYPED_TEST_CASE_P
#define INSTANTIATE_TYPED_TEST_CASE_P	IUTEST_INSTANTIATE_TYPED_TEST_CASE_P

#define GTEST_ATTRIBUTE_UNUSED_			IUTEST_ATTRIBUTE_UNUSED_
#define GTEST_AMBIGUOUS_ELSE_BLOCKER_	IUTEST_AMBIGUOUS_ELSE_BLOCKER_

#define GTEST_TEST_CLASS_NAME_	IUTEST_TEST_CLASS_NAME_
#define GTEST_TEST_				IUTEST_TEST_


#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#undef IUTEST_RUN_ALL_TESTS
#undef IUTEST_INIT

#undef IUTEST
#undef IUTEST_TEST
#undef IUTEST_F
#undef IUTEST_P
#undef IUTEST_INSTANTIATE_TEST_CASE_P

#undef IUTEST_FRIEND_TEST
#undef IUTEST_FRIEND_TYPED_TEST
#undef IUTEST_SCOPED_TRACE
#undef IUTEST_FLAG

#undef IUTEST_TYPED_TEST_CASE
#undef IUTEST_TYPED_TEST
#undef IUTEST_T
#undef IUTEST_TYPED_TEST_CASE_P
#undef IUTEST_TYPED_TEST_P
#undef IUTEST_TP
#undef IUTEST_REGISTER_TYPED_TEST_CASE_P
#undef IUTEST_INSTANTIATE_TYPED_TEST_CASE_P

#ifdef IUTEST_AP
#  undef IUTEST_AP
#endif
#ifdef INSTANTIATE_TYPED_TEST_CASE_AP
#  undef INSTANTIATE_TYPED_TEST_CASE_AP
#endif


#undef IUTEST_ATTRIBUTE_UNUSED_
#undef IUTEST_AMBIGUOUS_ELSE_BLOCKER_

#undef IUTEST_TEST_CLASS_NAME_
#undef IUTEST_TEST_

#undef IUTEST_SUPPRESS_UNREACHABLE_CODE_WARNING
#undef IUTEST_PP_CAT
#undef IUTEST_IS_NULLLITERAL

#undef IUTEST_THROUGH_ANALYSIS_ASSUME

#endif

//======================================================================
// define
#define IUTEST_RUN_ALL_TESTS	RUN_ALL_TESTS
#define IUTEST_INIT				::testing::InitIrisUnitTest

#define IUTEST		GTEST_TEST
#define IUTEST_TEST	GTEST_TEST
#define IUTEST_F	TEST_F
#define IUTEST_P	TEST_P
#define IUTEST_INSTANTIATE_TEST_CASE_P	INSTANTIATE_TEST_CASE_P

#define IUTEST_FRIEND_TEST			FRIEND_TEST
#define IUTEST_FRIEND_TYPED_TEST	template<typename T>FRIEND_TEST
#define IUTEST_SCOPED_TRACE			SCOPED_TRACE
#define IUTEST_FLAG					GTEST_FLAG

#define IUTEST_TYPED_TEST_CASE		TYPED_TEST_CASE
#define IUTEST_TYPED_TEST			TYPED_TEST
#define IUTEST_T					TYPED_TEST
#define IUTEST_TYPED_TEST_CASE_P	TYPED_TEST_CASE_P
#define IUTEST_TYPED_TEST_P			TYPED_TEST_P
#define IUTEST_TP					TYPED_TEST_P
#define IUTEST_REGISTER_TYPED_TEST_CASE_P		REGISTER_TYPED_TEST_CASE_P
#define IUTEST_INSTANTIATE_TYPED_TEST_CASE_P	INSTANTIATE_TYPED_TEST_CASE_P

#define IUTEST_ATTRIBUTE_UNUSED_		GTEST_ATTRIBUTE_UNUSED_
#define IUTEST_AMBIGUOUS_ELSE_BLOCKER_	GTEST_AMBIGUOUS_ELSE_BLOCKER_

#define IUTEST_TEST_CLASS_NAME_	GTEST_TEST_CLASS_NAME_
#define IUTEST_TEST_			GTEST_TEST_

#define IUTEST_SUPPRESS_UNREACHABLE_CODE_WARNING	GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_

#define IUTEST_PP_CAT	GTEST_CONCAT_TOKEN_
#define IUTEST_IS_NULLLITERAL	GTEST_IS_NULL_LITERAL_


// __analysis_assume
#if defined(_MSC_VER) && (_MSC_VER >= 1500) && !defined(__CUDACC__)

#define IUTEST_THROUGH_ANALYSIS_ASSUME(expr, todo)					\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_									\
	if( bool b = true ) {											\
		__analysis_assume(expr);									\
		goto IUTEST_PP_CAT(iutest_label_analysis_assume, __LINE__);	\
	} else															\
		IUTEST_PP_CAT(iutest_label_analysis_assume, __LINE__):		\
		todo

#else

#define IUTEST_THROUGH_ANALYSIS_ASSUME(expr, todo)	todo

#endif

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_CORE_HPP_0385C393_90D3_4B06_A027_4B07A17A33CB_

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_gmock.hpp
 * @brief		gmock 切り替え定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2014-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_GMOCK_HPP_4212321D_F709_4904_AAF7_5E1BE18C0947_
#define INCG_IRIS_IUTEST_SWITCH_GMOCK_HPP_4212321D_F709_4904_AAF7_5E1BE18C0947_

#if !defined(IUTEST_USE_GTEST)

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

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#undef IUTEST_ASSERT_THAT
#undef IUTEST_EXPECT_THAT
#undef IUTEST_INFORM_THAT
#undef IUTEST_ASSUME_THAT

#undef IUTEST_HAS_MATCHERS
#undef IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF
#undef IUTEST_HAS_MATCHER_ELEMENTSARE
#undef IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD
#undef IUTEST_HAS_MATCHER_REGEX

#endif

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

#if defined(IUTEST_USE_GMOCK)

#define IUTEST_HAS_MATCHERS							1
#define IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF			1
#define IUTEST_HAS_MATCHER_ELEMENTSARE				1
#define IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD	0
#define IUTEST_HAS_MATCHER_REGEX					1

#define IUTEST_ASSERT_THAT		ASSERT_THAT
#define IUTEST_EXPECT_THAT		EXPECT_THAT
#define IUTEST_INFORM_THAT		INFORM_THAT
#define IUTEST_ASSUME_THAT		ASSUME_THAT

#define INFORM_THAT(value, matcher) \
	INFORM_PRED_FORMAT1(::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
#define ASSUME_THAT(value, matcher) \
	ASSUME_PRED_FORMAT1(::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
	
#else

#define IUTEST_HAS_MATCHERS							0
#define IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF			0
#define IUTEST_HAS_MATCHER_ELEMENTSARE				0
#define IUTEST_HAS_MATCHER_ELEMENTSAREARRAYFORWARD	0
#define IUTEST_HAS_MATCHER_REGEX					0

#endif

//======================================================================
// using
#if defined(IUTEST_USE_GMOCK)

namespace testing {
namespace matchers
{

	using ::testing::Not;
	using ::testing::Eq;
	using ::testing::Ne;
	using ::testing::Lt;
	using ::testing::Le;
	using ::testing::Gt;
	using ::testing::Ge;
	using ::testing::IsNull;
	using ::testing::NotNull;
	using ::testing::DoubleEq;
	using ::testing::FloatEq;

	using ::testing::NanSensitiveDoubleEq;
	using ::testing::NanSensitiveFloatEq;
	
	using ::testing::StrEq;
	using ::testing::StrNe;
	using ::testing::StrCaseEq;
	using ::testing::StrCaseNe;
	using ::testing::HasSubstr;
	using ::testing::StartsWith;
	using ::testing::EndsWith;

	using ::testing::Contains;
	using ::testing::Each;
	using ::testing::ContainerEq;
	using ::testing::Pointwise;
	using ::testing::Key;
	using ::testing::Pair;
	using ::testing::Field;
	using ::testing::Property;

	using ::testing::ResultOf;
	using ::testing::Pointee;

	using ::testing::ElementsAre;
	using ::testing::ElementsAreArray;

	using ::testing::MatchesRegex;
	using ::testing::ContainsRegex;

	using ::testing::AllOf;
	using ::testing::AnyOf;

	using ::testing::A;
	using ::testing::_;
	using ::testing::TypedEq;
	
	template<typename T>
	inline internal::EqMatcher<T> Equals(T x) { return Eq(x); }

#if GMOCK_VER >= 0x01070000
	// gmock 1.7 later
	using ::testing::IsEmpty;
	using ::testing::SizeIs;
#endif

}	// end of namespace matcher
}	// end of namespace testing

#endif

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_SKIP_HPP_3CFB2B8D_9C8D_4B4F_9843_2FE38126BB31_

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_assert.hpp
 * @brief		ASSERT フレーバー切り替え ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_ASSERT_HPP_F4AD6E1B_4B1F_40EE_A0CC_D454587B2C39_
#define INCG_IRIS_IUTEST_SWITCH_ASSERT_HPP_F4AD6E1B_4B1F_40EE_A0CC_D454587B2C39_

#if !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(GTEST_INCLUDE_GTEST_GTEST_H_)

#undef ASSERT_TRUE
#undef ASSERT_FALSE
#undef ASSERT_EQ
#undef ASSERT_NE
#undef ASSERT_LT
#undef ASSERT_LE
#undef ASSERT_GT
#undef ASSERT_GE
#undef ASSERT_NEAR
#undef ASSERT_FLOAT_EQ
#undef ASSERT_DOUBLE_EQ
#undef ASSERT_STREQ
#undef ASSERT_STRNE
#undef ASSERT_STRCASEEQ
#undef ASSERT_STRCASENE
#undef ASSERT_THROW
#undef ASSERT_NO_THROW
#undef ASSERT_ANY_THROW
#undef ASSERT_NO_FATAL_FAILURE
#undef ASSERT_PRED_FORMAT1
#undef ASSERT_PRED_FORMAT2
#undef ASSERT_PRED_FORMAT3
#undef ASSERT_PRED_FORMAT4
#undef ASSERT_PRED_FORMAT5
#undef ASSERT_PRED1
#undef ASSERT_PRED2
#undef ASSERT_PRED3
#undef ASSERT_PRED4
#undef ASSERT_PRED5

#ifdef GTEST_OS_WINDOWS
#undef ASSERT_HRESULT_SUCCEEDED
#undef ASSERT_HRESULT_FAILED
#endif

#endif

//======================================================================
// define
#define ASSERT_TRUE		IUTEST_ASSERT_TRUE
#define ASSERT_FALSE	IUTEST_ASSERT_FALSE
#define ASSERT_EQ		IUTEST_ASSERT_EQ
#define ASSERT_NE		IUTEST_ASSERT_NE
#define ASSERT_LT		IUTEST_ASSERT_LT
#define ASSERT_LE		IUTEST_ASSERT_LE
#define ASSERT_GT		IUTEST_ASSERT_GT
#define ASSERT_GE		IUTEST_ASSERT_GE
#define ASSERT_NEAR		IUTEST_ASSERT_NEAR
#define ASSERT_FLOAT_EQ		IUTEST_ASSERT_FLOAT_EQ
#define ASSERT_DOUBLE_EQ	IUTEST_ASSERT_DOUBLE_EQ
#define ASSERT_STREQ		IUTEST_ASSERT_STREQ
#define ASSERT_STRNE		IUTEST_ASSERT_STRNE
#define ASSERT_STRCASEEQ	IUTEST_ASSERT_STRCASEEQ
#define ASSERT_STRCASENE	IUTEST_ASSERT_STRCASENE
#define ASSERT_THROW		IUTEST_ASSERT_THROW
#define ASSERT_NO_THROW		IUTEST_ASSERT_NO_THROW
#define ASSERT_ANY_THROW	IUTEST_ASSERT_ANY_THROW
#define ASSERT_NO_FATAL_FAILURE	IUTEST_ASSERT_NO_FATAL_FAILURE

#ifdef IUTEST_OS_WINDOWS
#  define ASSERT_HRESULT_SUCCEEDED	IUTEST_ASSERT_HRESULT_SUCCEEDED
#  define ASSERT_HRESULT_FAILED		IUTEST_ASSERT_HRESULT_FAILED
#endif

#define ASSERT_PRED1	IUTEST_ASSERT_PRED1
#define ASSERT_PRED2	IUTEST_ASSERT_PRED2
#define ASSERT_PRED3	IUTEST_ASSERT_PRED3
#define ASSERT_PRED4	IUTEST_ASSERT_PRED4
#define ASSERT_PRED5	IUTEST_ASSERT_PRED5

#define ASSERT_PRED_FORMAT1	IUTEST_ASSERT_PRED_FORMAT1
#define ASSERT_PRED_FORMAT2	IUTEST_ASSERT_PRED_FORMAT2
#define ASSERT_PRED_FORMAT3	IUTEST_ASSERT_PRED_FORMAT3
#define ASSERT_PRED_FORMAT4	IUTEST_ASSERT_PRED_FORMAT4
#define ASSERT_PRED_FORMAT5	IUTEST_ASSERT_PRED_FORMAT5


#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#undef IUTEST_ASSERT
#undef IUTEST_ASSERT_NOT
#undef IUTEST_ASSERT_TRUE
#undef IUTEST_ASSERT_FALSE
#undef IUTEST_ASSERT_EQ
#undef IUTEST_ASSERT_NE
#undef IUTEST_ASSERT_LT
#undef IUTEST_ASSERT_LE
#undef IUTEST_ASSERT_GT
#undef IUTEST_ASSERT_GE
#undef IUTEST_ASSERT_NEAR
#undef IUTEST_ASSERT_NULL
#undef IUTEST_ASSERT_NOTNULL
#undef IUTEST_ASSERT_SAME
#undef IUTEST_ASSERT_FLOAT_EQ
#undef IUTEST_ASSERT_DOUBLE_EQ
#undef IUTEST_ASSERT_STREQ
#undef IUTEST_ASSERT_STRNE
#undef IUTEST_ASSERT_STRCASEEQ
#undef IUTEST_ASSERT_STRCASENE
#undef IUTEST_ASSERT_THROW
#undef IUTEST_ASSERT_NO_THROW
#undef IUTEST_ASSERT_ANY_THROW
#undef IUTEST_ASSERT_NO_FATAL_FAILURE
#undef IUTEST_ASSERT_PRED_FORMAT1
#undef IUTEST_ASSERT_PRED_FORMAT2
#undef IUTEST_ASSERT_PRED_FORMAT3
#undef IUTEST_ASSERT_PRED_FORMAT4
#undef IUTEST_ASSERT_PRED_FORMAT5
#undef IUTEST_ASSERT_PRED1
#undef IUTEST_ASSERT_PRED2
#undef IUTEST_ASSERT_PRED3
#undef IUTEST_ASSERT_PRED4
#undef IUTEST_ASSERT_PRED5

#ifdef IUTEST_OS_WINDOWS
#undef IUTEST_ASSERT_HRESULT_SUCCEEDED
#undef IUTEST_ASSERT_HRESULT_FAILED
#endif

#undef IUTEST_ASSERT_FAIL

#undef IUTEST_ASSERT_FAILURE

#endif

//======================================================================
// define
#define IUTEST_ASSERT(...)					ASSERT_TRUE(__VA_ARGS__)
#define IUTEST_ASSERT_NOT(...)				ASSERT_FALSE(__VA_ARGS__)
#define IUTEST_ASSERT_TRUE(...)				ASSERT_TRUE(!!(__VA_ARGS__))
#define IUTEST_ASSERT_FALSE(...)			ASSERT_FALSE((__VA_ARGS__))
#define IUTEST_ASSERT_EQ					ASSERT_EQ
#define IUTEST_ASSERT_NE(expected, actual)	ASSERT_PRED_FORMAT2(::testing::internal::NeHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, expected, actual)
#define IUTEST_ASSERT_LT					ASSERT_LT
#define IUTEST_ASSERT_LE					ASSERT_LE
#define IUTEST_ASSERT_GT					ASSERT_GT
#define IUTEST_ASSERT_GE					ASSERT_GE
#define IUTEST_ASSERT_NEAR					ASSERT_NEAR
#define IUTEST_ASSERT_NULL(v)				IUTEST_THROUGH_ANALYSIS_ASSUME((v) == NULL, ASSERT_EQ(NULL, v))
#define IUTEST_ASSERT_NOTNULL(v)			IUTEST_THROUGH_ANALYSIS_ASSUME((v) != NULL, ASSERT_TRUE(NULL != (v)))
#define IUTEST_ASSERT_SAME(v1, v2)			ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSame, v1, v2)
#define IUTEST_ASSERT_FLOAT_EQ				ASSERT_FLOAT_EQ
#define IUTEST_ASSERT_DOUBLE_EQ				ASSERT_DOUBLE_EQ
#define IUTEST_ASSERT_STREQ					ASSERT_STREQ
#define IUTEST_ASSERT_STRNE					ASSERT_STRNE
#define IUTEST_ASSERT_STRCASEEQ				ASSERT_STRCASEEQ
#define IUTEST_ASSERT_STRCASENE				ASSERT_STRCASENE
#define IUTEST_ASSERT_THROW(statement, expected_exception)		ASSERT_THROW((void)(statement), expected_exception)
#define IUTEST_ASSERT_NO_THROW(statement)						ASSERT_NO_THROW((void)(statement))
#define IUTEST_ASSERT_ANY_THROW(statement)						ASSERT_ANY_THROW((void)(statement))
#define IUTEST_ASSERT_NO_FATAL_FAILURE		ASSERT_NO_FATAL_FAILURE

#ifdef GTEST_OS_WINDOWS
#  define IUTEST_ASSERT_HRESULT_SUCCEEDED	ASSERT_HRESULT_SUCCEEDED
#  define IUTEST_ASSERT_HRESULT_FAILED		ASSERT_HRESULT_FAILED
#endif

#define IUTEST_ASSERT_PRED1	ASSERT_PRED1
#define IUTEST_ASSERT_PRED2	ASSERT_PRED2
#define IUTEST_ASSERT_PRED3	ASSERT_PRED3
#define IUTEST_ASSERT_PRED4	ASSERT_PRED4
#define IUTEST_ASSERT_PRED5	ASSERT_PRED5

#define IUTEST_ASSERT_PRED_FORMAT1	ASSERT_PRED_FORMAT1
#define IUTEST_ASSERT_PRED_FORMAT2	ASSERT_PRED_FORMAT2
#define IUTEST_ASSERT_PRED_FORMAT3	ASSERT_PRED_FORMAT3
#define IUTEST_ASSERT_PRED_FORMAT4	ASSERT_PRED_FORMAT4
#define IUTEST_ASSERT_PRED_FORMAT5	ASSERT_PRED_FORMAT5

#define IUTEST_ASSERT_FAIL		GTEST_FAIL

#define IUTEST_ASSERT_FAILURE	GTEST_FATAL_FAILURE_

#endif // !defined(IUTEST_USE_GTEST)

#define ASSERT_NULL		IUTEST_ASSERT_NULL
#define ASSERT_NOTNULL	IUTEST_ASSERT_NOTNULL
#define ASSERT_SAME		IUTEST_ASSERT_SAME

#endif // INCG_IRIS_IUTEST_SWITCH_ASSERT_HPP_F4AD6E1B_4B1F_40EE_A0CC_D454587B2C39_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_expect.hpp
 * @brief		EXPECT フレーバー切り替え ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_EXPECT_HPP_F4AD6E1B_4B1F_40EE_A0CC_D454587B2C39_
#define INCG_IRIS_IUTEST_SWITCH_EXPECT_HPP_F4AD6E1B_4B1F_40EE_A0CC_D454587B2C39_

#if !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#ifdef GTEST_INCLUDE_GTEST_GTEST_H_

#undef EXPECT_TRUE
#undef EXPECT_FALSE
#undef EXPECT_EQ
#undef EXPECT_NE
#undef EXPECT_LT
#undef EXPECT_LE
#undef EXPECT_GT
#undef EXPECT_GE
#undef EXPECT_NEAR
#undef EXPECT_FLOAT_EQ
#undef EXPECT_DOUBLE_EQ
#undef EXPECT_STREQ
#undef EXPECT_STRNE
#undef EXPECT_STRCASEEQ
#undef EXPECT_STRCASENE
#undef EXPECT_THROW
#undef EXPECT_NO_THROW
#undef EXPECT_ANY_THROW
#undef EXPECT_NO_FATAL_FAILURE
#undef EXPECT_PRED_FORMAT1
#undef EXPECT_PRED_FORMAT2
#undef EXPECT_PRED_FORMAT3
#undef EXPECT_PRED_FORMAT4
#undef EXPECT_PRED_FORMAT5
#undef EXPECT_PRED1
#undef EXPECT_PRED2
#undef EXPECT_PRED3
#undef EXPECT_PRED4
#undef EXPECT_PRED5

#ifdef GTEST_OS_WINDOWS
#undef EXPECT_HRESULT_SUCCEEDED
#undef EXPECT_HRESULT_FAILED
#endif

#endif

//======================================================================
// define
#define EXPECT_TRUE		IUTEST_EXPECT_TRUE
#define EXPECT_FALSE	IUTEST_EXPECT_FALSE
#define EXPECT_EQ		IUTEST_EXPECT_EQ
#define EXPECT_NE		IUTEST_EXPECT_NE
#define EXPECT_LT		IUTEST_EXPECT_LT
#define EXPECT_LE		IUTEST_EXPECT_LE
#define EXPECT_GT		IUTEST_EXPECT_GT
#define EXPECT_GE		IUTEST_EXPECT_GE
#define EXPECT_NEAR		IUTEST_EXPECT_NEAR
#define EXPECT_FLOAT_EQ		IUTEST_EXPECT_FLOAT_EQ
#define EXPECT_DOUBLE_EQ	IUTEST_EXPECT_DOUBLE_EQ
#define EXPECT_STREQ		IUTEST_EXPECT_STREQ
#define EXPECT_STRNE		IUTEST_EXPECT_STRNE
#define EXPECT_STRCASEEQ	IUTEST_EXPECT_STRCASEEQ
#define EXPECT_STRCASENE	IUTEST_EXPECT_STRCASENE
#define EXPECT_THROW		IUTEST_EXPECT_THROW
#define EXPECT_NO_THROW		IUTEST_EXPECT_NO_THROW
#define EXPECT_ANY_THROW	IUTEST_EXPECT_ANY_THROW
#define EXPECT_NO_FATAL_FAILURE	IUTEST_EXPECT_NO_FATAL_FAILURE

#ifdef IUTEST_OS_WINDOWS
#  define EXPECT_HRESULT_SUCCEEDED	IUTEST_EXPECT_HRESULT_SUCCEEDED
#  define EXPECT_HRESULT_FAILED		IUTEST_EXPECT_HRESULT_FAILED
#endif

#define EXPECT_PRED1	IUTEST_EXPECT_PRED1
#define EXPECT_PRED2	IUTEST_EXPECT_PRED2
#define EXPECT_PRED3	IUTEST_EXPECT_PRED3
#define EXPECT_PRED4	IUTEST_EXPECT_PRED4
#define EXPECT_PRED5	IUTEST_EXPECT_PRED5

#define EXPECT_PRED_FORMAT1	IUTEST_EXPECT_PRED_FORMAT1
#define EXPECT_PRED_FORMAT2	IUTEST_EXPECT_PRED_FORMAT2
#define EXPECT_PRED_FORMAT3	IUTEST_EXPECT_PRED_FORMAT3
#define EXPECT_PRED_FORMAT4	IUTEST_EXPECT_PRED_FORMAT4
#define EXPECT_PRED_FORMAT5	IUTEST_EXPECT_PRED_FORMAT5


#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#ifdef INCG_IRIS_IUTEST_HPP_

#undef IUTEST_EXPECT
#undef IUTEST_EXPECT_NOT
#undef IUTEST_EXPECT_TRUE
#undef IUTEST_EXPECT_FALSE
#undef IUTEST_EXPECT_EQ
#undef IUTEST_EXPECT_NE
#undef IUTEST_EXPECT_LT
#undef IUTEST_EXPECT_LE
#undef IUTEST_EXPECT_GT
#undef IUTEST_EXPECT_GE
#undef IUTEST_EXPECT_NEAR
#undef IUTEST_EXPECT_NULL
#undef IUTEST_EXPECT_NOTNULL
#undef IUTEST_EXPECT_SAME
#undef IUTEST_EXPECT_FLOAT_EQ
#undef IUTEST_EXPECT_DOUBLE_EQ
#undef IUTEST_EXPECT_STREQ
#undef IUTEST_EXPECT_STRNE
#undef IUTEST_EXPECT_STRCASEEQ
#undef IUTEST_EXPECT_STRCASENE
#undef IUTEST_EXPECT_THROW
#undef IUTEST_EXPECT_NO_THROW
#undef IUTEST_EXPECT_ANY_THROW
#undef IUTEST_EXPECT_NO_FATAL_FAILURE
#undef IUTEST_EXPECT_PRED_FORMAT1
#undef IUTEST_EXPECT_PRED_FORMAT2
#undef IUTEST_EXPECT_PRED_FORMAT3
#undef IUTEST_EXPECT_PRED_FORMAT4
#undef IUTEST_EXPECT_PRED_FORMAT5
#undef IUTEST_EXPECT_PRED1
#undef IUTEST_EXPECT_PRED2
#undef IUTEST_EXPECT_PRED3
#undef IUTEST_EXPECT_PRED4
#undef IUTEST_EXPECT_PRED5

#ifdef IUTEST_OS_WINDOWS
#undef IUTEST_EXPECT_HRESULT_SUCCEEDED
#undef IUTEST_EXPECT_HRESULT_FAILED
#endif

#undef IUTEST_EXPECT_FAIL
#undef IUTEST_EXPECT_FAIL_AT

#undef IUTEST_EXPECT_FAILURE

#endif

//======================================================================
// define
#define IUTEST_EXPECT(...)					EXPECT_TRUE(__VA_ARGS__)
#define IUTEST_EXPECT_NOT(...)				EXPECT_FALSE(__VA_ARGS__)
#define IUTEST_EXPECT_TRUE(...)				EXPECT_TRUE(!!(__VA_ARGS__))
#define IUTEST_EXPECT_FALSE(...)			EXPECT_FALSE((__VA_ARGS__))
#define IUTEST_EXPECT_EQ					EXPECT_EQ
#define IUTEST_EXPECT_NE(expected, actual)	EXPECT_PRED_FORMAT2(::testing::internal::NeHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, expected, actual)
#define IUTEST_EXPECT_LT					EXPECT_LT
#define IUTEST_EXPECT_LE					EXPECT_LE
#define IUTEST_EXPECT_GT					EXPECT_GT
#define IUTEST_EXPECT_GE					EXPECT_GE
#define IUTEST_EXPECT_NEAR					EXPECT_NEAR
#define IUTEST_EXPECT_NULL(v)				EXPECT_EQ(NULL, v)
#define IUTEST_EXPECT_NOTNULL(v)			EXPECT_TRUE(NULL != (v))
#define IUTEST_EXPECT_SAME(v1, v2)			EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSame, v1, v2)
#define IUTEST_EXPECT_FLOAT_EQ				EXPECT_FLOAT_EQ
#define IUTEST_EXPECT_DOUBLE_EQ				EXPECT_DOUBLE_EQ
#define IUTEST_EXPECT_STREQ					EXPECT_STREQ
#define IUTEST_EXPECT_STRNE					EXPECT_STRNE
#define IUTEST_EXPECT_STRCASEEQ				EXPECT_STRCASEEQ
#define IUTEST_EXPECT_STRCASENE				EXPECT_STRCASENE
#define IUTEST_EXPECT_THROW(statement, expected_exception)	EXPECT_THROW((void)(statement), expected_exception)
#define IUTEST_EXPECT_NO_THROW(statement)					EXPECT_NO_THROW((void)(statement))
#define IUTEST_EXPECT_ANY_THROW(statement)					EXPECT_ANY_THROW((void)(statement))
#define IUTEST_EXPECT_NO_FATAL_FAILURE		EXPECT_NO_FATAL_FAILURE

#ifdef GTEST_OS_WINDOWS
#  define IUTEST_EXPECT_HRESULT_SUCCEEDED	EXPECT_HRESULT_SUCCEEDED
#  define IUTEST_EXPECT_HRESULT_FAILED		EXPECT_HRESULT_FAILED
#endif

#define IUTEST_EXPECT_PRED1	EXPECT_PRED1
#define IUTEST_EXPECT_PRED2	EXPECT_PRED2
#define IUTEST_EXPECT_PRED3	EXPECT_PRED3
#define IUTEST_EXPECT_PRED4	EXPECT_PRED4
#define IUTEST_EXPECT_PRED5	EXPECT_PRED5

#define IUTEST_EXPECT_PRED_FORMAT1	EXPECT_PRED_FORMAT1
#define IUTEST_EXPECT_PRED_FORMAT2	EXPECT_PRED_FORMAT2
#define IUTEST_EXPECT_PRED_FORMAT3	EXPECT_PRED_FORMAT3
#define IUTEST_EXPECT_PRED_FORMAT4	EXPECT_PRED_FORMAT4
#define IUTEST_EXPECT_PRED_FORMAT5	EXPECT_PRED_FORMAT5

#define IUTEST_EXPECT_FAIL		ADD_FAILURE
#define IUTEST_EXPECT_FAIL_AT	ADD_FAILURE_AT

#define IUTEST_EXPECT_FAILURE	GTEST_NONFATAL_FAILURE_

#endif // !defined(IUTEST_USE_GTEST)

#define EXPECT_NULL		IUTEST_EXPECT_NULL
#define EXPECT_NOTNULL	IUTEST_EXPECT_NOTNULL
#define EXPECT_SAME		IUTEST_EXPECT_SAME

#endif // INCG_IRIS_IUTEST_SWITCH_EXPECT_HPP_F4AD6E1B_4B1F_40EE_A0CC_D454587B2C39_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_inform.hpp
 * @brief		INFORM フレーバー切り替え ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_INFORM_HPP_F4AD6E1B_4B1F_40EE_A0CC_D454587B2C39_
#define INCG_IRIS_IUTEST_SWITCH_INFORM_HPP_F4AD6E1B_4B1F_40EE_A0CC_D454587B2C39_

#if !defined(IUTEST_USE_GTEST)

//======================================================================
// define
#define INFORM_TRUE		IUTEST_INFORM_TRUE
#define INFORM_FALSE	IUTEST_INFORM_FALSE
#define INFORM_EQ		IUTEST_INFORM_EQ
#define INFORM_NE		IUTEST_INFORM_NE
#define INFORM_LT		IUTEST_INFORM_LT
#define INFORM_LE		IUTEST_INFORM_LE
#define INFORM_GT		IUTEST_INFORM_GT
#define INFORM_GE		IUTEST_INFORM_GE
#define INFORM_NEAR		IUTEST_INFORM_NEAR
#define INFORM_FLOAT_EQ		IUTEST_INFORM_FLOAT_EQ
#define INFORM_DOUBLE_EQ	IUTEST_INFORM_DOUBLE_EQ
#define INFORM_STREQ		IUTEST_INFORM_STREQ
#define INFORM_STRNE		IUTEST_INFORM_STRNE
#define INFORM_STRCASEEQ	IUTEST_INFORM_STRCASEEQ
#define INFORM_STRCASENE	IUTEST_INFORM_STRCASENE
#define INFORM_THROW		IUTEST_INFORM_THROW
#define INFORM_NO_THROW		IUTEST_INFORM_NO_THROW
#define INFORM_ANY_THROW	IUTEST_INFORM_ANY_THROW
#define INFORM_NO_FATAL_FAILURE	IUTEST_INFORM_NO_FATAL_FAILURE

#ifdef IUTEST_OS_WINDOWS
#  define INFORM_HRESULT_SUCCEEDED	IUTEST_INFORM_HRESULT_SUCCEEDED
#  define INFORM_HRESULT_FAILED		IUTEST_INFORM_HRESULT_FAILED
#endif

#define INFORM_PRED1	IUTEST_INFORM_PRED1
#define INFORM_PRED2	IUTEST_INFORM_PRED2
#define INFORM_PRED3	IUTEST_INFORM_PRED3
#define INFORM_PRED4	IUTEST_INFORM_PRED4
#define INFORM_PRED5	IUTEST_INFORM_PRED5

#define INFORM_PRED_FORMAT1	IUTEST_INFORM_PRED_FORMAT1
#define INFORM_PRED_FORMAT2	IUTEST_INFORM_PRED_FORMAT2
#define INFORM_PRED_FORMAT3	IUTEST_INFORM_PRED_FORMAT3
#define INFORM_PRED_FORMAT4	IUTEST_INFORM_PRED_FORMAT4
#define INFORM_PRED_FORMAT5	IUTEST_INFORM_PRED_FORMAT5


#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#ifdef INCG_IRIS_IUTEST_HPP_

#undef IUTEST_INFORM
#undef IUTEST_INFORM_NOT
#undef IUTEST_INFORM_TRUE
#undef IUTEST_INFORM_FALSE
#undef IUTEST_INFORM_EQ
#undef IUTEST_INFORM_NE
#undef IUTEST_INFORM_LT
#undef IUTEST_INFORM_LE
#undef IUTEST_INFORM_GT
#undef IUTEST_INFORM_GE
#undef IUTEST_INFORM_NEAR
#undef IUTEST_INFORM_NULL
#undef IUTEST_INFORM_NOTNULL
#undef IUTEST_INFORM_SAME
#undef IUTEST_INFORM_FLOAT_EQ
#undef IUTEST_INFORM_DOUBLE_EQ
#undef IUTEST_INFORM_STREQ
#undef IUTEST_INFORM_STRNE
#undef IUTEST_INFORM_STRCASEEQ
#undef IUTEST_INFORM_STRCASENE
#undef IUTEST_INFORM_THROW
#undef IUTEST_INFORM_NO_THROW
#undef IUTEST_INFORM_ANY_THROW
#undef IUTEST_INFORM_NO_FATAL_FAILURE
#undef IUTEST_INFORM_PRED_FORMAT1
#undef IUTEST_INFORM_PRED_FORMAT2
#undef IUTEST_INFORM_PRED_FORMAT3
#undef IUTEST_INFORM_PRED_FORMAT4
#undef IUTEST_INFORM_PRED_FORMAT5
#undef IUTEST_INFORM_PRED1
#undef IUTEST_INFORM_PRED2
#undef IUTEST_INFORM_PRED3
#undef IUTEST_INFORM_PRED4
#undef IUTEST_INFORM_PRED5

#ifdef IUTEST_OS_WINDOWS
#undef IUTEST_INFORM_HRESULT_SUCCEEDED
#undef IUTEST_INFORM_HRESULT_FAILED
#endif

#undef IUTEST_INFORM_FAILURE

#endif

//======================================================================
// define
// INFORM 対応のために、初期化関数を呼ぶ
#ifdef RUN_ALL_TESTS
#  undef RUN_ALL_TESTS
#endif
#define RUN_ALL_TESTS()			(::testing::inform_support::AppendInformSupportPrinter(), (::testing::UnitTest::GetInstance()->Run()))

//	INFORM 対応
#define GTEST_INFORM_FAILURE_(message) \
	GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)

#define INFORM_PRED_FORMAT1(pred_format, v1) \
	GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_INFORM_FAILURE_)
#define INFORM_PRED1(pred, v1) \
	GTEST_PRED1_(pred, v1, GTEST_INFORM_FAILURE_)

#define INFORM_PRED_FORMAT2(pred_format, v1, v2) \
	GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_INFORM_FAILURE_)
#define INFORM_PRED2(pred, v1, v2) \
	GTEST_PRED2_(pred, v1, v2, GTEST_INFORM_FAILURE_)

#define INFORM_PRED_FORMAT3(pred_format, v1, v2, v3) \
	GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_INFORM_FAILURE_)
#define INFORM_PRED3(pred, v1, v2, v3) \
	GTEST_PRED3_(pred, v1, v2, v3, GTEST_INFORM_FAILURE_)

#define INFORM_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
	GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_INFORM_FAILURE_)
#define INFORM_PRED4(pred, v1, v2, v3, v4) \
	GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_INFORM_FAILURE_)

#define INFORM_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
	GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_INFORM_FAILURE_)
#define INFORM_PRED5(pred, v1, v2, v3, v4, v5) \
	GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_INFORM_FAILURE_)


#define INFORM_TRUE(condition)	GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_INFORM_FAILURE_)
#define INFORM_FALSE(condition)	GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, GTEST_INFORM_FAILURE_)

#define INFORM_EQ(expected, actual) \
	INFORM_PRED_FORMAT2(::testing::internal:: \
	EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \
	expected, actual)
#define INFORM_NE(expected, actual) \
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual)
#define INFORM_LE(val1, val2) \
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
#define INFORM_LT(val1, val2) \
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
#define INFORM_GE(val1, val2) \
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
#define INFORM_GT(val1, val2) \
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)

#define INFORM_STREQ(expected, actual) \
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
#define INFORM_STRNE(s1, s2) \
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
#define INFORM_STRCASEEQ(expected, actual) \
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
#define INFORM_STRCASENE(s1, s2)\
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)

#define INFORM_FLOAT_EQ(expected, actual)\
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
	expected, actual)
#define INFORM_DOUBLE_EQ(expected, actual)\
	INFORM_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
	expected, actual)
#define INFORM_NEAR(val1, val2, abs_error)\
	INFORM_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
	val1, val2, abs_error)

#define INFORM_THROW(statement, expected_exception) \
	GTEST_TEST_THROW_(statement, expected_exception, GTEST_INFORM_FAILURE_)
#define INFORM_NO_THROW(statement) \
	GTEST_TEST_NO_THROW_(statement, GTEST_INFORM_FAILURE_)
#define INFORM_ANY_THROW(statement) \
	GTEST_TEST_ANY_THROW_(statement, GTEST_INFORM_FAILURE_)

#define INFORM_NO_FATAL_FAILURE(statement) \
	GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_INFORM_FAILURE_)

#define IUTEST_INFORM(...)					INFORM_TRUE(__VA_ARGS__)
#define IUTEST_INFORM_NOT(...)				INFORM_FALSE(__VA_ARGS__)
#define IUTEST_INFORM_TRUE(...)				INFORM_TRUE(!!(__VA_ARGS__))
#define IUTEST_INFORM_FALSE(...)			INFORM_FALSE((__VA_ARGS__))
#define IUTEST_INFORM_EQ					INFORM_EQ
#define IUTEST_INFORM_NE(expected, actual)	INFORM_PRED_FORMAT2(::testing::internal::NeHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, expected, actual)
#define IUTEST_INFORM_LT					INFORM_LT
#define IUTEST_INFORM_LE					INFORM_LE
#define IUTEST_INFORM_GT					INFORM_GT
#define IUTEST_INFORM_GE					INFORM_GE
#define IUTEST_INFORM_NULL(v)				INFORM_EQ(NULL, v)
#define IUTEST_INFORM_NOTNULL(v)			INFORM_TRUE(NULL != (v))
#define IUTEST_INFORM_SAME(v1, v2)			INFORM_PRED_FORMAT2(::testing::internal::CmpHelperSame, v1, v2)
#define IUTEST_INFORM_NEAR					INFORM_NEAR
#define IUTEST_INFORM_FLOAT_EQ				INFORM_FLOAT_EQ
#define IUTEST_INFORM_DOUBLE_EQ				INFORM_DOUBLE_EQ
#define IUTEST_INFORM_STREQ					INFORM_STREQ
#define IUTEST_INFORM_STRNE					INFORM_STRNE
#define IUTEST_INFORM_STRCASEEQ				INFORM_STRCASEEQ
#define IUTEST_INFORM_STRCASENE				INFORM_STRCASENE
#define IUTEST_INFORM_THROW(statement, expected_exception)	INFORM_THROW((void)(statement), expected_exception)
#define IUTEST_INFORM_NO_THROW(statement)	INFORM_NO_THROW((void)(statement))
#define IUTEST_INFORM_ANY_THROW(statement)	INFORM_ANY_THROW((void)(statement))
#define IUTEST_INFORM_NO_FATAL_FAILURE		INFORM_NO_FATAL_FAILURE

#ifdef GTEST_OS_WINDOWS
# define INFORM_HRESULT_SUCCEEDED(expr) \
	INFORM_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
# define INFORM_HRESULT_FAILED(expr) \
	INFORM_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))

#  define IUTEST_INFORM_HRESULT_SUCCEEDED	INFORM_HRESULT_SUCCEEDED
#  define IUTEST_INFORM_HRESULT_FAILED		INFORM_HRESULT_FAILED
#endif

#define IUTEST_INFORM_PRED1	INFORM_PRED1
#define IUTEST_INFORM_PRED2	INFORM_PRED2
#define IUTEST_INFORM_PRED3	INFORM_PRED3
#define IUTEST_INFORM_PRED4	INFORM_PRED4
#define IUTEST_INFORM_PRED5	INFORM_PRED5

#define IUTEST_INFORM_PRED_FORMAT1	INFORM_PRED_FORMAT1
#define IUTEST_INFORM_PRED_FORMAT2	INFORM_PRED_FORMAT2
#define IUTEST_INFORM_PRED_FORMAT3	INFORM_PRED_FORMAT3
#define IUTEST_INFORM_PRED_FORMAT4	INFORM_PRED_FORMAT4
#define IUTEST_INFORM_PRED_FORMAT5	INFORM_PRED_FORMAT5

#define IUTEST_INFORM_FAILURE	GTEST_INFORM_FAILURE_

//======================================================================
// class
namespace testing
{

namespace inform_support
{
	class DefaultPrinter : public ::testing::EmptyTestEventListener
	{
	private:
		virtual void OnTestPartResult(const TestPartResult& test_part_result)
		{
			if( ::testing::UnitTest::GetInstance()->listeners().default_result_printer() == NULL ) return;

			if( test_part_result.type() == TestPartResult::kSuccess )
			{
				// 成功のときに出力
				TestPartResult tmp(TestPartResult::kNonFatalFailure
					, test_part_result.file_name()
					, test_part_result.line_number()
					, test_part_result.message());
				::testing::UnitTest::GetInstance()->listeners().default_result_printer()->OnTestPartResult(tmp);
			}
		}
	};
	inline void AppendInformSupportPrinter(void)
	{
		// INFORM 用に printer を追加
		::testing::UnitTest::GetInstance()->listeners().Append( new DefaultPrinter() );
	}
}

}

#endif // !defined(IUTEST_USE_GTEST)

#define INFORM_NULL		IUTEST_INFORM_NULL
#define INFORM_NOTNULL	IUTEST_INFORM_NOTNULL
#define INFORM_SAME		IUTEST_INFORM_SAME

#endif // INCG_IRIS_IUTEST_SWITCH_INFORM_HPP_F4AD6E1B_4B1F_40EE_A0CC_D454587B2C39_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_assume.hpp
 * @brief		ASSUME フレーバー切り替え ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2013-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_ASSUME_HPP_E22A3162_D581_4F4F_A344_F5D701B21F53_
#define INCG_IRIS_IUTEST_SWITCH_ASSUME_HPP_E22A3162_D581_4F4F_A344_F5D701B21F53_

#if !defined(IUTEST_USE_GTEST)

//======================================================================
// define
#define ASSUME_TRUE		IUTEST_ASSUME_TRUE
#define ASSUME_FALSE	IUTEST_ASSUME_FALSE
#define ASSUME_EQ		IUTEST_ASSUME_EQ
#define ASSUME_NE		IUTEST_ASSUME_NE
#define ASSUME_LT		IUTEST_ASSUME_LT
#define ASSUME_LE		IUTEST_ASSUME_LE
#define ASSUME_GT		IUTEST_ASSUME_GT
#define ASSUME_GE		IUTEST_ASSUME_GE
#define ASSUME_NEAR		IUTEST_ASSUME_NEAR
#define ASSUME_FLOAT_EQ		IUTEST_ASSUME_FLOAT_EQ
#define ASSUME_DOUBLE_EQ	IUTEST_ASSUME_DOUBLE_EQ
#define ASSUME_STREQ		IUTEST_ASSUME_STREQ
#define ASSUME_STRNE		IUTEST_ASSUME_STRNE
#define ASSUME_STRCASEEQ	IUTEST_ASSUME_STRCASEEQ
#define ASSUME_STRCASENE	IUTEST_ASSUME_STRCASENE
#define ASSUME_THROW		IUTEST_ASSUME_THROW
#define ASSUME_NO_THROW		IUTEST_ASSUME_NO_THROW
#define ASSUME_ANY_THROW	IUTEST_ASSUME_ANY_THROW
#define ASSUME_NO_FATAL_FAILURE	IUTEST_ASSUME_NO_FATAL_FAILURE

#ifdef IUTEST_OS_WINDOWS
#  define ASSUME_HRESULT_SUCCEEDED	IUTEST_ASSUME_HRESULT_SUCCEEDED
#  define ASSUME_HRESULT_FAILED		IUTEST_ASSUME_HRESULT_FAILED
#endif

#define ASSUME_PRED1	IUTEST_ASSUME_PRED1
#define ASSUME_PRED2	IUTEST_ASSUME_PRED2
#define ASSUME_PRED3	IUTEST_ASSUME_PRED3
#define ASSUME_PRED4	IUTEST_ASSUME_PRED4
#define ASSUME_PRED5	IUTEST_ASSUME_PRED5

#define ASSUME_PRED_FORMAT1	IUTEST_ASSUME_PRED_FORMAT1
#define ASSUME_PRED_FORMAT2	IUTEST_ASSUME_PRED_FORMAT2
#define ASSUME_PRED_FORMAT3	IUTEST_ASSUME_PRED_FORMAT3
#define ASSUME_PRED_FORMAT4	IUTEST_ASSUME_PRED_FORMAT4
#define ASSUME_PRED_FORMAT5	IUTEST_ASSUME_PRED_FORMAT5


#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#undef IUTEST_ASSUME
#undef IUTEST_ASSUME_NOT
#undef IUTEST_ASSUME_TRUE
#undef IUTEST_ASSUME_FALSE
#undef IUTEST_ASSUME_EQ
#undef IUTEST_ASSUME_NE
#undef IUTEST_ASSUME_LT
#undef IUTEST_ASSUME_LE
#undef IUTEST_ASSUME_GT
#undef IUTEST_ASSUME_GE
#undef IUTEST_ASSUME_NEAR
#undef IUTEST_ASSUME_NULL
#undef IUTEST_ASSUME_NOTNULL
#undef IUTEST_ASSUME_SAME
#undef IUTEST_ASSUME_FLOAT_EQ
#undef IUTEST_ASSUME_DOUBLE_EQ
#undef IUTEST_ASSUME_STREQ
#undef IUTEST_ASSUME_STRNE
#undef IUTEST_ASSUME_STRCASEEQ
#undef IUTEST_ASSUME_STRCASENE
#undef IUTEST_ASSUME_THROW
#undef IUTEST_ASSUME_NO_THROW
#undef IUTEST_ASSUME_ANY_THROW
#undef IUTEST_ASSUME_NO_FATAL_FAILURE
#undef IUTEST_ASSUME_PRED_FORMAT1
#undef IUTEST_ASSUME_PRED_FORMAT2
#undef IUTEST_ASSUME_PRED_FORMAT3
#undef IUTEST_ASSUME_PRED_FORMAT4
#undef IUTEST_ASSUME_PRED_FORMAT5
#undef IUTEST_ASSUME_PRED1
#undef IUTEST_ASSUME_PRED2
#undef IUTEST_ASSUME_PRED3
#undef IUTEST_ASSUME_PRED4
#undef IUTEST_ASSUME_PRED5

#ifdef IUTEST_OS_WINDOWS
#undef IUTEST_ASSUME_HRESULT_SUCCEEDED
#undef IUTEST_ASSUME_HRESULT_FAILED
#endif

#undef IUTEST_ASSUME_FAILURE

#endif

//======================================================================
// define
#define GTEST_ASSUME_FAILURE_(message) \
	return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)

#define ASSUME_PRED_FORMAT1(pred_format, v1) \
	GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_ASSUME_FAILURE_)
#define ASSUME_PRED1(pred, v1) \
	GTEST_PRED1_(pred, v1, GTEST_ASSUME_FAILURE_)

#define ASSUME_PRED_FORMAT2(pred_format, v1, v2) \
	GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_ASSUME_FAILURE_)
#define ASSUME_PRED2(pred, v1, v2) \
	GTEST_PRED2_(pred, v1, v2, GTEST_ASSUME_FAILURE_)

#define ASSUME_PRED_FORMAT3(pred_format, v1, v2, v3) \
	GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_ASSUME_FAILURE_)
#define ASSUME_PRED3(pred, v1, v2, v3) \
	GTEST_PRED3_(pred, v1, v2, v3, GTEST_ASSUME_FAILURE_)

#define ASSUME_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
	GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_ASSUME_FAILURE_)
#define ASSUME_PRED4(pred, v1, v2, v3, v4) \
	GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_ASSUME_FAILURE_)

#define ASSUME_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
	GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_ASSUME_FAILURE_)
#define ASSUME_PRED5(pred, v1, v2, v3, v4, v5) \
	GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_ASSUME_FAILURE_)


#define ASSUME_TRUE(condition)	GTEST_TEST_BOOLEAN_(condition, #condition, false, true, GTEST_ASSUME_FAILURE_)
#define ASSUME_FALSE(condition)	GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, GTEST_ASSUME_FAILURE_)

#define ASSUME_EQ(expected, actual) \
	ASSUME_PRED_FORMAT2(::testing::internal:: \
	EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \
	expected, actual)
#define ASSUME_NE(expected, actual) \
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual)
#define ASSUME_LE(val1, val2) \
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2)
#define ASSUME_LT(val1, val2) \
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2)
#define ASSUME_GE(val1, val2) \
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2)
#define ASSUME_GT(val1, val2) \
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)

#define ASSUME_STREQ(expected, actual) \
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual)
#define ASSUME_STRNE(s1, s2) \
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2)
#define ASSUME_STRCASEEQ(expected, actual) \
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual)
#define ASSUME_STRCASENE(s1, s2)\
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2)

#define ASSUME_FLOAT_EQ(expected, actual)\
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \
	expected, actual)
#define ASSUME_DOUBLE_EQ(expected, actual)\
	ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \
	expected, actual)
#define ASSUME_NEAR(val1, val2, abs_error)\
	ASSUME_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \
	val1, val2, abs_error)

#define ASSUME_THROW(statement, expected_exception) \
	GTEST_TEST_THROW_(statement, expected_exception, GTEST_ASSUME_FAILURE_)
#define ASSUME_NO_THROW(statement) \
	GTEST_TEST_NO_THROW_(statement, GTEST_ASSUME_FAILURE_)
#define ASSUME_ANY_THROW(statement) \
	GTEST_TEST_ANY_THROW_(statement, GTEST_ASSUME_FAILURE_)

#define ASSUME_NO_FATAL_FAILURE(statement) \
	GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_ASSUME_FAILURE_)

#define IUTEST_ASSUME(...)					ASSUME_TRUE(__VA_ARGS__)
#define IUTEST_ASSUME_NOT(...)				ASSUME_FALSE(__VA_ARGS__)
#define IUTEST_ASSUME_TRUE(...)				ASSUME_TRUE(!!(__VA_ARGS__))
#define IUTEST_ASSUME_FALSE(...)			ASSUME_FALSE((__VA_ARGS__))
#define IUTEST_ASSUME_EQ					ASSUME_EQ
#define IUTEST_ASSUME_NE(expected, actual)	ASSUME_PRED_FORMAT2(::testing::internal::NeHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, expected, actual)
#define IUTEST_ASSUME_LT					ASSUME_LT
#define IUTEST_ASSUME_LE					ASSUME_LE
#define IUTEST_ASSUME_GT					ASSUME_GT
#define IUTEST_ASSUME_GE					ASSUME_GE
#define IUTEST_ASSUME_NULL(v)				ASSUME_EQ(NULL, v)
#define IUTEST_ASSUME_NOTNULL(v)			ASSUME_TRUE(NULL != (v))
#define IUTEST_ASSUME_SAME(v1, v2)			ASSUME_PRED_FORMAT2(::testing::internal::CmpHelperSame, v1, v2)
#define IUTEST_ASSUME_NEAR					ASSUME_NEAR
#define IUTEST_ASSUME_FLOAT_EQ				ASSUME_FLOAT_EQ
#define IUTEST_ASSUME_DOUBLE_EQ				ASSUME_DOUBLE_EQ
#define IUTEST_ASSUME_STREQ					ASSUME_STREQ
#define IUTEST_ASSUME_STRNE					ASSUME_STRNE
#define IUTEST_ASSUME_STRCASEEQ				ASSUME_STRCASEEQ
#define IUTEST_ASSUME_STRCASENE				ASSUME_STRCASENE
#define IUTEST_ASSUME_THROW(statement, expected_exception)	ASSUME_THROW((void)(statement), expected_exception)
#define IUTEST_ASSUME_NO_THROW(statement)	ASSUME_NO_THROW((void)(statement))
#define IUTEST_ASSUME_ANY_THROW(statement)	ASSUME_ANY_THROW((void)(statement))
#define IUTEST_ASSUME_NO_FATAL_FAILURE		ASSUME_NO_FATAL_FAILURE

#ifdef GTEST_OS_WINDOWS
# define ASSUME_HRESULT_SUCCEEDED(expr) \
	ASSUME_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr))
# define ASSUME_HRESULT_FAILED(expr) \
	ASSUME_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr))

#  define IUTEST_ASSUME_HRESULT_SUCCEEDED	ASSUME_HRESULT_SUCCEEDED
#  define IUTEST_ASSUME_HRESULT_FAILED		ASSUME_HRESULT_FAILED
#endif

#define IUTEST_ASSUME_PRED1	ASSUME_PRED1
#define IUTEST_ASSUME_PRED2	ASSUME_PRED2
#define IUTEST_ASSUME_PRED3	ASSUME_PRED3
#define IUTEST_ASSUME_PRED4	ASSUME_PRED4
#define IUTEST_ASSUME_PRED5	ASSUME_PRED5

#define IUTEST_ASSUME_PRED_FORMAT1	ASSUME_PRED_FORMAT1
#define IUTEST_ASSUME_PRED_FORMAT2	ASSUME_PRED_FORMAT2
#define IUTEST_ASSUME_PRED_FORMAT3	ASSUME_PRED_FORMAT3
#define IUTEST_ASSUME_PRED_FORMAT4	ASSUME_PRED_FORMAT4
#define IUTEST_ASSUME_PRED_FORMAT5	ASSUME_PRED_FORMAT5

#define IUTEST_ASSUME_FAILURE	GTEST_ASSUME_FAILURE_

#endif // !defined(IUTEST_USE_GTEST)

#define ASSUME_NULL		IUTEST_ASSUME_NULL
#define ASSUME_NOTNULL	IUTEST_ASSUME_NOTNULL
#define ASSUME_SAME		IUTEST_ASSUME_SAME

#endif // INCG_IRIS_IUTEST_SWITCH_ASSUME_HPP_E22A3162_D581_4F4F_A344_F5D701B21F53_

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_assertion_return.hpp
 * @brief		AssertionReturn 切り替え対応 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2013-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_ASSERTION_RETURN_HPP_3913D1E7_E6FD_49B9_BB4C_795939FEB5C5_
#define INCG_IRIS_IUTEST_SWITCH_ASSERTION_RETURN_HPP_3913D1E7_E6FD_49B9_BB4C_795939FEB5C5_

#if !defined(IUTEST_USE_GTEST)

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#ifdef INCG_IRIS_IUTEST_HPP_
#  undef IUTEST_HAS_ASSERTION_RETURN
#endif

#ifdef GTEST_MESSAGE_AT_
#  undef GTEST_MESSAGE_AT_
#endif

//======================================================================
// define
#define IUTEST_HAS_ASSERTION_RETURN	1

#define GTEST_MESSAGE_AT_(file, line, message, result_type)					\
	::testing::internal::AssertHelperEx(result_type, file, line, message)	\
		= ::testing::AssertionMessage()

//======================================================================
// class
namespace testing
{

template<typename T>
struct AssertionReturnType
{
	T value;
	AssertionReturnType(void) {}
	AssertionReturnType(const T& v) : value(v) {}
};
template<>
struct AssertionReturnType<void>
{
	AssertionReturnType(void) {}
};

template<typename T>
inline AssertionReturnType<T> AssertionReturn(const T& ret) { return AssertionReturnType<T>(ret); }
inline AssertionReturnType<void> AssertionReturn(void) { return AssertionReturnType<void>(); }

namespace internal
{

template<typename T>
struct AssertionFixed
{
	Message msg;
	AssertionReturnType<T> ret;
	AssertionFixed(const Message& message, const AssertionReturnType<T>& r) : msg(message), ret(r) {}
};

}	// end of namespace internal

class AssertionMessage : public Message
{
	typedef ::std::ostream& (*BasicNarrowIoManip)(::std::ostream&);
public:
	template<typename T>
	AssertionMessage& operator << (T val)
	{
		Message::operator << (val);
		return *this;
	}
	AssertionMessage& operator << (BasicNarrowIoManip val)
	{
		Message::operator << (val);
		return *this;
	}
	AssertionMessage& operator << (const AssertionReturnType<void>&)
	{
		return *this;
	}
	template<typename R>
	internal::AssertionFixed<R> operator << (const AssertionReturnType<R>& r)
	{
		return internal::AssertionFixed<R>(*this, r);
	}
private:
	void operator=(const AssertionMessage&);
};

namespace internal
{

class AssertHelperEx : public AssertHelper
{
public:
	AssertHelperEx(TestPartResult::Type type, const char* file, int line, const char* message)
		: AssertHelper(type, file, line, message) {}

	void operator = (const Message& message) const
	{
		AssertHelper::operator = (message);
	}
	template<typename R>
	R operator = (const AssertionFixed<R>& fixed) const
	{
		AssertHelper::operator = (fixed.msg);
		return fixed.ret.value;
	}
private:
	GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperEx);
};

}	// end of namespace internal
}	// end of namespace testing

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_ASSERTION_RETURN_HPP_3913D1E7_E6FD_49B9_BB4C_795939FEB5C5_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_package.hpp
 * @brief		IUTEST_PACKAGE 切り替え定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_PACKAGE_HPP_5D6B75EE_F445_4730_8FEA_FB6249BCBD9C_
#define INCG_IRIS_IUTEST_SWITCH_PACKAGE_HPP_5D6B75EE_F445_4730_8FEA_FB6249BCBD9C_

#if !defined(IUTEST_USE_GTEST)

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

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#undef IUTEST_PACKAGE
#undef IUTEST_HAS_PACKAGE

#endif

//======================================================================
// define
#define IUTEST_PACKAGE(name)		namespace name
#define IUTEST_HAS_PACKAGE			0

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_PACKAGE_HPP_5D6B75EE_F445_4730_8FEA_FB6249BCBD9C_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_peep.hpp
 * @brief		IUTEST_PEEP 切り替え定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_PEEP_HPP_316C2127_8DF8_4B99_9C07_9170B403D6AD_
#define INCG_IRIS_IUTEST_SWITCH_PEEP_HPP_316C2127_8DF8_4B99_9C07_9170B403D6AD_

#if !defined(IUTEST_USE_GTEST)

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

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// define
#ifndef IUTEST_HAS_PEEP
#  define IUTEST_HAS_PEEP				0
#endif
#ifndef IUTEST_HAS_PEEP_FUNC
#  define IUTEST_HAS_PEEP_FUNC			0
#endif
#ifndef IUTEST_HAS_PEEP_STATIC_FUNC
#  define IUTEST_HAS_PEEP_STATIC_FUNC	0
#endif
#ifndef IUTEST_HAS_PEEP_CLASS
#  define IUTEST_HAS_PEEP_CLASS			0
#endif

#if IUTEST_HAS_PEEP

namespace testing {
namespace detail 
{

using ::iutest::detail::peep_tag;

}	// end of namespace detail

using ::iutest::Peep;

}	// end of namespace testing

#endif

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_PEEP_HPP_316C2127_8DF8_4B99_9C07_9170B403D6AD_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_pmz.hpp
 * @brief		IUTEST_PMZ 切り替え定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_PMZ_HPP_3913D1E7_E6FD_49B9_BB4C_795939FEB5C5_
#define INCG_IRIS_IUTEST_SWITCH_PMZ_HPP_3913D1E7_E6FD_49B9_BB4C_795939FEB5C5_

#if !defined(IUTEST_USE_GTEST)

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

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#undef IUTEST_HAS_PARAM_METHOD_TEST

#endif

//======================================================================
// define
#ifndef IUTEST_HAS_PARAM_METHOD_TEST
#  define IUTEST_HAS_PARAM_METHOD_TEST	0
#endif

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_PMZ_HPP_3913D1E7_E6FD_49B9_BB4C_795939FEB5C5_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_pred.hpp
 * @brief		述語フォーマット 切り替え定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2013-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_PRED_HPP_B00F77FE_0772_48EC_B182_DAB0AA3EA2DC_
#define INCG_IRIS_IUTEST_SWITCH_PRED_HPP_B00F77FE_0772_48EC_B182_DAB0AA3EA2DC_

#if !defined(IUTEST_USE_GTEST)

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

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#undef IUTEST_PRED_FORMAT1_
#undef IUTEST_PRED_FORMAT2_
#undef IUTEST_PRED_FORMAT3_
#undef IUTEST_PRED_FORMAT4_
#undef IUTEST_PRED_FORMAT5_

#ifdef IUTEST_PRED_
#  undef IUTEST_PRED_
#endif
#ifdef IUTEST_PRED_FORMAT_
#  undef IUTEST_PRED_FORMAT_
#endif

#endif

//======================================================================
// define
#define IUTEST_PRED_FORMAT1_	GTEST_PRED_FORMAT1_
#define IUTEST_PRED_FORMAT2_	GTEST_PRED_FORMAT2_
#define IUTEST_PRED_FORMAT3_	GTEST_PRED_FORMAT3_
#define IUTEST_PRED_FORMAT4_	GTEST_PRED_FORMAT4_
#define IUTEST_PRED_FORMAT5_	GTEST_PRED_FORMAT5_

#ifndef IUTEST_THROW_PRED_FORMAT2_
#  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)
#endif

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_PRED_HPP_B00F77FE_0772_48EC_B182_DAB0AA3EA2DC_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_skip.hpp
 * @brief		IUTEST_SKIP 切り替え定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_SKIP_HPP_3CFB2B8D_9C8D_4B4F_9843_2FE38126BB31_
#define INCG_IRIS_IUTEST_SWITCH_SKIP_HPP_3CFB2B8D_9C8D_4B4F_9843_2FE38126BB31_

#if !defined(IUTEST_USE_GTEST)

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

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#undef IUTEST_SKIP

#endif

//======================================================================
// define
#define IUTEST_SKIP()			GTEST_AMBIGUOUS_ELSE_BLOCKER_	\
								if( ::testing::internal::AlwaysTrue() ) return GTEST_MESSAGE_("Skipped. ", ::testing::TestPartResult::kSuccess)


#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_SKIP_HPP_3CFB2B8D_9C8D_4B4F_9843_2FE38126BB31_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_throw_value.hpp
 * @brief		IUTEST_*_THROW_VALUE アサーション切り替え ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_THROW_VALUE_HPP_5D6B75EE_F445_4730_8FEA_FB6249BCBD9C_
#define INCG_IRIS_IUTEST_SWITCH_THROW_VALUE_HPP_5D6B75EE_F445_4730_8FEA_FB6249BCBD9C_

#if !defined(IUTEST_USE_GTEST)

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

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#if defined(INCG_IRIS_IUTEST_HPP_)

#undef IUTEST_ASSERT_THROW_VALUE_EQ
#undef IUTEST_ASSERT_THROW_VALUE_NE
#undef IUTEST_ASSERT_THROW_VALUE_STREQ
#undef IUTEST_ASSERT_THROW_VALUE_STRCASEEQ

#undef IUTEST_EXPECT_THROW_VALUE_EQ
#undef IUTEST_EXPECT_THROW_VALUE_NE
#undef IUTEST_EXPECT_THROW_VALUE_STREQ
#undef IUTEST_EXPECT_THROW_VALUE_STRCASEEQ

#undef IUTEST_INFORM_THROW_VALUE_EQ
#undef IUTEST_INFORM_THROW_VALUE_NE
#undef IUTEST_INFORM_THROW_VALUE_STREQ
#undef IUTEST_INFORM_THROW_VALUE_STRCASEEQ

#undef IUTEST_ASSUME_THROW_VALUE_EQ
#undef IUTEST_ASSUME_THROW_VALUE_NE
#undef IUTEST_ASSUME_THROW_VALUE_STREQ
#undef IUTEST_ASSUME_THROW_VALUE_STRCASEEQ


#undef IUTEST_TEST_THROW_VALUE_
#undef IUTEST_TEST_THROW_VALUE_EQ_
#undef IUTEST_TEST_THROW_VALUE_NE_
#undef IUTEST_TEST_THROW_VALUE_STREQ_
#undef IUTEST_TEST_THROW_VALUE_STRCASEEQ_

#endif

//======================================================================
// define
#ifndef IUTEST_ASSERT_THROW_PRED_FORMAT2
#  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)
#endif

#ifndef IUTEST_EXPECT_THROW_PRED_FORMAT2
#  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)
#endif

#ifndef IUTEST_INFORM_THROW_PRED_FORMAT2
#  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)
#endif

#ifndef IUTEST_ASSUME_THROW_PRED_FORMAT2
#  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_INFORM_FAILURE)
#endif

// ASSERT
#define IUTEST_ASSERT_THROW_VALUE_EQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_value, IUTEST_ASSERT_FAILURE)
#define IUTEST_ASSERT_THROW_VALUE_NE(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, expected_value, IUTEST_ASSERT_FAILURE)
#define IUTEST_ASSERT_THROW_VALUE_STREQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_value, IUTEST_ASSERT_FAILURE)
#define IUTEST_ASSERT_THROW_VALUE_STRCASEEQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_value, IUTEST_ASSERT_FAILURE)

// EXPECT
#define IUTEST_EXPECT_THROW_VALUE_EQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_value, IUTEST_EXPECT_FAILURE)
#define IUTEST_EXPECT_THROW_VALUE_NE(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, expected_value, IUTEST_EXPECT_FAILURE)
#define IUTEST_EXPECT_THROW_VALUE_STREQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_value, IUTEST_EXPECT_FAILURE)
#define IUTEST_EXPECT_THROW_VALUE_STRCASEEQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_value, IUTEST_EXPECT_FAILURE)

// INFORM
#define IUTEST_INFORM_THROW_VALUE_EQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_value, IUTEST_INFORM_FAILURE)
#define IUTEST_INFORM_THROW_VALUE_NE(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, expected_value, IUTEST_INFORM_FAILURE)
#define IUTEST_INFORM_THROW_VALUE_STREQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_value, IUTEST_INFORM_FAILURE)
#define IUTEST_INFORM_THROW_VALUE_STRCASEEQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_value, IUTEST_INFORM_FAILURE)

// ASSUME
#define IUTEST_ASSUME_THROW_VALUE_EQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_value, IUTEST_ASSUME_FAILURE)
#define IUTEST_ASSUME_THROW_VALUE_NE(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, expected_value, IUTEST_ASSUME_FAILURE)
#define IUTEST_ASSUME_THROW_VALUE_STREQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_value, IUTEST_ASSUME_FAILURE)
#define IUTEST_ASSUME_THROW_VALUE_STRCASEEQ(statement, expected_exception, expected_value)	IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_value, IUTEST_ASSUME_FAILURE)


#define IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, pred_formatter)	\
	IUTEST_AMBIGUOUS_ELSE_BLOCKER_													\
	if( ::testing::AssertionResult ar = ::testing::AssertionSuccess() ) {			\
		try {																		\
			IUTEST_SUPPRESS_UNREACHABLE_CODE_WARNING((void)(statement));			\
			ar << "\nExpected: " #statement " throws an exception of type "			\
					#expected_exception ".\n  Actual: it throws nothing.";			\
			goto IUTEST_PP_CAT(iutest_label_throw_value, __LINE__);					\
		} catch( expected_exception const& e) {										\
			if( ::testing::AssertionResult ar2 = pred_formatter("e", #expected_exception_value, e, expected_exception_value) ) {			\
			} else {																\
				ar << "\nExpected: " #statement " throws an exception of value\n" << ar2.message();	\
				goto IUTEST_PP_CAT(iutest_label_throw_value, __LINE__);				\
			}																		\
		} catch( ... ) {															\
			ar << "\nExpected: " #statement " throws an exception of type "			\
				#expected_exception ".\n  Actual: it throws a different type.";		\
			goto IUTEST_PP_CAT(iutest_label_throw_value, __LINE__);					\
		}																			\
	} else																			\
		IUTEST_PP_CAT(iutest_label_throw_value, __LINE__):							\
		on_failure(ar.message())

#define IUTEST_TEST_THROW_VALUE_EQ_(statement, expected_exception, expected_exception_value, on_failure)	\
	IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, ::testing::internal::EqHelper<GTEST_IS_NULL_LITERAL_(expected_exception_value)>::Compare)
#define IUTEST_TEST_THROW_VALUE_NE_(statement, expected_exception, expected_exception_value, on_failure)	\
	IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, ::testing::internal::NeHelper<GTEST_IS_NULL_LITERAL_(expected_exception_value)>::Compare)
#define IUTEST_TEST_THROW_VALUE_STREQ_(statement, expected_exception, expected_exception_value, on_failure)	\
	IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, ::testing::internal::CmpHelperSTREQ)
#define IUTEST_TEST_THROW_VALUE_STRCASEEQ_(statement, expected_exception, expected_exception_value, on_failure)	\
	IUTEST_TEST_THROW_VALUE_(statement, expected_exception, expected_exception_value, on_failure, ::testing::internal::CmpHelperSTRCASEEQ)

#endif // !defined(IUTEST_USE_GTEST)

// ASSERT
#define ASSERT_THROW_PRED_FORMAT2		IUTEST_ASSERT_THROW_PRED_FORMAT2
#define ASSERT_THROW_VALUE_EQ			IUTEST_ASSERT_THROW_VALUE_EQ
#define ASSERT_THROW_VALUE_NE			IUTEST_ASSERT_THROW_VALUE_NE
#define ASSERT_THROW_VALUE_STREQ		IUTEST_ASSERT_THROW_VALUE_STREQ
#define ASSERT_THROW_VALUE_STRCASEEQ	IUTEST_ASSERT_THROW_VALUE_STRCASEEQ

// EXPECT
#define EXPECT_THROW_PRED_FORMAT2		IUTEST_EXPECT_THROW_PRED_FORMAT2
#define EXPECT_THROW_VALUE_EQ			IUTEST_EXPECT_THROW_VALUE_EQ
#define EXPECT_THROW_VALUE_NE			IUTEST_EXPECT_THROW_VALUE_NE
#define EXPECT_THROW_VALUE_STREQ		IUTEST_EXPECT_THROW_VALUE_STREQ
#define EXPECT_THROW_VALUE_STRCASEEQ	IUTEST_EXPECT_THROW_VALUE_STRCASEEQ

// INFORM
#define INFORM_THROW_PRED_FORMAT2		IUTEST_INFORM_THROW_PRED_FORMAT2
#define INFORM_THROW_VALUE_EQ			IUTEST_INFORM_THROW_VALUE_EQ
#define INFORM_THROW_VALUE_NE			IUTEST_INFORM_THROW_VALUE_NE
#define INFORM_THROW_VALUE_STREQ		IUTEST_INFORM_THROW_VALUE_STREQ
#define INFORM_THROW_VALUE_STRCASEEQ	IUTEST_INFORM_THROW_VALUE_STRCASEEQ

// ASSUME
#define ASSUME_THROW_PRED_FORMAT2		IUTEST_ASSUME_THROW_PRED_FORMAT2
#define ASSUME_THROW_VALUE_EQ			IUTEST_ASSUME_THROW_VALUE_EQ
#define ASSUME_THROW_VALUE_NE			IUTEST_ASSUME_THROW_VALUE_NE
#define ASSUME_THROW_VALUE_STREQ		IUTEST_ASSUME_THROW_VALUE_STREQ
#define ASSUME_THROW_VALUE_STRCASEEQ	IUTEST_ASSUME_THROW_VALUE_STRCASEEQ

#endif // INCG_IRIS_IUTEST_SWITCH_THROW_VALUE_HPP_5D6B75EE_F445_4730_8FEA_FB6249BCBD9C_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_no_failure.hpp
 * @brief		IUTEST_*_no_failure アサーション切り替え ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_NO_FAILURE_HPP_5D6B75EE_F445_4730_8FEA_FB6249BCBD9C_
#define INCG_IRIS_IUTEST_SWITCH_NO_FAILURE_HPP_5D6B75EE_F445_4730_8FEA_FB6249BCBD9C_

#if !defined(IUTEST_USE_GTEST)

//======================================================================
// define
#define ASSERT_NO_FAILURE	IUTEST_ASSERT_NO_FAILURE
#define EXPECT_NO_FAILURE	IUTEST_EXPECT_NO_FAILURE
#define INFORM_NO_FAILURE	IUTEST_INFORM_NO_FAILURE
#define ASSUME_NO_FAILURE	IUTEST_ASSUME_NO_FAILURE

#else // !defined(IUTEST_USE_GTEST)

//======================================================================
// undef
#ifdef INCG_IRIS_IUTEST_HPP_

#undef IUTEST_ASSERT_NO_FAILURE
#undef IUTEST_EXPECT_NO_FAILURE
#undef IUTEST_INFORM_NO_FAILURE
#undef IUTEST_ASSUME_NO_FAILURE

#endif

//======================================================================
// define
#define IUTEST_ASSERT_NO_FAILURE	ASSERT_NO_FAILURE
#define IUTEST_EXPECT_NO_FAILURE	EXPECT_NO_FAILURE
#define IUTEST_INFORM_NO_FAILURE	INFORM_NO_FAILURE
#define IUTEST_ASSUME_NO_FAILURE	ASSUME_NO_FAILURE

#define ASSERT_NO_FAILURE(statement)	GTEST_TEST_NO_FAILURE_(statement, GTEST_FATAL_FAILURE_)
#define EXPECT_NO_FAILURE(statement)	GTEST_TEST_NO_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
#define INFORM_NO_FAILURE(statement)	GTEST_TEST_NO_FAILURE_(statement, GTEST_INFORM_FAILURE_)
#define ASSUME_NO_FAILURE(statement)	GTEST_TEST_NO_FAILURE_(statement, GTEST_ASSUME_FAILURE_)

#define GTEST_TEST_NO_FAILURE_(statement, fail)							\
	GTEST_AMBIGUOUS_ELSE_BLOCKER_										\
	if(::testing::internal::AlwaysTrue()) {								\
		::testing::internal::HasNewFailureHelper gtest_failure_checker;	\
		GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement);		\
		if(gtest_failure_checker.has_new_failure()) {					\
			goto GTEST_CONCAT_TOKEN_(gtest_label_testnofail_, __LINE__);\
		}																\
	} else																\
		GTEST_CONCAT_TOKEN_(gtest_label_testnofail_, __LINE__):			\
			fail("Expected: " #statement " doesn't generate new "		\
					"failures in the current thread.\n"					\
					"  Actual: it does.")

//======================================================================
// class
namespace testing
{

namespace internal
{

class HasNewFailureHelper : public HasNewFatalFailureHelper
{
public:
	HasNewFailureHelper(void) : m_has_new_failure(false)
	{
	}
	virtual ~HasNewFailureHelper(void)
	{
	}
public:
	virtual void ReportTestPartResult(const TestPartResult& result)
	{
		if( result.failed() )
		{
			m_has_new_failure = true;
		}
	}
	bool has_new_failure() const { return m_has_new_failure; }

private:
	bool m_has_new_failure;
};

}	// end of namespace internal
}	// end of namespace testing

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_NO_FAILURE_HPP_5D6B75EE_F445_4730_8FEA_FB6249BCBD9C_

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_filepath.hpp
 * @brief		FilePath 切り替え ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2013-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_FILEPATH_HPP_D92E9CDC_9C63_4008_BE35_6E32177B28D2_
#define INCG_IRIS_IUTEST_SWITCH_FILEPATH_HPP_D92E9CDC_9C63_4008_BE35_6E32177B28D2_

#if !defined(IUTEST_USE_GTEST)

#else // !defined(IUTEST_USE_GTEST)

namespace testing {
namespace internal
{

inline bool operator == (const FilePath& lhs
						 , const FilePath& rhs)
{
	return posix::StrCaseCmp(lhs.c_str(), rhs.c_str()) == 0;
}

inline bool operator == (const FilePath& lhs
						 , const char* rhs)
{
	return posix::StrCaseCmp(lhs.c_str(), rhs) == 0;
}

inline bool operator == (const char* lhs
						 , const FilePath& rhs)
{
	return posix::StrCaseCmp(lhs, rhs.c_str()) == 0;
}

inline ::std::ostream& operator << (::std::ostream& os, const FilePath& path)
{
	return os << path.c_str();
}

}	// end of namespace internal
}	// end of namespace testing

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_FILEPATH_HPP_D92E9CDC_9C63_4008_BE35_6E32177B28D2_

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_switch_cmphelper.hpp
 * @brief		gtest 用 比較ヘルパー関数 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_SWITCH_CMPHELPER_HPP_0378DF29_2DE7_4C60_8E12_32FEA8BEAA7C_
#define INCG_IRIS_IUTEST_SWITCH_CMPHELPER_HPP_0378DF29_2DE7_4C60_8E12_32FEA8BEAA7C_

#if !defined(IUTEST_USE_GTEST)

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

#else // !defined(IUTEST_USE_GTEST)

namespace testing
{

namespace internal
{

#if GTEST_MINORVER < 0x06
template<bool> struct EnableIf;
template<> struct EnableIf<true> { typedef void type; };
#endif

//======================================================================
// function
template<typename T1, typename T2>
inline AssertionResult	CmpHelperSame(const char* expected_str, const char* actual_str
	, const T1& expected, const T2& actual)
{
	return EqHelper<false>::Compare(expected_str, actual_str, &expected, &actual);
}

template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
	, const ::std::basic_string<Elem, Traits, Ax>& val1
	, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return CmpHelperSTREQ(expr1, expr2, val1.c_str(), val2.c_str());
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
	, const Elem* val1
	, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return CmpHelperSTREQ(expr1, expr2, val1, val2.c_str());
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTREQ(const char* expr1, const char* expr2
	, const ::std::basic_string<Elem, Traits, Ax>& val1
	, const Elem* val2)
{
	return CmpHelperSTREQ(expr1, expr2, val1.c_str(), val2);
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
	, const ::std::basic_string<Elem, Traits, Ax>& val1
	, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return CmpHelperSTRNE(expr1, expr2, val1.c_str(), val2.c_str());
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
	, const Elem* val1
	, const ::std::basic_string<Elem, Traits, Ax>& val2)
{
	return CmpHelperSTRNE(expr1, expr2, val1, val2.c_str());
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNE(const char* expr1, const char* expr2
	, const ::std::basic_string<Elem, Traits, Ax>& val1
	, const Elem* val2)
{
	return CmpHelperSTRNE(expr1, expr2, val1.c_str(), val2);
}

inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRCASEEQ(const char* expr1, const char* expr2
	, const wchar_t* val1, const wchar_t* val2)
{
	if( val1 == NULL || val2 == NULL )
	{
		if( val1 == val2 ) return AssertionSuccess();
	}
	else
	{
		if( iu_wcsicmp(val1, val2) == 0 ) return AssertionSuccess();
	}
	return EqFailure(expr1, expr2
		, FormatForComparisonFailureMessage(val1, val2).c_str()
		, FormatForComparisonFailureMessage(val2, val1).c_str()
		, true);
}
template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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);
}

inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRCASENE(const char* expr1, const char* expr2
	, const wchar_t* val1, const wchar_t* val2)
{
	if( val1 == NULL || val2 == NULL )
	{
		if( val1 != val2 ) return AssertionSuccess();
	}
	else
	{
		if( iu_wcsicmp(val1, val2) != 0 ) return AssertionSuccess();
	}
	return AssertionFailure() << "error: Value of: " << expr1 << " != " << expr2
		<< "\n  Actual: " << FormatForComparisonFailureMessage(val2, val1) << "\nExpected: " << FormatForComparisonFailureMessage(val1, val2) ;
}

template<typename Elem, typename Traits, typename Ax>
inline AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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);
}

template <bool lhs_is_null_literal>
class NeHelper {
public:
	template <typename T1, typename T2>
	static AssertionResult Compare(const char* expected_expression,
		const char* actual_expression,
		const T1& expected,
		const T2& actual) {
			return CmpHelperNE(expected_expression, actual_expression, expected,
				actual);
	}

	static AssertionResult Compare(const char* expected_expression,
		const char* actual_expression,
		BiggestInt expected,
		BiggestInt actual) {
			return CmpHelperNE(expected_expression, actual_expression, expected,
				actual);
	}
};

template <>
class NeHelper<true> {
public:
	template <typename T1, typename T2>
	static AssertionResult Compare(
		const char* expected_expression,
		const char* actual_expression,
		const T1& expected,
		const T2& actual,
		typename EnableIf<!is_pointer<T2>::value>::type* = 0) {
			return CmpHelperNE(expected_expression, actual_expression, expected,
				actual);
	}

	template <typename T>
	static AssertionResult Compare(
		const char* expected_expression,
		const char* actual_expression,
		Secret* ,
		T* actual) {
			return CmpHelperNE(expected_expression, actual_expression,
				static_cast<T*>(NULL), actual);
	}
};

}	// end of namespace internal
}	// end of namespace testing

#endif // !defined(IUTEST_USE_GTEST)

#endif // INCG_IRIS_IUTEST_SWITCH_CMPHELPER_HPP_0378DF29_2DE7_4C60_8E12_32FEA8BEAA7C_

namespace iutest
{

//======================================================================
// function
inline void IUTEST_ATTRIBUTE_UNUSED_ InitGoogleTest(int* argc, char** argv)
{
	InitIrisUnitTest(argc, argv);
}
inline void IUTEST_ATTRIBUTE_UNUSED_ InitGoogleTest(int* argc, wchar_t** argv)
{
	InitIrisUnitTest(argc, argv);
}

#if defined(GMOCK_INCLUDE_GMOCK_GMOCK_H_)
inline void IUTEST_ATTRIBUTE_UNUSED_ InitGoogleMock(int* argc, char** argv)
{
	testing::InitGoogleMock(argc, argv);
}
inline void IUTEST_ATTRIBUTE_UNUSED_ InitGoogleMock(int* argc, wchar_t** argv)
{
	testing::InitGoogleMock(argc, argv);
}
#endif

}

#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_

#if defined(GTEST_INCLUDE_GTEST_GTEST_H_)
// すでに testing namespace が存在するので、define で置き換え
#  define testing	iutest
#else
// それ以外は namespace の置き換えで対応
namespace testing = iutest;
#endif

#endif

#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
#  define GTEST_INCLUDE_GTEST_GTEST_H_	// 以降で、gtest が include されないようにする
#endif

#else // !defined(IUTEST_USE_GTEST)

#if defined(INCG_IRIS_IUTEST_HPP_)
#  if IUTEST_HAS_TUPLE
#    define GTEST_USE_OWN_TR1_TUPLE	0
#  endif
#  ifdef StaticAssertTypeEq
#	 undef StaticAssertTypeEq
#  endif
#endif

#if defined(_MSC_VER) && _MSC_VER == 1700
#  ifndef _VARIADIC_MAX
#    define _VARIADIC_MAX	10
#  endif

#include <tuple>
namespace std {
namespace tr1
{
	using ::std::tuple;
}
}
#endif

#ifdef __STRICT_ANSI__
#  undef __STRICT_ANSI__
#  include <cstdio>
#  include <string.h>
#  include <stdlib.h>
#  define __STRICT_ANSI__
#endif

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_ver.hpp
 * @brief		iris unit test version 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_VER_HPP_D65CB7A7_D2AD_40FE_8F5F_8FBF376A0010_
#define INCG_IRIS_IUTEST_VER_HPP_D65CB7A7_D2AD_40FE_8F5F_8FBF376A0010_

//======================================================================
// define
#define IUTEST_VER			0x01130000u //!< iutest version 1.13.0.0
#define IUTEST_MAJORVER		0x01u		//!< Major Version
#define IUTEST_MINORVER		0x13u		//!< Minor Version
#define IUTEST_BUILD		0x00u		//!< Build
#define IUTEST_REVISION		0x00u		//!< Revision

/**
 * @mainpage
 * @sa	@b	ProjectHome \n
 *			OSDN        : http://osdn.jp/projects/iutest/ \n
 *			github		: https://github.com/srz-zumix/iutest \n
 *			google group: https://groups.google.com/forum/?fromgroups#!forum/g-iutest \n
 *
 * @par		copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License.
 *
 * @par		LICENSE

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:\n
\n
  1. Redistributions of source code must retain the above copyright notice,\n
     this list of conditions and the following disclaimer.\n
  2. Redistributions in binary form must reproduce the above copyright notice,\n
     this list of conditions and the following disclaimer in the documentation \n
     and/or other materials provided with the distribution.\n
  3. the copyright holder's name is not used to endorse products \n
     built using this software without specific written permission.\n
\n
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

/**
 * @page	CMDLINE		コマンドラインオプション
 * @par		Command Line Options
 <table>
   <tr><td>--help, -h                        </td><td></td><td>Generate help message.</td></tr>
   <tr><td>--iutest_output                   </td><td>xml|junit[:path]</td><td>Path of xml report.</td></tr>
   <tr><td>--iutest_list_tests               </td><td></td><td>List up tests.</td></tr>
   <tr><td>--iutest_list_tests_with_where    </td><td></td><td>List up tests with where.</td></tr>
   <tr><td>--iutest_color                    </td><td>&lt;yes|no|auto|ansi&gt;</td><td>Console color enable.</td></tr>
   <tr><td>--iutest_flagfile                 </td><td>&lt;file&gt;</td><td>Set the flag from the file.</td></tr>
   <tr><td>--iutest_filter                   </td><td>&lt;filter&gt;</td><td>Select the test run.</td></tr>
   <tr><td>--iutest_shuffle                  </td><td></td><td>Do shuffle test.</td></tr>
   <tr><td>--iutest_random_seed              </td><td>&lt;seed&gt;</td><td>Set random seed.</td></tr>
   <tr><td>--iutest_also_run_disabled_tests  </td><td></td><td>Run disabled tests.</td></tr>
   <tr><td>--iutest_break_on_failure         </td><td>[yes|no]</td><td>When that failed to break.</td></tr>
   <tr><td>--iutest_throw_on_failure         </td><td>[yes|no]</td><td>When that failed to throw.</td></tr>
   <tr><td>--iutest_catch_exceptions         </td><td>&lt;yes|no&gt;</td><td>Catch exceptions enable.</td></tr>
   <tr><td>--iutest_print_time               </td><td>&lt;yes|no&gt;</td><td>Setting the display of elapsed time.</td></tr>
   <tr><td>--iutest_repeat                   </td><td>&lt;count&gt;</td><td>Set the number of repetitions of the test.</td></tr>
   <tr><td>--iutest_stream_result_to         </td><td>&lt;host:port&gt;</td><td>Set stream test results server.</td></tr>
   <tr><td>--iutest_file_location            </td><td>&lt;auto|vs|gcc&gt;</td><td>Format file location messages.</td></tr>
   <tr><td>--iutest_default_package_name     </td><td>[name]</td><td>Set default root package name.</td></tr>
   <tr><td>--verbose                         </td><td></td><td>Verbose option.</td></tr>
   <tr><td>--feature                         </td><td></td><td>Show iutest feature.</td></tr>
   <tr><td>--version, -v                     </td><td></td><td>Show iutest version.</td></tr>
 </table>
  * yes or no option can use "yes|y|on|true|t|1|no|n|off|false|f|0"
*/

/**
 * @page	ENVIRONMENT_OPTIONS	環境変数オプション
 * @par		Environment variable Options
 <table>
   <tr><td>IUTEST_OUTPUT=xml|junit[:path]  </td><td>Path of xml report.</td></tr>
   <tr><td>IUTEST_COLOR=yes|no|auto        </td><td>Console color enable.</td></tr>
   <tr><td>IUTEST_FLAGFILE=file            </td><td>Set the flag from the file.</td></tr>
   <tr><td>IUTEST_FILTER=filter            </td><td>Select the test run.</td></tr>
   <tr><td>IUTEST_SHUFFLE                  </td><td>Do shuffle test.</td></tr>
   <tr><td>IUTEST_RANDOM_SEED=seed         </td><td>Set random seed.</td></tr>
   <tr><td>IUTEST_ALSO_RUN_DISABLED_TESTS  </td><td>Run disabled tests.</td></tr>
   <tr><td>IUTEST_BREAK_ON_FAILURE=0|1     </td><td>When that failed to break.</td></tr>
   <tr><td>IUTEST_THROW_ON_FAILURE=0|1     </td><td>When that failed to throw.</td></tr>
   <tr><td>IUTEST_CATCH_EXCEPTIONS=0|1     </td><td>Catch exceptions enable.</td></tr>
   <tr><td>IUTEST_PRINT_TIME=0|1           </td><td>Setting the display of elapsed time.</td></tr>
   <tr><td>IUTEST_REPEAT=count             </td><td>Set the number of repetitions of the test.</td></tr>
   <tr><td>IUTEST_FILE_LOCATION=auto|vs|gcc</td><td>Format file location messages.</td></tr>
   <tr><td>IUTEST_ROOT_PACKAGE_NAME=[name] </td><td>Set root package name.</td></tr>
 </table>
*/

/**
 * @page	CHANGELOG	変更履歴
 * @par		Changes
 <ul>
  <li>v1.13.0.0
    <ul>
      <li>--iutest_flagfile コマンドラインオプションに対応</li>
      <li>MFC コンテナ対応</li>
      <li>値のパラメータ化テストのテスト名指定に対応</li>
      <li>型付けテストのテスト名に型名をつけるオプションマクロ (IUTEST_TYPED_TEST_APPEND_TYPENAME) を追加</li>
      <li>非ヨーダ記法を提供するヘッダーを追加</li>
      <li>Visual Studio 2015 対応</li>
      <li>tr1/iutest_vc_unittest.hpp を修正</li>
    </ul>
  </li>
  <li>v1.12.0.0
    <ul>
      <li>IUTEST_PACKAGE v2 (多重定義制限の撤廃)</li>
      <li>Matcher に MatchesRegex,ContainsRegex を追加</li>
      <li>Matcher に ElementsAreArrayForward を追加</li>
      <li>ElementsAreArray で要素数の一致チェックを行うように変更（以前までの ElementsAreArray は ElementsAreArrayForward に変更）</li>
      <li>IUTEST_*_MATCHES_REGEXEQ,NE、IUTEST_*_CONTAINS_REGEXEQ,NE 追加</li>
      <li>--iutest_filter=@filter.txt のようにファイルからフィルター指定できるように対応</li>
      <li>IUTEST_MAKE_PEEP で関数ポインターの typedef をしなくてもいいように修正</li>
      <li>quick_exit 対応</li>
      <li>IUTEST_REPORT_SKIPPED を IUTEST_HAS_REPORT_SKIPPED に変更</li>
      <li>Visual Studio 2015 Preview 対応</li>
      <li>twilio 対応</li>
    </ul>
  </li>
  <li>v1.11.1.0
    <ul>
      <li>IUTEST_REGISTER_TYPED_TEST_CASE_P でテスト名の後ろの空白が名前に含まれてしまう不具合を修正</li>
    </ul>
  </li>
  <li>v1.11.0.0
    <ul>
      <li>fused-src 対応</li>
      <li>Wandbox 対応</li>
      <li>Matcher に Eq,Ne,Le,Lt,Ge,Gt,IsNull,NotNull,TypeEq を追加</li>
      <li>Matcher に StrEq,StrNe,StrCaseEq,StrCaseNe,HasSubstr を追加</li>
      <li>Matcher に FloatEq,DoubleEq,NanSensitiveFloatEq,NanSensitiveDoubleEq を追加</li>
      <li>Matcher に Not,ResultOf,Pointee を追加</li>
      <li>コンテナMatcher に Each,ContainerEq,Pointwise,At,IsEmpty,SizeIs,ElementsAre,ElementsAreArray を追加</li>
      <li>コンテナMatcher の Contains から HasSubstr 機能を削除</li>
      <li>コンテナMatcher の条件に Matcher を使えるように修正</li>
      <li>メンバーMatcher に Key,Pair,Field を追加</li>
      <li>ワイルドカードMatcher A,_ を追加</li>
      <li>IUTEST_*_FLOAT_EQ,DOUBLE_EQ で NAN の比較が真を返す不具合を修正</li>
      <li>Visual Studio 2015 Preview 対応</li>
    </ul>
  </li>
  <li>v1.10.0.0
    <ul>
      <li>--verbose コマンドラインオプションを追加</li>
      <li>--iutest_default_package_name コマンドラインオプションを追加</li>
      <li>operatoer == のないオブジェクトの IUTEST_*_EQ 対応</li>
      <li>operatoer != のないオブジェクトの IUTEST_*_NE 対応</li>
      <li>junit xml 出力に対応（--iutest_output=junit）</li>
      <li>tuple の要素を取得する GetParam template 関数を追加</li>
      <li>IUTEST_FLAG(ostream_formatter) を追加</li>
      <li>tuple 要素を取得する GetParam tempalate 関数を追加</li>
      <li>ARM対応</li>
      <li>--iutest_break_on_failure でスキップや警告でも停止していた不具合を修正</li>
      <li>Visual Studio 14 CTP 3 対応</li>
    </ul>
  </li>
  <li>v1.9.1.0
    <ul>
      <li>IUTEST_P,IUTEST_TYPED_TEST_P で DISABLED_ 指定が機能しない問題を修正</li>
      <li>TestFixutre を定義しなくても IUTEST_P が使えるように対応</li>
      <li>Visual Studio 14 CTP 対応</li>
    </ul>
  </li>
  <li>v1.9.0.0
    <ul>
      <li>IUTEST_*_THAT 追加</li>
      <li>式アサーション追加（IUTEST_ASSERT, IUTEST_EXPECT, IUTEST_INFORM, IUTEST_ASSUME）</li>
      <li>式アサーション追加（IUTEST_*_NOT）</li>
      <li>IUTEST_USE_MAIN 追加(main 関数定義 config)</li>
      <li>IUTEST_ASSERT を IUTEST_ASSERT_EXIT に変更</li>
    </ul>
  </li>
  <li>v1.8.1.0
    <ul>
      <li>SetUp/SetUpTestCase での SKIP/ASSUME に対応</li>
      <li>MAC OS 判定、ビルドエラー修正 (thanks to mogemimi for the pull request)</li>
      <li>--iutest_filter で : 区切りの複数条件指定が正しく動作しない不具合を修正</li>
      <li>--iutest_list_tests_with_where で値のパラメータも出力するように修正</li>
      <li>バグ修正</li>
    </ul>
  </li>
  <li>v1.8.0.0
    <ul>
      <li>IUTEST_USE_THROW_ON_ASSERT_FAILURE を IUTEST_USE_THROW_ON_ASSERTION_FAILURE に変更</li>
      <li>IUTEST_USE_THROW_ON_ASSERTION_FAILURE を指定した場合 SKIP や ASSUME も例外を投げるように変更</li>
      <li>IUTEST_*_EQ_RANGE を追加</li>
      <li>IUTEST_*_STRIN,IUTEST_*_STRNOTIN を追加</li>
      <li>IUTEST_FLAG(output) に対応</li>
      <li>IUTEST_*_NO_FAILURE の gtest モード対応</li>
      <li>AVR 対応</li>
      <li>IUTEST_*_NO_FAILURE が警告やスキップを失敗と判断しないように変更</li>
      <li>IUTEST_*_TRUE/FALSE を可変長対応</li>
      <li>フィクスチャークラス名を IUTEST_TEST マクロのテストケース名に使用した場合にエラーになるように修正(MSVC拡張)</li>
      <li>パッケージ内の値のパラメータ化テストのテストケース名が pkg.prefix/testcase となるように変更</li>
      <li>Visual C++ Compiler November 2013 CTP 対応</li>
      <li>リスナーのセットアップ関数を変更</li>
      <li>IUTEST_SCOPED_PEEP,IUTEST_MAKE_SCOPED_PEEP を廃止</li>
      <li>ソースコードのエンコーディングを UTF8 BOM 有りに変更</li>
      <li>バグ修正</li>
    </ul>
  </li>
  <li>v1.7.0.0
    <ul>
      <li>テストフィクスチャの定義が省ける値のパラメータ化テストを追加(IUTEST_AP,IUTEST_INSTANTIATE_TEST_CASE_AP)</li>
      <li>値のパラメータを operator + で連結できるように修正</li>
      <li>値のパラメータを連結する ::iutest::Concat を追加</li>
      <li>IUTEST_TYPED_TEST,IUTEST_TYPED_TEST_P の別名マクロを追加(IUTEST_T, IUTEST_TP)</li>
      <li>xml 出力に timestamp を追加</li>
      <li>前提条件の検証用マクロ IUTEST_ASSUME_* を追加</li>
      <li>SSTP 通知リスナーを追加</li>
      <li>Windows 向けメニュー登録ユーティリティを追加</li>
      <li>値のパラメータ化テストが日本語テスト名に対応していなかった問題を修正</li>
      <li>ビルドエラー修正</li>
    </ul>
  </li>
  <li>v1.6.1.0
    <ul>
      <li>Visual Studio 2013 Preview 対応</li>
    </ul>
  </li>
  <li>v1.6.0.0
    <ul>
      <li>stream result 対応</li>
      <li>gtest モードで AssertionReturn が使えるように対応</li>
      <li>AssertionReturn の仕様変更</li>
      <li>::iutest::RandomGenerator を追加</li>
      <li>::iutest::RandomValues で乱数シードを指定できるように修正</li>
      <li>spi で TestPartResult 数をチェックするように変更</li>
      <li>spi で substr でメッセージをチェックするように変更</li>
      <li>ASSERT_*, EXPECT_*, INFORM_* マクロのストリームに iomanip が使用できなかった問題を修正</li>
    </ul>
  </li>
  <li>v1.5.0.4
    <ul>
      <li>--iutest_filter でマッチしなかったテストは XML に出力しないように変更</li>
      <li>XML 出力の skipped にメッセージを出力するように修正</li>
      <li>--iutest_filter にマッチしたテスト数が取得できるように修正</li>
      <li>デフォルトログ出力を --iutest_filter の結果を考慮した出力に変更</li>
    </ul>
  </li>
  <li>v1.5.0.0
    <ul>
      <li>日本語テスト名に対応</li>
      <li>SetUpTestCase などのテスト実行中以外でも RecordProperty できるように変更</li>
      <li>iutest_list_tests_with_where コマンドラインオプションを追加</li>
      <li>IUTEST_TYPED_TEST_CASE,IUTEST_TYPED_TEST_CASE_P に直接 ::iutest::Types を書けるように修正/li>
      <li>誤った使い方をした場合にエラーを出力するように修正</li>
      <li>IUTEST_PEEP の仕様変更</li>
      <li>MiniDump 出力に対応</li>
      <li>noexcept に対応</li>
    </ul>
  </li>
  <li>v1.4.0.0
    <ul>
      <li>IUTEST_ASSERT_* で void 以外の戻り値を返せるように修正(::iutest::AssertionReturn)</li>
      <li>::iutest::Types メンバーに型を取得する get を追加</li>
      <li>::iutest::ValuesIn を initializer_list に対応</li>
      <li>値のパラメータ化テスト向けに任意のパラメータを生成する ValuesGen を追加</li>
      <li>値のパラメータ化テスト向けに乱数パラメータを生成する RandomValues を追加</li>
      <li>extern template 対応</li>
      <li>C++11 random ヘッダーが使用できるとき distribution を使うように変更</li>
      <li>コード分析ツールのためのコードの追加情報(__analysis_assume) を IUTEST_*_NULL と IUTEST_*_NOTNULL に追加(MSVC)</li>
      <li>古いコンパイラへの対応</li>
    </ul>
  </li>
  <li>v1.3.1.0
    <ul>
      <li>IUTEST_SKIP したときのログを追加</li>
      <li>IUTEST_SKIP() << "message" に対応</li>
      <li>スキップしたテストのログ出力を修正</li>
      <li>コンパイルの通らないテストコードを許可するテスト生成マクロ(*_IGNORE)を追加</li>
    </ul>
  </li>
  <li>v1.3.0.1
    <ul>
      <li>IUTEST_THROW_ON_ASSERT_FAILURE を IUTEST_USE_THROW_ON_ASSERT_FAILURE に変更</li>
      <li>IUTEST_FRIEND_TYPED_TEST を追加</li>
      <li>乱数シードが繰り返し毎に必ず変わるように修正</li>
      <li>GTEST で始まる環境変数に対応</li>
      <li>メッセージ出力のファイル/行のフォーマットを動的に変更できるオプションを追加(--iutest_file_location)</li>
      <li>gtest モードでのビルドエラー修正</li>
      <li>IUTEST_*_FATAL_FAILURE, IUTEST_*_NONFATAL_FAILURE で lambda を利用して変数にアクセスできるように修正</li>
      <li>IUTEST_*_NO_FATAL_FAILURE が FATAL FAILURE のみで判断するように変更</li>
      <li>IUTEST_*_NO_FAILURE を追加</li>
      <li>ライブラリビルド対応</li>
      <li>CUDA 対応</li>
      <li>explicit conversion operator 対応</li>
    </ul>
  </li>
  <li>v1.2.0.2
    <ul>
      <li>IUTEST_*_EQ_COLLECTIONS アサーションを追加</li>
      <li>Android NDK 対応</li>
      <li>名前空間を提供する IUTEST_PACKAGE 追加</li>
      <li>IUTEST_*_STRNE, IUTEST_*_STRCASENE の失敗メッセージを改善</li>
      <li>プログレス出力リスナーを追加</li>
    </ul>
  </li>
  <li>v1.1.2.0
    <ul>
      <li>IUTEST_*_NO_THROW で失敗したときに例外の情報を出力するように修正</li>
      <li>printer 修正</li>
    </ul>
  </li>
  <li>v1.1.1.2
    <ul>
      <li>Windows Mobile でのビルドエラー修正</li>
      <li>IUTEST_HAS_STRINGSTREAM=0 のときのビルドエラー修正</li>
      <li>宣言と定義を分離</li>
    </ul>
  </li>
  <li>v1.1.0.0
    <ul>
      <li>v1.1.0 リリースバージョン</li>
    </ul>
  </li>
  <li>v1.0.7.1
    <ul>
      <li>2バイト文字が xml に正しく出力されない問題を修正（setlocale が必要）</li>
      <li>例外の値を検査する述語アサーションを IUTEST_*_THROW_PRED_FORMAT2 追加</li>
      <li>例外の値を検査するアサーションのログ出力を修正</li>
    </ul>
  </li>
  <li>v1.0.6.0
    <ul>
      <li>例外の値を検査するアサーションを EQ/NE/STREQ/STRCASEEQ に修正</li>
    </ul>
  </li>
  <li>v1.0.5.2
    <ul>
      <li>明示的なスキップとして IUTEST_SKIP を追加</li>
      <li>コンソール出力先を動的に変更できるように修正</li>
      <li>実行すべきテストが実行されなかった場合に失敗を出力するように修正</li>
      <li>Visual Studio UnitTest Framework で IUTEST_P,IUTEST_TYPED_TEST,IUTEST_TYPED_TEST_P が使用できるように修正(tr1)</li>
    </ul>
  </li>
  <li>v1.0.4.0
    <ul>
      <li>iutest::Pairwise を追加</li>
      <li>コードサイズ削減</li>
    </ul>
  </li>
  <li>v1.0.3.1
    <ul>
      <li>ファイルパス操作補助クラスの追加</li>
      <li>IUTEST_*_EQ で if( expected == actual ) から if( actual == expected ) に変更</li>
      <li>IUTEST_*_NO_FATAL_FAILURE に空の statement を与えても警告が出ないように修正</li>
    </ul>
  </li>
  <li>v1.0.2.0
    <ul>
      <li>例外の値を検査するアサーションを追加</li>
    </ul>
  </li>
  <li>v1.0.1.0
    <ul>
      <li>CRT セキュリティ強化関数の失敗時ハンドラに対応</li>
      <li>iutest::InitIrisUnitTest が呼ばれていない場合に警告を出すように変更</li>
    </ul>
  </li>
  <li>v1.0.0.0
    <ul>
      <li>初期リリース</li>
    </ul>
  </li>
  <li>v0.36.2.1
    <ul>
      <li>型名表記をデマングルするように修正</li>
      <li>Google Test を使用した場合でも std::string に対応した文字列比較アサーションを使えるように修正</li>
      <li>Google Test を使用した時に wchar_t 版の STRCASENE が使えるように修正</li>
      <li>IUTEST_THROW_ON_ASSERT_FAILURE のデフォルト値を 0 に変更</li>
      <li>IUTEST_THROW_ON_ASSERT_FAILURE が有効なとき IUTEST_*_FATAL_FAILURE が正しく動作しない問題を修正</li>
      <li>spi テスト中に break_on_failure/throw_on_failure で止まらないように修正</li>
      <li>アサーションのみの利用ができるように修正</li>
      <li>グローバルスコープ解決演算子をつけるように修正</li>
      <li>Google Test のバージョン判別を追加</li>
    </ul>
  </li>
  <li>v0.35.0.0
    <ul>
      <li>IUTEST_PMZ, IUTEST_PMZ_F テスト生成マクロを追加</li>
    </ul>
  </li>
  <li>v0.34.0.0
    <ul>
      <li>複数 IUTEST_REGISTER_TYPED_TEST_CASE_P できない不具合を修正</li>
      <li>テストが中断した際に実行されなかったテストを notrun で XML 出力するように修正</li>
      <li>--iutest_break_on_failure を有効にしデバッグなし実行をしたときにダイアログがでないように修正</li>
    </ul>
  </li>
  <li>v0.33.1.0
    <ul>
      <li>iutest::UnitTest::repeat_counter 関数を追加</li>
      <li>OnTestIterationStart/End の iteration 引数が 0 から始まるように修正</li>
      <li>QuietResultPrinter 追加</li>
      <li>util 修正</li>
    </ul>
  </li>
  <li>v0.32.0.0
    <ul>
      <li>iutest::Combine を可変長に対応</li>
      <li>IUTEST_PEEP を cv 修飾されたメンバに対応</li>
      <li>テスト全体、テストケースの経過時間の計測方法を変更</li>
    </ul>
  </li>
  <li>v0.31.2.1
    <ul>
      <li>IUTEST_STATIC_ASSERT 追加</li>
      <li>IUTEST_SCOPED_TRACE で gtest と同じ記法が使えるように修正</li>
      <li>std::chrono::high_resolution_clock に対応</li>
      <li>iutest::PrintToString でストリーム出力できない型に対応（バイト配列を出力）</li>
      <li>テスト用乱数のシード取得を追加</li>
      <li>IUTEST_*_TRUE|FALSE で iutest::AssertionResult を受け取れるように修正</li>
      <li>--feature オプションを追加</li>
    </ul>
  </li>
  <li>v0.30.1.0
    <ul>
      <li>IUTEST_*_STREQ, IUTEST_*_STRNE を char16_t, char32_t に対応</li>
      <li>一部の環境でワイド文字列の IUTEST_*_STRCASEEQ, IUTEST_*_STRCASENE が大文字小文字が区別されていた不具合を修正</li>
      <li>nullptr に対応</li>
      <li>乱数シードを指定しなかった場合に現在時刻（ミリ秒）からシードを決定するように修正</li>
      <li>シャッフルテスト時に乱数シードをログ出力するように修正</li>
      <li>時刻取得用のコンフィグマクロを追加</li>
      <li>iutest::PrintToString でコンパイルが通らない型があったので修正</li>
      <li>EQ系アサーションのメッセージを修正</li>
    </ul>
  </li>
  <li>v0.29.1.0
    <ul>
      <li>IUTEST_INSTANTIATE_TYPED_TEST_CASE_P の型リストに単一の型(int, char...)を使用できるように修正</li>
      <li>ASSERT マクロが例外を throw するか設定する IUTEST_THROW_ON_ASSERT_FAILURE を追加(default=1) </li>
      <li>--iutest_throw_on_failure 時に致命的ではないエラーで失敗した場合 throw されない不具合を修正</li>
      <li>2回 IUTEST_RUN_ALL_TESTS したときの不具合を修正</li>
      <li>Environment の解放タイミングを修正</li>
    </ul>
  </li>
  <li>v0.28.0.1
    <ul>
      <li>iutest::Environment::SetUp などテスト以外の場所で失敗した場合に対応</li>
    </ul>
  </li>
  <li>v0.27.0.0
    <ul>
      <li>namespace を考慮した IUTEST_MAKE_SCOPED_PEEP, IUTEST_SCOPED_PEEP マクロを追加</li>
      <li>iutest::AddGlobalTestEnvironment を使うとコンパイルエラーになる問題を修正</li>
      <li>iutest::Environment は new して使うように仕様変更</li>
      <li>iutest::Environment の TearDown の実行順序を SetUp の逆順に変更</li>
    </ul>
  </li>
  <li>v0.26.2.0
    <ul>
      <li>RecordProperty でキーが重複した場合に上書きするように修正</li>
      <li>IUTEST_HAS_PEEP, IUTEST_HAS_PEEP_FUNC, IUTEST_PEEP_STATIC_FUNC コンフィグマクロを追加</li>
      <li>iutest_prod.hpp に private メンバーへのアクセス機能を追加(IUTEST_MAKE_PEEP, IUTEST_PEEP_GET etc...)</li>
      <li>IUTEST_FRIEND_TEST 不具合修正</li>
    </ul>
  </li>
  <li>v0.25.2.0
    <ul>
      <li>gtest との互換性がとれていなかった箇所を修正</li>
      <li>IUTEST_FLAG に filter を追加</li>
      <li>オプションに対応してない値を指定したときにヘルプを出力するように修正</li>
      <li>真偽値を指定するコマンドラインオプションを yes|no に対応</li>
      <li>xml 出力に type param, value param を出力するように修正</li>
      <li>RTTI が有効なときに型情報が出力されていなかった問題を修正</li>
      <li>PrintTo を tuple に対応</li>
    </ul>
  </li>
  <li>v0.24.1.0
    <ul>
      <li>Test Anything Protocol ファイル出力リスナーを追加</li>
      <li>DISABLE テストが xml に run として出力される問題を修正</li>
      <li>DISABLE テスト関係の不具合を修正</li>
      <li>IUTEST_REPORT_SKIPPED マクロでデフォルトxml出力リスナーが skip を出力するか選択できるように修正</li>
      <li>0|1 のフラグを渡すオプションに yes|no, y|n, true|false, t|f が使えるように修正</li>
      <li>--iutest_color に ANSI オプションを追加（エスケープシーケンスで色を出力）</li>
      <li>--iutest_color で大文字小文字を区別しないように修正</li>
    </ul>
  </li>
  <li>v0.23.3.0
    <ul>
      <li>IUTEST_*_SAME アサーションを追加</li>
      <li>IUTEST_*_NULL, IUTEST_*_NOTNULL アサーションを追加</li>
      <li>Test Anyting Protocol リスナーの追加</li>
      <li>デフォルトリスナーを解放したときに NULL 参照する不具合を修正</li>
      <li>テストユーティリティのテスト用に iutest_spi.hpp を追加</li>
      <li>IUTEST_*_STR* アサーションで NULL を与えて失敗させると落ちる問題を修正</li>
      <li>--iutest_throw_on_failure=1 でテスト全体を中断するように変更</li>
    </ul>
  </li>
  <li>v0.22.0.1
    <ul>
      <li>Variadic Templates 対応（iutest::Types, iutest::Values）</li>
      <li>Variadic Templates に対応した述語アサーションを追加（IUTEST_*_PRED）</li>
      <li>IUTEST_*_PRED_FORMAT を追加</li>
      <li>--iutest_throw_on_failure=1 としたとき、テスト中に例外が発生するとテスト側で catch されない不具合を修正</li>
    </ul>
  </li>
  <li>v0.21.0.1
    <ul>
      <li>IUTEST_*_NO_FATAL_FAILURE を追加</li>
      <li>STRCASEEQ, STRCASENE が ASSERT でしか使えなかった問題を修正</li>
      <li>IUTEST_*_PRED5 がコンパイルエラーになる問題を修正</li>
      <li>INFORM マクロが一部コンパイルエラーになる問題を修正</li>
      <li>gcc で例外が使えるかどうかの判定が逆になっていた問題を修正</li>
      <li>アサーションマクロに渡した式の出力を修正</li>
      <li>Visual Studio 11 対応</li>
      <li>clang対応</li>
      <li>サンプルソースを修正</li>
    </ul>
  </li>
  <li>v0.20.0.0
    <ul>
      <li>--iutest_filter を使用したときに、失敗テスト出力が出ない不具合を修正</li>
      <li>テスト、テストケース総数の取得関数が、実行してないものを含めていなかった不具合を修正</li>
      <li>テスト、テストケースの実行した（実行予定）総数の取得関数を追加</li>
      <li>IUTEST_*_STREQ 等、文字列比較マクロに NULL を渡した場合に例外が発生する不具合を修正</li>
      <li>IUTEST_RUN_ALL_TESTS の戻り値が間違っていた不具合を修正</li>
    </ul>
  </li>
  <li>v0.19.0.0
    <ul>
      <li>イベントリスナーに RecordProperty 時のイベントを追加</li>
      <li>google mock 対応</li>
      <li>IUTEST_*_STRCASE* に std::string をそのまま使えるように修正</li>
      <li>rvalue reference 対応</li>
    </ul>
  </li>
  <li>v0.18.1.1
    <ul>
      <li>On*End イベントは、リストの後ろから実行するように変更</li>
      <li>警告用（失敗にならない）テスト IUTEST_INFORM_*** マクロを追加</li>
      <li>iutest::TestPartResult のインターフェイスを修正</li>
      <li>エラー出力の Actual と Expected が逆になっていた不具合を修正</li>
      <li>char もしくは unsigned char の 0 をメッセージ出力する際にヌル文字にならないように修正</li>
      <li>ターミナルの色つき出力処理を修正</li>
      <li>Visual Studio 以外でビルドした場合の環境変数に対応</li>
      <li>IUTEST_ASSERT_EQ のエラー出力が、 Actual と Expected が逆になっていた不具合を修正</li>
    </ul>
  </li>
  <li>v0.17.0.0
    <ul>
      <li>.h から .hpp に変更</li>
      <li>gtest のコマンドライン引数に対応</li>
      <li>--iutest_filter オプションで *Test*-*TestA* のように除外フィルタをかけたときに正しく動作しない不具合を修正</li>
    </ul>
  </li>
  <li>v0.16.1.1
    <ul>
      <li>iutest::InitIrisUnitTest の vector 対応</li>
      <li>NaCl, ARM 対応</li>
      <li>RecordProperty の template 対応</li>
    </ul>
  </li>
  <li>v0.16.0.2
    <ul>
      <li>型アサーション 対応</li>
      <li>RecoredProperty 対応</li>
      <li>iutest::Combine 対応/li>
      <li>型をパラメータ化したテスト<に対応/li>
      <li>googletest との切り替え対応</li>
      <li>googletest との差異を吸収</li>
      <li>致命的な失敗時に throw するオプション対応( --iutest_throw_on_failure=<0|1> )</li>
      <li>経過時間の出力オプション対応( --iutest_print_time=<0|1> )</li>
      <li>実行するテストの選択オプション対応( --iutest_filter=selection )</li>
      <li>iutest::PrintToString 対応</li>
      <li>IUTEST_FLAG マクロによるオプション指定に対応</li>
      <li>繰り返しオプション対応( --iutest_repeat=count )</li>
      <li>イベントリスナー対応</li>
      <li>グローバル環境セットに対応(iutest::AddGlobalTestEnvironment)</li>
      <li>複合条件テスト用に述語アサーションのヘルパーを追加(iuutil::CmpHelperOR)</li>
      <li>型付けテスト対応</li>
      <li>テストに乱数生成機能を追加( genrand )</li>
      <li>環境変数でのテストオプション指定に対応</li>
      <li>DISABLEDテスト実行オプション対応( --iutest_also_run_disabled_tests )</li>
      <li>例外キャッチオプション対応( --iutest_catch_exceptions=<0|1> )</li>
      <li>失敗時ブレークオプション対応( --iutest_break_on_failure )</li>
      <li>シャッフルテスト対応</li>
      <li>出力カラーオプション対応( --iutest_color=<yes|no|auto> )</li>
      <li>ヘルプオプション対応( --help )</li>
      <li>パラメータテスト対応</li>
      <li>DISABLED_ に対応</li>
      <li>xml 出力に対応</li>
    </ul>
  </li>
</ul>
*/

/**
 * @example main.cpp
 * @example assertion.cpp
 * @example disabledtest.cpp
 * @example exception.cpp
 * @example fixture.cpp
 * @example matcher.cpp
 * @example parameterized.cpp
 * @example printto.cpp
 * @example simple.cpp
 * @example typed.cpp
*/

#endif // INCG_IRIS_IUTEST_VER_HPP_D65CB7A7_D2AD_40FE_8F5F_8FBF376A0010_
#include <gtest/gtest.h>
#if defined(IUTEST_USE_GMOCK)
#include <gmock/gmock.h>
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_gmock_ver.hpp
 * @brief		google mock version 識別 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2014-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_GMOCK_VER_HPP_CBBF82C8_EB6F_4398_BAA6_5B485AC52D36_
#define INCG_IRIS_IUTEST_GMOCK_VER_HPP_CBBF82C8_EB6F_4398_BAA6_5B485AC52D36_

#if defined(IUTEST_USE_GTEST) && defined(IUTEST_USE_GMOCK)

//======================================================================
// include
#include <gmock/gmock.h>

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

// google mock version

#ifndef GMOCK_MAJORVER
#  define GMOCK_MAJORVER	0x01		//!< Major Version
#endif

//!< Minor Version
#ifndef GMOCK_MINORVER
#  if   defined(GMOCK_GMOCK_MORE_MATCHERS_H_)
#    define GMOCK_MINORVER	0x07
#  else
// v1.6.0 以前は未対応
#    define GMOCK_MINORVER	0x06
#  endif
#endif

#ifndef GMOCK_BUILD
#  define GTEST_BUILD		0x00		//!< Build
#endif

#ifndef GMOCK_REVISION
#  define GMOCK_REVISION	0x00		//!< Revision
#endif

#ifndef GMOCK_VER
#  define	GMOCK_VER		((GMOCK_MAJORVER<<24)	\
							|(GMOCK_MINORVER<<16)	\
							|(GMOCK_BUILD<<8)		\
							|(GMOCK_REVISION<<0)	\
							)	//!< google test version
#endif

#endif

#endif // INCG_IRIS_IUTEST_GMOCK_VER_HPP_CBBF82C8_EB6F_4398_BAA6_5B485AC52D36_
#endif
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_gtest_ver.hpp
 * @brief		gtest version 識別 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_GTEST_VER_HPP_7396AEF4_D1AB_44B5_9FE3_23CEC1240158_
#define INCG_IRIS_IUTEST_GTEST_VER_HPP_7396AEF4_D1AB_44B5_9FE3_23CEC1240158_

#if defined(IUTEST_USE_GTEST)

//======================================================================
// include
#include <gtest/gtest.h>

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

// gtest version

#ifndef GTEST_MAJORVER
#  define GTEST_MAJORVER	0x01		//!< Major Version
#endif

//!< Minor Version
#ifndef GTEST_MINORVER
#  if   defined(GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_)
#    define GTEST_MINORVER	0x08
#  elif !defined(RUN_ALL_TESTS) && !defined(GTEST_CREF_WORKAROUND_)
#    define GTEST_MINORVER	0x07
#  elif defined(ADD_FAILURE_AT)
#    define GTEST_MINORVER	0x06
#  elif defined(GTEST_API_)
#    define GTEST_MINORVER	0x05
#  elif defined(EXPECT_DEATH_IF_SUPPORTED)
#    define GTEST_MINORVER	0x04
#  elif defined(GTEST_HIDE_UNREACHABLE_CODE_)
#    define GTEST_MINORVER	0x03
#  elif defined(GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_)
#    define GTEST_MINORVER	0x02
#  elif defined(GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_)
#    define GTEST_MINORVER	0x01
#  else
#    define GTEST_MINORVER	0x00
#  endif
#endif

#ifndef GTEST_BUILD
#  if GTEST_MINORVER == 0x02 && defined(GTEST_HAS_CLONE)
#    define GTEST_BUILD		0x01		//!< Build
#  elif GTEST_MINORVER == 0x00
// 判断難しい
#    define GTEST_BUILD		0x01		//!< Build
#  else
#    define GTEST_BUILD		0x00		//!< Build
#  endif
#endif

#ifndef GTEST_REVISION
#  define GTEST_REVISION	0x00		//!< Revision
#endif

#ifndef GTEST_VER
#  define	GTEST_VER		((GTEST_MAJORVER<<24)	\
							|(GTEST_MINORVER<<16)	\
							|(GTEST_BUILD<<8)		\
							|(GTEST_REVISION<<0)	\
							)	//!< google test version
#endif

#endif

#endif // INCG_IRIS_IUTEST_GTEST_VER_HPP_7396AEF4_D1AB_44B5_9FE3_23CEC1240158_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_pragma.hpp
 * @brief		iris unit test pragma 依存の吸収 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PRAGMA_HPP_FBC5A1DE_3D0C_443E_84B1_5F0618DF9A6B_
#define INCG_IRIS_IUTEST_PRAGMA_HPP_FBC5A1DE_3D0C_443E_84B1_5F0618DF9A6B_

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

// pragma
#if   defined(_MSC_VER) && _MSC_VER >= 1310
#  define IUTEST_PRAGMA(x)	__pragma(x)
#elif defined(__GNUC__)
#  define IUTEST_PRAGMA(x)	_Pragma(#x)
#elif defined(__clang__)
#  define IUTEST_PRAGMA(x)	_Pragma(#x)
#else
#  define IUTEST_PRAGMA(x)
#endif

#define IUTEST_PRAGMA_MESSAGE(m)	IUTEST_PRAGMA(message (m))

// pragma warning
#if defined(_MSC_VER)
#  define IUTEST_PRAGMA_MSC_WARN_PUSH()			IUTEST_PRAGMA(warning (push))
#  define IUTEST_PRAGMA_MSC_WARN_DISABLE(x)		IUTEST_PRAGMA(warning (disable: x))
#  define IUTEST_PRAGMA_MSC_WARN_POP()			IUTEST_PRAGMA(warning (pop))
#endif

#if defined(__GNUC__)
#  if ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
#    define IUTEST_PRAGMA_GCC_WARN_PUSH()		IUTEST_PRAGMA(GCC diagnostic push)
#    define IUTEST_PRAGMA_GCC_WARN_DISABLE(x)	IUTEST_PRAGMA(GCC diagnostic ignored x)
#    define IUTEST_PRAGMA_GCC_WARN_POP()		IUTEST_PRAGMA(GCC diagnostic pop)
#  else
#    define IUTEST_PRAGMA_GCC_WARN_PUSH()		
#    define IUTEST_PRAGMA_GCC_WARN_DISABLE(x)	
#    define IUTEST_PRAGMA_GCC_WARN_POP()		
#  endif
#endif

#if defined(__clang__)
#  define IUTEST_PRAGMA_CLANG_WARN_PUSH()		IUTEST_PRAGMA(clang diagnostic push)
#  define IUTEST_PRAGMA_CLANG_WARN_DISABLE(x)	IUTEST_PRAGMA(clang diagnostic ignored x)
#  define IUTEST_PRAGMA_CLANG_WARN_POP()		IUTEST_PRAGMA(clang diagnostic pop)
#  if defined(__GNUC__)
#    undef IUTEST_PRAGMA_GCC_WARN_PUSH		
#    undef IUTEST_PRAGMA_GCC_WARN_DISABLE
#    undef IUTEST_PRAGMA_GCC_WARN_POP	
#  endif
#  define IUTEST_PRAGMA_GCC_WARN_PUSH			IUTEST_PRAGMA_CLANG_WARN_PUSH
#  define IUTEST_PRAGMA_GCC_WARN_DISABLE		IUTEST_PRAGMA_CLANG_WARN_DISABLE
#  define IUTEST_PRAGMA_GCC_WARN_POP			IUTEST_PRAGMA_CLANG_WARN_POP
#endif

#ifndef IUTEST_PRAGMA_MSC_WARN_PUSH
#  define IUTEST_PRAGMA_MSC_WARN_PUSH()
#endif
#ifndef IUTEST_PRAGMA_MSC_WARN_DISABLE
#  define IUTEST_PRAGMA_MSC_WARN_DISABLE(x)
#endif
#ifndef IUTEST_PRAGMA_MSC_WARN_POP
#  define IUTEST_PRAGMA_MSC_WARN_POP()
#endif

#ifndef IUTEST_PRAGMA_GCC_WARN_PUSH
#  define IUTEST_PRAGMA_GCC_WARN_PUSH()
#endif
#ifndef IUTEST_PRAGMA_GCC_WARN_DISABLE
#  define IUTEST_PRAGMA_GCC_WARN_DISABLE(x)
#endif
#ifndef IUTEST_PRAGMA_GCC_WARN_POP
#  define IUTEST_PRAGMA_GCC_WARN_POP()
#endif

#ifndef IUTEST_PRAGMA_CLANG_WARN_PUSH
#  define IUTEST_PRAGMA_CLANG_WARN_PUSH()
#endif
#ifndef IUTEST_PRAGMA_CLANG_WARN_DISABLE
#  define IUTEST_PRAGMA_CLANG_WARN_DISABLE(x)
#endif
#ifndef IUTEST_PRAGMA_CLANG_WARN_POP
#  define IUTEST_PRAGMA_CLANG_WARN_POP()
#endif

#if   defined(_MSC_VER)
#  define IUTEST_PARGMA_WARN_PUSH()		IUTEST_PRAGMA_MSC_WARN_PUSH()
#  define IUTEST_PARGMA_WARN_POP()		IUTEST_PRAGMA_MSC_WARN_POP()
#elif defined(__GNUC__)
#  define IUTEST_PARGMA_WARN_PUSH()		IUTEST_PRAGMA_GCC_WARN_PUSH()
#  define IUTEST_PARGMA_WARN_POP()		IUTEST_PRAGMA_GCC_WARN_POP()
#elif defined(__clang__)
#  define IUTEST_PARGMA_WARN_PUSH()		IUTEST_PRAGMA_CLANG_WARN_PUSH()
#  define IUTEST_PARGMA_WARN_POP()		IUTEST_PRAGMA_CLANG_WARN_PUSH()
#else
#  define IUTEST_PARGMA_WARN_PUSH()
#  define IUTEST_PARGMA_WARN_POP()
#endif


// pragma warning xxx
#if defined(_MSC_VER) && defined(__STDC_WANT_SECURE_LIB__) && __STDC_WANT_SECURE_LIB__
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()		IUTEST_PRAGMA_MSC_WARN_PUSH()	\
															IUTEST_PRAGMA_MSC_WARN_DISABLE(4996)
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()		IUTEST_PRAGMA_MSC_WARN_POP()
#else
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
#  define IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
#endif

#if defined(_MSC_VER) && _MSC_VER < 1700
#  define IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()	IUTEST_PRAGMA_MSC_WARN_PUSH()	\
																IUTEST_PRAGMA_MSC_WARN_DISABLE(4231)
#  define IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()		IUTEST_PRAGMA_MSC_WARN_POP()
#else
#  define IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()
#  define IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()
#endif

#if defined(_MSC_VER) && IUTEST_HAS_CONSTEXPR
#  define IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()	IUTEST_PRAGMA_MSC_WARN_PUSH()	\
																			IUTEST_PRAGMA_MSC_WARN_DISABLE(4592)
#  define IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()		IUTEST_PRAGMA_MSC_WARN_POP()
#else
#  define IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_BEGIN()
#  define IUTEST_PRAGMA_CONSTEXPR_CALLED_AT_RUNTIME_WARN_DISABLE_END()
#endif


#if   defined(_MSC_VER)
#  define IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()	IUTEST_PRAGMA(warning (disable:4389 4018))
#elif defined(__clang__)
#  define IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()	IUTEST_PRAGMA_CLANG_WARN_DISABLE("-Wsign-compare")
#elif defined(__GNUC__)
#  define IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()	IUTEST_PRAGMA_GCC_WARN_DISABLE("-Wsign-compare")
#else
#  define IUTEST_PRAGMA_WARN_DISABLE_SIGN_COMPARE()
#endif

#if   defined(_MSC_VER)
#  define IUTEST_PRAGMA_WARN_DISABLE_EMPTY_BODY()	IUTEST_PRAGMA(warning (disable:4390))
#elif defined(__clang__)
#  define IUTEST_PRAGMA_WARN_DISABLE_EMPTY_BODY()	IUTEST_PRAGMA_CLANG_WARN_DISABLE("-Wempty-body")
#elif defined(__GNUC__)
#  define IUTEST_PRAGMA_WARN_DISABLE_EMPTY_BODY()	IUTEST_PRAGMA_GCC_WARN_DISABLE("-Wempty-body")
#else
#  define IUTEST_PRAGMA_WARN_DISABLE_EMPTY_BODY()
#endif

#endif // INCG_IRIS_IUTEST_PRAGMA_HPP_FBC5A1DE_3D0C_443E_84B1_5F0618DF9A6B_

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

#if defined(INCG_IRIS_IUTEST_HPP_)
#undef IUTEST_SUCCEED
#undef IUTEST_FAIL
#undef IUTEST_ADD_FAILURE
#undef IUTEST_ADD_FAILURE_AT

#undef IUTEST_HAS_PARAM_TEST
#undef IUTEST_HAS_AUTOFIXTURE_PARAM_TEST
#undef IUTEST_HAS_ANY_PARAM_TEST
#undef IUTEST_HAS_COMBINE
#undef IUTEST_HAS_VARIADIC_COMBINE
#undef IUTEST_HAS_PAIRWISE
#undef IUTEST_HAS_VARIADIC_PAIRWISE
#undef IUTEST_HAS_CONCAT
#undef IUTEST_HAS_VARIADIC_PRED
#undef IUTEST_HAS_TYPED_TEST
#undef IUTEST_HAS_TYPED_TEST_P
#undef IUTEST_TYPED_TEST_P_STRICT

#undef IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE
#undef IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE

#undef IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT

#undef IUTEST_HAS_VALUESGEN
#undef IUTEST_HAS_RANDOMVALUES
#undef IUTEST_STATIC_ASSERT_MSG
#undef IUTEST_HAS_STATIC_ASSERT_TYPEEQ
#ifdef IUTEST_USE_THROW_ON_ASSERT_FAILURE
#  undef IUTEST_USE_THROW_ON_ASSERT_FAILURE
#endif
#undef IUTEST_USE_THROW_ON_ASSERTION_FAILURE
#undef IUTEST_HAS_LAMBDA_STATEMENTS
#undef IUTEST_HAS_SPI_LAMBDA_SUPPORT
#undef IUTEST_HAS_GENRAND
#undef IUTEST_HAS_PRINT_TO
#undef IUTEST_HAS_TESTNAME_ALIAS
#undef IUTEST_HAS_TESTNAME_ALIAS_JP
#undef IUTEST_HAS_STREAM_RESULT

#undef IUTEST_HAS_VARIADIC_TEMPLATES
#undef IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES
#undef IUTEST_HAS_INITIALIZER_LIST
#undef IUTEST_HAS_CHAR16_T
#undef IUTEST_HAS_CHAR32_T

#undef IUTEST_HAS_EXCEPTIONS
#undef IUTEST_HAS_RTTI
#undef IUTEST_HAS_REGEX
#undef IUTEST_HAS_SEH

#undef IUTEST_HAS_STREAMCAPTURE

#undef IUTEST_OPERAND
#undef IUTEST_EXPRESSION

#endif

#define IUTEST_SUCCEED			GTEST_SUCCEED
#define IUTEST_FAIL				GTEST_FAIL
#define IUTEST_ADD_FAILURE		ADD_FAILURE
#define IUTEST_ADD_FAILURE_AT	ADD_FAILURE_AT

#define IUTEST_HAS_PARAM_TEST				GTEST_HAS_PARAM_TEST
#define IUTEST_HAS_AUTOFIXTURE_PARAM_TEST	0
#define IUTEST_HAS_ANY_PARAM_TEST			0
#define IUTEST_HAS_COMBINE					GTEST_HAS_COMBINE
#define IUTEST_HAS_VARIADIC_COMBINE			0
#define IUTEST_HAS_PAIRWISE					0
#define IUTEST_HAS_VARIADIC_PAIRWISE		0
#define IUTEST_HAS_CONCAT					0
#define IUTEST_HAS_VARIADIC_PRED			0
#define IUTEST_HAS_TYPED_TEST				GTEST_HAS_TYPED_TEST
#define IUTEST_HAS_TYPED_TEST_P				GTEST_HAS_TYPED_TEST_P
#define IUTEST_TYPED_TEST_P_STRICT			1

#define IUTEST_HAS_ARITHMETIC_EXPRESSION_DECOMPOSE	0
#define IUTEST_HAS_BITWISE_EXPRESSION_DECOMPOSE		1

#define IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT	0

#define IUTEST_HAS_VALUESGEN			0
#define IUTEST_HAS_RANDOMVALUES			0
#define IUTEST_HAS_STATIC_ASSERT_TYPEEQ	1
#define IUTEST_USE_THROW_ON_ASSERTION_FAILURE	0
#define IUTEST_HAS_LAMBDA_STATEMENTS	0
#define IUTEST_HAS_SPI_LAMBDA_SUPPORT	0
#define IUTEST_HAS_GENRAND				0
#define IUTEST_HAS_PRINT_TO				1
#define IUTEST_HAS_TESTNAME_ALIAS		0
#define IUTEST_HAS_TESTNAME_ALIAS_JP	0
#define IUTEST_HAS_STREAM_RESULT		1

#define IUTEST_HAS_STREAMCAPTURE		0

#define IUTEST_HAS_EXCEPTIONS		GTEST_HAS_EXCEPTIONS
#define IUTEST_HAS_RTTI				GTEST_HAS_RTTI
#define IUTEST_HAS_REGEX			GTEST_USES_POSIX_RE
#define IUTEST_HAS_SEH				GTEST_HAS_SEH







#ifndef IUTEST_STATIC_ASSERT_MSG
#  define IUTEST_STATIC_ASSERT_MSG(B, Msg)	\
	typedef ::testing::iusupport::StaticAssertionTest< sizeof(::testing::iusupport::StaticAssertionFailure< (bool)B >) > IUTEST_PP_CAT(iutest_static_assert_typedef_, __LINE__)
#endif

#ifndef IUTEST_STATIC_ASSERT
#  define IUTEST_STATIC_ASSERT(...)	IUTEST_STATIC_ASSERT_MSG((__VA_ARGS__), "")
#endif

#ifdef IUTEST_ASSERT_EXIT
#  undef IUTEST_ASSERT_EXIT
#endif
#define IUTEST_ASSERT_EXIT(cond)	do { if( !(cond) ) {													\
										GTEST_MESSAGE_(#cond, ::testing::TestPartResult::kFatalFailure);	\
										exit(1);															\
									} } while(::testing::internal::AlwaysFalse())

#define IUTEST_OPERAND(op)			op
#define IUTEST_EXPRESSION(expr)		expr

#if GTEST_VER < 0x01070000

#undef GTEST_COMPILE_ASSERT_
#define GTEST_COMPILE_ASSERT_(expr, msg) \
  typedef ::testing::internal::CompileAssert<(static_cast<bool>(expr))> \
      msg[static_cast<bool>(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_

#endif

namespace testing
{

//======================================================================
// function
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, char** argv)
{
	InitGoogleTest(pargc, argv);
}
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, wchar_t** argv)
{
	InitGoogleTest(pargc, argv);
}
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, const char** argv)
{
	InitGoogleTest(pargc, const_cast<char**>(argv));
}
inline void IUTEST_ATTRIBUTE_UNUSED_ InitIrisUnitTest(int* pargc, const wchar_t** argv)
{
	InitGoogleTest(pargc, const_cast<wchar_t**>(argv));
}

// tuple
namespace tuples
{
#if GTEST_HAS_STD_TUPLE_
	using ::std::tuple;
	using ::std::tuple_size;
	using ::std::tuple_element;
	using ::std::make_tuple;
	using ::std::get;
#else
	using ::std::tr1::tuple;
	using ::std::tr1::tuple_size;
	using ::std::tr1::tuple_element;
	using ::std::tr1::make_tuple;
	using ::std::tr1::get;
#endif
}

#if GTEST_VER < 0x01080000
using tuples::tuple;
using tuples::tuple_size;
using tuples::tuple_element;
#endif

using tuples::make_tuple;
using tuples::get;

namespace iusupport
{
	
	template<bool b>struct StaticAssertionFailure;
	
	template<> struct StaticAssertionFailure<true> { enum { value = 1 }; };
	
	template<int x>struct StaticAssertionTest {};
}

#if defined(INCG_IRIS_IUTEST_HPP_)

namespace iusupport
{
	inline AssertionResult iuMakeAssertionResult(const AssertionResult& ar) { return ar; }
	inline AssertionResult iuMakeAssertionResult(const ::iutest::AssertionResult& ar)
	{
		return AssertionResult(static_cast<bool>(ar)) << ar.message();
	}
}

// ::iutest::AssertionResult -> ::testing::AssertionResult
#undef GTEST_ASSERT_
#define GTEST_ASSERT_(expression, on_failure) \
  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  if (const ::testing::AssertionResult gtest_ar = ::testing::iusupport::iuMakeAssertionResult(expression)) \
	; \
  else \
	on_failure(gtest_ar.failure_message())

#endif

namespace internal
{

template<typename T>
struct is_pointer<T* volatile> : public true_type {};

}	// end of namespace internal

// ostream
typedef ::std::ostream	iu_ostream;

}	// end of namespace testing

#if defined(INCG_IRIS_IUTEST_HPP_)
// すでに iutest namespace が存在するので、define で対応
#  define iutest testing
#else
namespace iutest = testing;
#endif

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util.hpp
 * @brief		iris unit test utility
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_HPP_EBAC3846_4D1E_4B32_A85F_6D6A7CCFAF75_
#define INCG_IRIS_IUTEST_UTIL_HPP_EBAC3846_4D1E_4B32_A85F_6D6A7CCFAF75_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util_assertion.hpp
 * @brief		iris unit test assertion 拡張 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_ASSERTION_HPP_A45F8265_40E0_44F2_91C6_090B1778657C_
#define INCG_IRIS_IUTEST_UTIL_ASSERTION_HPP_A45F8265_40E0_44F2_91C6_090B1778657C_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_type_traits.hpp
 * @brief		iris unit test type traits
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_TYPE_TRAITS_HPP_6F091F15_784A_4F50_BD18_B8F67C5AF0CF_
#define INCG_IRIS_IUTEST_TYPE_TRAITS_HPP_6F091F15_784A_4F50_BD18_B8F67C5AF0CF_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_pp.hpp
 * @brief		iris unit test プリプロセッサ 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_PP_HPP_E8F72184_9C72_4E74_B581_A1F51F291F3A_
#define INCG_IRIS_IUTEST_PP_HPP_E8F72184_9C72_4E74_B581_A1F51F291F3A_

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

/**
 * @brief	コピー禁止定義
*/
#define IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TypeName)	\
	TypeName( const TypeName& );						\
	TypeName& operator = ( const TypeName& )

/**
 * @brief	代入禁止定義
*/
#define IUTEST_PP_DISALLOW_ASSIGN(TypeName)		\
	TypeName& operator = ( const TypeName& )

/**
 * @brief	コピー/ムーブ禁止定義
*/
#if defined(IUTEST_HAS_RVALUE_REFS) && IUTEST_HAS_RVALUE_REFS
#  define IUTEST_PP_DISALLOW_MOVE_AND_COPY_AND_ASSIGN(TypeName)	\
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TypeName);				\
	TypeName( TypeName&& rhs );									\
	TypeName& operator = ( TypeName&& )
#else
#  define IUTEST_PP_DISALLOW_MOVE_AND_COPY_AND_ASSIGN(TypeName)	\
	IUTEST_PP_DISALLOW_COPY_AND_ASSIGN(TypeName)
#endif

/**
 * @private
 * @{
*/

#if !defined(IUTEST_PP_TOSTRING)
#  define IUTEST_PP_TOSTRING(z_)	IUTEST_PP_TOSTRING_(z_)
#endif
#define IUTEST_PP_TOSTRING_(z_)		#z_

#if !defined(IUTEST_PP_CAT)
#  define IUTEST_PP_CAT(a_, b_)		IUTEST_PP_CAT_(a_, b_)
#endif
#define IUTEST_PP_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		IUTEST_PP_CAT(__LINE__, __COUNTER__)
#else
#  define IUTEST_PP_UNIQUEID		__LINE__
#endif

#define IUTEST_UNUSED_VAR(x)		(void)(x)

// DEC
#define IUTEST_PP_DEC(n)	IUTEST_PP_DEC_I(n)
#define IUTEST_PP_DEC_I(n)	IUTEST_PP_DEC_##n
#define IUTEST_PP_DEC_0		nil
#define IUTEST_PP_DEC_1		0
#define IUTEST_PP_DEC_2		1
#define IUTEST_PP_DEC_3		2
#define IUTEST_PP_DEC_4		3
#define IUTEST_PP_DEC_5		4
#define IUTEST_PP_DEC_6		5
#define IUTEST_PP_DEC_7		6
#define IUTEST_PP_DEC_8		7
#define IUTEST_PP_DEC_9		8
#define IUTEST_PP_DEC_10	9
#define IUTEST_PP_DEC_11	10
#define IUTEST_PP_DEC_12	11
#define IUTEST_PP_DEC_13	12
#define IUTEST_PP_DEC_14	13
#define IUTEST_PP_DEC_15	14
#define IUTEST_PP_DEC_16	15
#define IUTEST_PP_DEC_17	16
#define IUTEST_PP_DEC_18	17
#define IUTEST_PP_DEC_19	18
#define IUTEST_PP_DEC_20	19
#define IUTEST_PP_DEC_21	20
#define IUTEST_PP_DEC_22	21
#define IUTEST_PP_DEC_23	22
#define IUTEST_PP_DEC_24	23
#define IUTEST_PP_DEC_25	24
#define IUTEST_PP_DEC_26	25
#define IUTEST_PP_DEC_27	26
#define IUTEST_PP_DEC_28	27
#define IUTEST_PP_DEC_29	28
#define IUTEST_PP_DEC_30	29
#define IUTEST_PP_DEC_31	30
#define IUTEST_PP_DEC_32	31
#define IUTEST_PP_DEC_33	32
#define IUTEST_PP_DEC_34	33
#define IUTEST_PP_DEC_35	34
#define IUTEST_PP_DEC_36	35
#define IUTEST_PP_DEC_37	36
#define IUTEST_PP_DEC_38	37
#define IUTEST_PP_DEC_39	38
#define IUTEST_PP_DEC_40	39
#define IUTEST_PP_DEC_41	40
#define IUTEST_PP_DEC_42	41
#define IUTEST_PP_DEC_43	42
#define IUTEST_PP_DEC_44	43
#define IUTEST_PP_DEC_45	44
#define IUTEST_PP_DEC_46	45
#define IUTEST_PP_DEC_47	46
#define IUTEST_PP_DEC_48	47
#define IUTEST_PP_DEC_49	48
#define IUTEST_PP_DEC_50	49
#define IUTEST_PP_DEC_51	50
#define IUTEST_PP_DEC_52	51
#define IUTEST_PP_DEC_53	52
#define IUTEST_PP_DEC_54	53
#define IUTEST_PP_DEC_55	54
#define IUTEST_PP_DEC_56	55
#define IUTEST_PP_DEC_57	56
#define IUTEST_PP_DEC_58	57
#define IUTEST_PP_DEC_59	58
#define IUTEST_PP_DEC_60	59
#define IUTEST_PP_DEC_61	60
#define IUTEST_PP_DEC_62	61
#define IUTEST_PP_DEC_63	62
#define IUTEST_PP_DEC_64	63
#define IUTEST_PP_DEC_65	64
#define IUTEST_PP_DEC_66	65
#define IUTEST_PP_DEC_67	66
#define IUTEST_PP_DEC_68	67
#define IUTEST_PP_DEC_69	68
#define IUTEST_PP_DEC_70	69
#define IUTEST_PP_DEC_71	70
#define IUTEST_PP_DEC_72	71
#define IUTEST_PP_DEC_73	72
#define IUTEST_PP_DEC_74	73
#define IUTEST_PP_DEC_75	74
#define IUTEST_PP_DEC_76	75
#define IUTEST_PP_DEC_77	76
#define IUTEST_PP_DEC_78	77
#define IUTEST_PP_DEC_79	78
#define IUTEST_PP_DEC_80	79
#define IUTEST_PP_DEC_81	80
#define IUTEST_PP_DEC_82	81
#define IUTEST_PP_DEC_83	82
#define IUTEST_PP_DEC_84	83
#define IUTEST_PP_DEC_85	84
#define IUTEST_PP_DEC_86	85
#define IUTEST_PP_DEC_87	86
#define IUTEST_PP_DEC_88	87
#define IUTEST_PP_DEC_89	88
#define IUTEST_PP_DEC_90	89
#define IUTEST_PP_DEC_91	90
#define IUTEST_PP_DEC_92	91
#define IUTEST_PP_DEC_93	92
#define IUTEST_PP_DEC_94	93
#define IUTEST_PP_DEC_95	94
#define IUTEST_PP_DEC_96	95
#define IUTEST_PP_DEC_97	96
#define IUTEST_PP_DEC_98	97
#define IUTEST_PP_DEC_99	98
#define IUTEST_PP_DEC_100	99

// INC
#define IUTEST_PP_INC(n)	IUTEST_PP_INC_I(n)
#define IUTEST_PP_INC_I(n)	IUTEST_PP_INC_##n
#define IUTEST_PP_INC_0		1
#define IUTEST_PP_INC_1		2
#define IUTEST_PP_INC_2		3
#define IUTEST_PP_INC_3		4
#define IUTEST_PP_INC_4		5
#define IUTEST_PP_INC_5		6
#define IUTEST_PP_INC_6		7
#define IUTEST_PP_INC_7		8
#define IUTEST_PP_INC_8		9
#define IUTEST_PP_INC_9		10
#define IUTEST_PP_INC_10	11
#define IUTEST_PP_INC_11	12
#define IUTEST_PP_INC_12	13
#define IUTEST_PP_INC_13	14
#define IUTEST_PP_INC_14	15
#define IUTEST_PP_INC_15	16
#define IUTEST_PP_INC_16	17
#define IUTEST_PP_INC_17	18
#define IUTEST_PP_INC_18	19
#define IUTEST_PP_INC_19	20
#define IUTEST_PP_INC_20	21
#define IUTEST_PP_INC_21	22
#define IUTEST_PP_INC_22	23
#define IUTEST_PP_INC_23	24
#define IUTEST_PP_INC_24	25
#define IUTEST_PP_INC_25	26
#define IUTEST_PP_INC_26	27
#define IUTEST_PP_INC_27	28
#define IUTEST_PP_INC_28	29
#define IUTEST_PP_INC_29	30
#define IUTEST_PP_INC_30	31
#define IUTEST_PP_INC_31	32
#define IUTEST_PP_INC_32	33
#define IUTEST_PP_INC_33	34
#define IUTEST_PP_INC_34	35
#define IUTEST_PP_INC_35	36
#define IUTEST_PP_INC_36	37
#define IUTEST_PP_INC_37	38
#define IUTEST_PP_INC_38	39
#define IUTEST_PP_INC_39	40
#define IUTEST_PP_INC_40	41
#define IUTEST_PP_INC_41	42
#define IUTEST_PP_INC_42	43
#define IUTEST_PP_INC_43	44
#define IUTEST_PP_INC_44	45
#define IUTEST_PP_INC_45	46
#define IUTEST_PP_INC_46	47
#define IUTEST_PP_INC_47	48
#define IUTEST_PP_INC_48	49
#define IUTEST_PP_INC_49	50
#define IUTEST_PP_INC_50	51
#define IUTEST_PP_INC_51	52
#define IUTEST_PP_INC_52	53
#define IUTEST_PP_INC_53	54
#define IUTEST_PP_INC_54	55
#define IUTEST_PP_INC_55	56
#define IUTEST_PP_INC_56	57
#define IUTEST_PP_INC_57	58
#define IUTEST_PP_INC_58	59
#define IUTEST_PP_INC_59	60
#define IUTEST_PP_INC_60	61
#define IUTEST_PP_INC_61	62
#define IUTEST_PP_INC_62	63
#define IUTEST_PP_INC_63	64
#define IUTEST_PP_INC_64	65
#define IUTEST_PP_INC_65	66
#define IUTEST_PP_INC_66	67
#define IUTEST_PP_INC_67	68
#define IUTEST_PP_INC_68	69
#define IUTEST_PP_INC_69	70
#define IUTEST_PP_INC_70	71
#define IUTEST_PP_INC_71	72
#define IUTEST_PP_INC_72	73
#define IUTEST_PP_INC_73	74
#define IUTEST_PP_INC_74	75
#define IUTEST_PP_INC_75	76
#define IUTEST_PP_INC_76	77
#define IUTEST_PP_INC_77	78
#define IUTEST_PP_INC_78	79
#define IUTEST_PP_INC_79	80
#define IUTEST_PP_INC_80	81
#define IUTEST_PP_INC_81	82
#define IUTEST_PP_INC_82	83
#define IUTEST_PP_INC_83	84
#define IUTEST_PP_INC_84	85
#define IUTEST_PP_INC_85	86
#define IUTEST_PP_INC_86	87
#define IUTEST_PP_INC_87	88
#define IUTEST_PP_INC_88	89
#define IUTEST_PP_INC_89	90
#define IUTEST_PP_INC_90	91
#define IUTEST_PP_INC_91	92
#define IUTEST_PP_INC_92	93
#define IUTEST_PP_INC_93	94
#define IUTEST_PP_INC_94	95
#define IUTEST_PP_INC_95	96
#define IUTEST_PP_INC_96	97
#define IUTEST_PP_INC_97	98
#define IUTEST_PP_INC_98	99
#define IUTEST_PP_INC_99	100
#define IUTEST_PP_INC_100	nil

// REPEAT
#define IUTEST_PP_LIMIT_REPEAT	50

#define IUTEST_PP_REPEAT_PARAMS_MACRO_(i, param)	param
#define IUTEST_PP_REPEAT_PARAMS_MACRO_IN_BINARY_(i, param1, param2)	param2(i, param1)

#define IUTEST_PP_REPEAT_PARAMS(n, param)			IUTEST_PP_REPEAT(n, IUTEST_PP_REPEAT_PARAMS_MACRO_, param)
#define IUTEST_PP_REPEAT(n, m, param)				IUTEST_PP_REPEAT_BINARY(n, IUTEST_PP_REPEAT_PARAMS_MACRO_IN_BINARY_, param, m)

#define IUTEST_PP_REPEAT_BINARY_PARAMS_MACRO_(i, param1, param2)	param1 param2

#define IUTEST_PP_REPEAT_BINARY_PARAMS(n, param1, param2)	IUTEST_PP_REPEAT_BINARY(n, IUTEST_PP_REPEAT_BINARY_PARAMS_MACRO_, param1, param2)
#define IUTEST_PP_REPEAT_BINARY(n, m, param1, param2)		IUTEST_PP_REPEAT_BINARY_PARAMS_I(n, m, param1, param2)

#define IUTEST_PP_REPEAT_BINARY_PARAMS_I(n, m, p1, p2)	IUTEST_PP_CAT(IUTEST_PP_REPEAT_I_, IUTEST_PP_DEC(n))(0, m, p1, p2)

#define IUTEST_PP_REPEAT_I_nil(i, m, p1, p2)
#define IUTEST_PP_REPEAT_I_0( i, m, p1, p2)		m(i, p1, p2)
#define IUTEST_PP_REPEAT_I_1( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_0 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_2( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_1 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_3( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_2 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_4( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_3 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_5( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_4 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_6( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_5 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_7( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_6 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_8( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_7 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_9( i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_8 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_10(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_9 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_11(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_10(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_12(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_11(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_13(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_12(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_14(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_13(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_15(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_14(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_16(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_15(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_17(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_16(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_18(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_17(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_19(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_18(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_20(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_19(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_21(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_20(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_22(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_21(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_23(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_22(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_24(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_23(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_25(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_24(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_26(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_25(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_27(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_26(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_28(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_27(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_29(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_28(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_30(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_29(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_31(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_30(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_32(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_31(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_33(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_32(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_34(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_33(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_35(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_34(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_36(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_35(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_37(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_36(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_38(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_37(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_39(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_38(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_40(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_39(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_41(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_40(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_42(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_41(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_43(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_42(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_44(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_43(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_45(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_44(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_46(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_45(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_47(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_46(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_48(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_47(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_49(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_48(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_REPEAT_I_50(i, m, p1, p2)		m(i, p1, p2) IUTEST_PP_REPEAT_I_49(IUTEST_PP_INC(i), m, p1, p2)

// ENUM
#define IUTEST_PP_LIMIT_ENUM	50

#define IUTEST_PP_ENUM_PARAMS_MACRO_(i, param)	IUTEST_PP_CAT(param, i)
#define IUTEST_PP_ENUM_PARAMS_MACRO_IN_BINARY_(i, param1, param2)	param2(i, param1)

#define IUTEST_PP_ENUM_PARAMS(n, param)			IUTEST_PP_ENUM(n, IUTEST_PP_ENUM_PARAMS_MACRO_, param)
#define IUTEST_PP_ENUM(n, m, param)				IUTEST_PP_ENUM_BINARY(n, IUTEST_PP_ENUM_PARAMS_MACRO_IN_BINARY_, param, m)

#define IUTEST_PP_ENUM_SHIFTED_PARAMS(n, param)	IUTEST_PP_ENUM_SHIFTED(n, IUTEST_PP_ENUM_PARAMS_MACRO_, param)
#define IUTEST_PP_ENUM_SHIFTED(n, m, param)		IUTEST_PP_ENUM_SHIFTED_BINARY(n, IUTEST_PP_ENUM_PARAMS_MACRO_IN_BINARY_, param, m)

#define IUTEST_PP_ENUM_BINARY_PARAMS_MACRO_(i, param1, param2)	IUTEST_PP_CAT(param1, i) IUTEST_PP_CAT(param2, i)

#define IUTEST_PP_ENUM_BINARY_PARAMS(n, param1, param2)			IUTEST_PP_ENUM_BINARY(n, IUTEST_PP_ENUM_BINARY_PARAMS_MACRO_, param1, param2)
#define IUTEST_PP_ENUM_BINARY(n, m, param1, param2)				IUTEST_PP_ENUM_BINARY_PARAMS_I(0, n, m, param1, param2)

#define IUTEST_PP_ENUM_SHIFTED_BINARY_PARAMS(n, param1, param2)	IUTEST_PP_ENUM_BINARY(n, IUTEST_PP_ENUM_BINARY_PARAMS_MACRO_, param1, param2)
#define IUTEST_PP_ENUM_SHIFTED_BINARY(n, m, param1, param2)		IUTEST_PP_ENUM_BINARY_PARAMS_I(1, n, m, param1, param2)

#define IUTEST_PP_ENUM_BINARY_PARAMS_I(begin, n, m, p1, p2)	IUTEST_PP_CAT(IUTEST_PP_ENUM_I_, IUTEST_PP_DEC(n))(begin, m, p1, p2)

#define IUTEST_PP_ENUM_I_nil(i, m, p1, p2)	
#define IUTEST_PP_ENUM_I_0( i, m, p1, p2)	m(i, p1, p2)
#define IUTEST_PP_ENUM_I_1( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_0 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_2( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_1 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_3( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_2 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_4( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_3 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_5( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_4 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_6( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_5 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_7( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_6 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_8( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_7 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_9( i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_8 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_10(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_9 (IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_11(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_10(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_12(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_11(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_13(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_12(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_14(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_13(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_15(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_14(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_16(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_15(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_17(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_16(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_18(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_17(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_19(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_18(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_20(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_19(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_21(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_20(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_22(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_21(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_23(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_22(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_24(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_23(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_25(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_24(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_26(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_25(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_27(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_26(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_28(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_27(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_29(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_28(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_30(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_29(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_31(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_30(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_32(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_31(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_33(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_32(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_34(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_33(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_35(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_34(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_36(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_35(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_37(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_36(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_38(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_37(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_39(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_38(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_40(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_39(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_41(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_40(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_42(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_41(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_43(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_42(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_44(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_43(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_45(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_44(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_46(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_45(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_47(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_46(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_48(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_47(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_49(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_48(IUTEST_PP_INC(i), m, p1, p2)
#define IUTEST_PP_ENUM_I_50(i, m, p1, p2)	m(i, p1, p2), IUTEST_PP_ENUM_I_49(IUTEST_PP_INC(i), m, p1, p2)

// BOOL
#define IUTEST_PP_BOOL(n)	IUTEST_PP_BOOL_I(n)
#define IUTEST_PP_BOOL_I(n)	IUTEST_PP_BOOL_##n
#define IUTEST_PP_BOOL_0	0
#define IUTEST_PP_BOOL_1	1
#define IUTEST_PP_BOOL_2	1
#define IUTEST_PP_BOOL_3	1
#define IUTEST_PP_BOOL_4	1
#define IUTEST_PP_BOOL_5	1
#define IUTEST_PP_BOOL_6	1
#define IUTEST_PP_BOOL_7	1
#define IUTEST_PP_BOOL_8	1
#define IUTEST_PP_BOOL_9	1
#define IUTEST_PP_BOOL_10	1
#define IUTEST_PP_BOOL_11	1
#define IUTEST_PP_BOOL_12	1
#define IUTEST_PP_BOOL_13	1
#define IUTEST_PP_BOOL_14	1
#define IUTEST_PP_BOOL_15	1
#define IUTEST_PP_BOOL_16	1
#define IUTEST_PP_BOOL_17	1
#define IUTEST_PP_BOOL_18	1
#define IUTEST_PP_BOOL_19	1
#define IUTEST_PP_BOOL_20	1
#define IUTEST_PP_BOOL_21	1
#define IUTEST_PP_BOOL_22	1
#define IUTEST_PP_BOOL_23	1
#define IUTEST_PP_BOOL_24	1
#define IUTEST_PP_BOOL_25	1
#define IUTEST_PP_BOOL_26	1
#define IUTEST_PP_BOOL_27	1
#define IUTEST_PP_BOOL_28	1
#define IUTEST_PP_BOOL_29	1
#define IUTEST_PP_BOOL_30	1
#define IUTEST_PP_BOOL_31	1
#define IUTEST_PP_BOOL_32	1
#define IUTEST_PP_BOOL_33	1
#define IUTEST_PP_BOOL_34	1
#define IUTEST_PP_BOOL_35	1
#define IUTEST_PP_BOOL_36	1
#define IUTEST_PP_BOOL_37	1
#define IUTEST_PP_BOOL_38	1
#define IUTEST_PP_BOOL_39	1
#define IUTEST_PP_BOOL_40	1
#define IUTEST_PP_BOOL_41	1
#define IUTEST_PP_BOOL_42	1
#define IUTEST_PP_BOOL_43	1
#define IUTEST_PP_BOOL_44	1
#define IUTEST_PP_BOOL_45	1
#define IUTEST_PP_BOOL_46	1
#define IUTEST_PP_BOOL_47	1
#define IUTEST_PP_BOOL_48	1
#define IUTEST_PP_BOOL_49	1
#define IUTEST_PP_BOOL_50	1
#define IUTEST_PP_BOOL_51	1
#define IUTEST_PP_BOOL_52	1
#define IUTEST_PP_BOOL_53	1
#define IUTEST_PP_BOOL_54	1
#define IUTEST_PP_BOOL_55	1
#define IUTEST_PP_BOOL_56	1
#define IUTEST_PP_BOOL_57	1
#define IUTEST_PP_BOOL_58	1
#define IUTEST_PP_BOOL_59	1
#define IUTEST_PP_BOOL_60	1
#define IUTEST_PP_BOOL_61	1
#define IUTEST_PP_BOOL_62	1
#define IUTEST_PP_BOOL_63	1
#define IUTEST_PP_BOOL_64	1
#define IUTEST_PP_BOOL_65	1
#define IUTEST_PP_BOOL_66	1
#define IUTEST_PP_BOOL_67	1
#define IUTEST_PP_BOOL_68	1
#define IUTEST_PP_BOOL_69	1
#define IUTEST_PP_BOOL_70	1
#define IUTEST_PP_BOOL_71	1
#define IUTEST_PP_BOOL_72	1
#define IUTEST_PP_BOOL_73	1
#define IUTEST_PP_BOOL_74	1
#define IUTEST_PP_BOOL_75	1
#define IUTEST_PP_BOOL_76	1
#define IUTEST_PP_BOOL_77	1
#define IUTEST_PP_BOOL_78	1
#define IUTEST_PP_BOOL_79	1
#define IUTEST_PP_BOOL_80	1
#define IUTEST_PP_BOOL_81	1
#define IUTEST_PP_BOOL_82	1
#define IUTEST_PP_BOOL_83	1
#define IUTEST_PP_BOOL_84	1
#define IUTEST_PP_BOOL_85	1
#define IUTEST_PP_BOOL_86	1
#define IUTEST_PP_BOOL_87	1
#define IUTEST_PP_BOOL_88	1
#define IUTEST_PP_BOOL_89	1
#define IUTEST_PP_BOOL_90	1
#define IUTEST_PP_BOOL_91	1
#define IUTEST_PP_BOOL_92	1
#define IUTEST_PP_BOOL_93	1
#define IUTEST_PP_BOOL_94	1
#define IUTEST_PP_BOOL_95	1
#define IUTEST_PP_BOOL_96	1
#define IUTEST_PP_BOOL_97	1
#define IUTEST_PP_BOOL_98	1
#define IUTEST_PP_BOOL_99	1
#define IUTEST_PP_BOOL_100	1
#define IUTEST_PP_BOOL_101	1
#define IUTEST_PP_BOOL_102	1
#define IUTEST_PP_BOOL_103	1
#define IUTEST_PP_BOOL_104	1
#define IUTEST_PP_BOOL_105	1
#define IUTEST_PP_BOOL_106	1
#define IUTEST_PP_BOOL_107	1
#define IUTEST_PP_BOOL_108	1
#define IUTEST_PP_BOOL_109	1
#define IUTEST_PP_BOOL_110	1
#define IUTEST_PP_BOOL_111	1
#define IUTEST_PP_BOOL_112	1
#define IUTEST_PP_BOOL_113	1
#define IUTEST_PP_BOOL_114	1
#define IUTEST_PP_BOOL_115	1
#define IUTEST_PP_BOOL_116	1
#define IUTEST_PP_BOOL_117	1
#define IUTEST_PP_BOOL_118	1
#define IUTEST_PP_BOOL_119	1
#define IUTEST_PP_BOOL_120	1
#define IUTEST_PP_BOOL_121	1
#define IUTEST_PP_BOOL_122	1
#define IUTEST_PP_BOOL_123	1
#define IUTEST_PP_BOOL_124	1
#define IUTEST_PP_BOOL_125	1
#define IUTEST_PP_BOOL_126	1
#define IUTEST_PP_BOOL_127	1
#define IUTEST_PP_BOOL_128	1
#define IUTEST_PP_BOOL_129	1
#define IUTEST_PP_BOOL_130	1
#define IUTEST_PP_BOOL_131	1
#define IUTEST_PP_BOOL_132	1
#define IUTEST_PP_BOOL_133	1
#define IUTEST_PP_BOOL_134	1
#define IUTEST_PP_BOOL_135	1
#define IUTEST_PP_BOOL_136	1
#define IUTEST_PP_BOOL_137	1
#define IUTEST_PP_BOOL_138	1
#define IUTEST_PP_BOOL_139	1
#define IUTEST_PP_BOOL_140	1
#define IUTEST_PP_BOOL_141	1
#define IUTEST_PP_BOOL_142	1
#define IUTEST_PP_BOOL_143	1
#define IUTEST_PP_BOOL_144	1
#define IUTEST_PP_BOOL_145	1
#define IUTEST_PP_BOOL_146	1
#define IUTEST_PP_BOOL_147	1
#define IUTEST_PP_BOOL_148	1
#define IUTEST_PP_BOOL_149	1
#define IUTEST_PP_BOOL_150	1
#define IUTEST_PP_BOOL_151	1
#define IUTEST_PP_BOOL_152	1
#define IUTEST_PP_BOOL_153	1
#define IUTEST_PP_BOOL_154	1
#define IUTEST_PP_BOOL_155	1
#define IUTEST_PP_BOOL_156	1
#define IUTEST_PP_BOOL_157	1
#define IUTEST_PP_BOOL_158	1
#define IUTEST_PP_BOOL_159	1
#define IUTEST_PP_BOOL_160	1
#define IUTEST_PP_BOOL_161	1
#define IUTEST_PP_BOOL_162	1
#define IUTEST_PP_BOOL_163	1
#define IUTEST_PP_BOOL_164	1
#define IUTEST_PP_BOOL_165	1
#define IUTEST_PP_BOOL_166	1
#define IUTEST_PP_BOOL_167	1
#define IUTEST_PP_BOOL_168	1
#define IUTEST_PP_BOOL_169	1
#define IUTEST_PP_BOOL_170	1
#define IUTEST_PP_BOOL_171	1
#define IUTEST_PP_BOOL_172	1
#define IUTEST_PP_BOOL_173	1
#define IUTEST_PP_BOOL_174	1
#define IUTEST_PP_BOOL_175	1
#define IUTEST_PP_BOOL_176	1
#define IUTEST_PP_BOOL_177	1
#define IUTEST_PP_BOOL_178	1
#define IUTEST_PP_BOOL_179	1
#define IUTEST_PP_BOOL_180	1
#define IUTEST_PP_BOOL_181	1
#define IUTEST_PP_BOOL_182	1
#define IUTEST_PP_BOOL_183	1
#define IUTEST_PP_BOOL_184	1
#define IUTEST_PP_BOOL_185	1
#define IUTEST_PP_BOOL_186	1
#define IUTEST_PP_BOOL_187	1
#define IUTEST_PP_BOOL_188	1
#define IUTEST_PP_BOOL_189	1
#define IUTEST_PP_BOOL_190	1
#define IUTEST_PP_BOOL_191	1
#define IUTEST_PP_BOOL_192	1
#define IUTEST_PP_BOOL_193	1
#define IUTEST_PP_BOOL_194	1
#define IUTEST_PP_BOOL_195	1
#define IUTEST_PP_BOOL_196	1
#define IUTEST_PP_BOOL_197	1
#define IUTEST_PP_BOOL_198	1
#define IUTEST_PP_BOOL_199	1
#define IUTEST_PP_BOOL_200	1
#define IUTEST_PP_BOOL_201	1
#define IUTEST_PP_BOOL_202	1
#define IUTEST_PP_BOOL_203	1
#define IUTEST_PP_BOOL_204	1
#define IUTEST_PP_BOOL_205	1
#define IUTEST_PP_BOOL_206	1
#define IUTEST_PP_BOOL_207	1
#define IUTEST_PP_BOOL_208	1
#define IUTEST_PP_BOOL_209	1
#define IUTEST_PP_BOOL_210	1
#define IUTEST_PP_BOOL_211	1
#define IUTEST_PP_BOOL_212	1
#define IUTEST_PP_BOOL_213	1
#define IUTEST_PP_BOOL_214	1
#define IUTEST_PP_BOOL_215	1
#define IUTEST_PP_BOOL_216	1
#define IUTEST_PP_BOOL_217	1
#define IUTEST_PP_BOOL_218	1
#define IUTEST_PP_BOOL_219	1
#define IUTEST_PP_BOOL_220	1
#define IUTEST_PP_BOOL_221	1
#define IUTEST_PP_BOOL_222	1
#define IUTEST_PP_BOOL_223	1
#define IUTEST_PP_BOOL_224	1
#define IUTEST_PP_BOOL_225	1
#define IUTEST_PP_BOOL_226	1
#define IUTEST_PP_BOOL_227	1
#define IUTEST_PP_BOOL_228	1
#define IUTEST_PP_BOOL_229	1
#define IUTEST_PP_BOOL_230	1
#define IUTEST_PP_BOOL_231	1
#define IUTEST_PP_BOOL_232	1
#define IUTEST_PP_BOOL_233	1
#define IUTEST_PP_BOOL_234	1
#define IUTEST_PP_BOOL_235	1
#define IUTEST_PP_BOOL_236	1
#define IUTEST_PP_BOOL_237	1
#define IUTEST_PP_BOOL_238	1
#define IUTEST_PP_BOOL_239	1
#define IUTEST_PP_BOOL_240	1
#define IUTEST_PP_BOOL_241	1
#define IUTEST_PP_BOOL_242	1
#define IUTEST_PP_BOOL_243	1
#define IUTEST_PP_BOOL_244	1
#define IUTEST_PP_BOOL_245	1
#define IUTEST_PP_BOOL_246	1
#define IUTEST_PP_BOOL_247	1
#define IUTEST_PP_BOOL_248	1
#define IUTEST_PP_BOOL_249	1
#define IUTEST_PP_BOOL_250	1
#define IUTEST_PP_BOOL_251	1
#define IUTEST_PP_BOOL_252	1
#define IUTEST_PP_BOOL_253	1
#define IUTEST_PP_BOOL_254	1
#define IUTEST_PP_BOOL_255	1

// IF
#define IUTEST_PP_IF(cond, t, f)	IUTEST_PP_IF_I(IUTEST_PP_BOOL(cond), t, f)
#define IUTEST_PP_IF_I(cond, t, f)	IUTEST_PP_CAT(IUTEST_PP_IF_, cond)(t, f)
#define IUTEST_PP_IF_0(t, f)		f
#define IUTEST_PP_IF_1(t, f)		t

// IS EMPTY
#define IUTEST_PP_IS_EMPTY(x)		IUTEST_PP_IS_EMPTY_I(x IUTEST_PP_EMPTY_TAG)
#define IUTEST_PP_IS_EMPTY_I(x)		IUTEST_PP_IS_EMPTY_I_( IUTEST_PP_CAT(IUTEST_PP_EMPTY_TAG_, x)() )
#define IUTEST_PP_IS_EMPTY_I_(x)	IUTEST_PP_IS_EMPTY_II((x))
#define IUTEST_PP_IS_EMPTY_II(x)	IUTEST_PP_IS_EMPTY_II_ x
#define IUTEST_PP_IS_EMPTY_II_(a, b)	b

#define IUTEST_PP_EMPTY()		
#define IUTEST_PP_EMPTY_TAG()	, 0
#define IUTEST_PP_EMPTY_TAG_IUTEST_PP_EMPTY_TAG	1, 1 IUTEST_PP_EMPTY

/**
 * @}
*/

#endif // INCG_IRIS_IUTEST_PP_HPP_E8F72184_9C72_4E74_B581_A1F51F291F3A_

//======================================================================
// define
#ifndef IUTEST_HAS_HDR_TYPETARITS
#  if defined(__clang__)
#    if __has_include( <type_traits> ) && IUTEST_HAS_CXX11
#      define IUTEST_HAS_HDR_TYPETARITS		1
#    endif
#  elif (defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)) && IUTEST_HAS_CXX11
#    define IUTEST_HAS_HDR_TYPETARITS		1
#  elif defined(_MSC_VER)
#    if _MSC_VER >= 1600
#      define IUTEST_HAS_HDR_TYPETARITS		1
#    endif
#  endif
#endif

#ifndef IUTEST_HAS_HDR_TYPETARITS
#  define IUTEST_HAS_HDR_TYPETARITS			0
#endif

#ifndef IUTEST_HAS_RVALUE_REFS
#  if   (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#    define IUTEST_HAS_RVALUE_REFS	1
#  elif defined(_MSC_VER) && (_MSC_VER >= 1700)
#    define IUTEST_HAS_RVALUE_REFS	1
#  endif
#endif

#ifndef IUTEST_HAS_RVALUE_REFS
#  define IUTEST_HAS_RVALUE_REFS	0
#endif

#if IUTEST_HAS_HDR_TYPETARITS
#  include <type_traits>
#endif


namespace iutest_type_traits
{

/**
 * @brief	identity
*/
template<typename T>struct identity { typedef T type; };

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

/**
* @brief	add const to pointer
*/
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;
};

#endif


#if IUTEST_HAS_HDR_TYPETARITS

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_pointer;
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::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;
using ::std::is_member_function_pointer;
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 > {};

template<bool B>
struct bool_constant : ::std::integral_constant<bool, B> {};

#else

//======================================================================
// struct

/**
 * @brief	bool constant
*/
template<bool B>
struct bool_constant
{
#if defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
	enum { value = B };
#else
	static const bool value = B;
#endif
};
#if !defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
template<bool B>const bool bool_constant<B>::value;
#endif

typedef bool_constant<true>  true_type;
typedef bool_constant<false> false_type;

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

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

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

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

/**
 * @brief	remove_cv
*/
template<typename T>
struct remove_cv
{
	typedef typename remove_const< typename remove_volatile<T>::type >::type type;
};

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

#endif

namespace is_pointer_helper
{


template<typename T>
class is_pointer
{
#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
	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;
#else
	typedef T rmcv_type;
	static T& make_t();
	static char IsPointerHelper(const volatile void*);
	static char (&IsPointerHelper(...))[2];

	enum { IsPointer = sizeof(IsPointerHelper(make_t())) == 1 ? true : false };
public:
	typedef bool_constant<IsPointer> type;
#endif
};

}

/**
 * @brief	is_pointer
*/
#if !defined(_MSC_VER) || _MSC_VER >= 1310
template<typename T>
struct is_pointer : public is_pointer_helper::is_pointer<T>::type {};
#else
template<typename T>
struct is_pointer_impl : public is_pointer_helper::is_pointer<T> {};

template<typename T>
struct is_pointer : public is_pointer_impl<T>::type {};
#endif

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

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;
};

}

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

}

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

}

/**
 * @brief	is_const
*/
template<typename T>
struct is_const : public is_const_helper::is_const<T>::type {};

#endif // #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

namespace is_same_helper
{

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)


template<typename T1, typename T2>
struct is_same { typedef false_type type; };

template<typename T>
struct is_same<T, T> { typedef true_type type; };

#elif IUTEST_HAS_CLASS_MEMBER_TEMPLATE_SPECIALIZATION


template<typename T1, typename T2>
class is_same
{
	template<typename T>
	struct impl { typedef false_type type; };
	template<>
	struct impl<T1> { typedef true_type type; };
public:
	typedef typename impl<T2>::type type;
};

#endif

}

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || IUTEST_HAS_CLASS_MEMBER_TEMPLATE_SPECIALIZATION

/**
 * @brief	is_same
*/
template<typename T1, typename T2>
struct is_same : public is_same_helper::is_same<T1, T2>::type {};

#endif

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;
};

}

/**
 * @brief	is class
*/
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(void);

	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;
};

}

/**
 * @brief	is convertible
*/
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
{
#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
	typedef typename remove_cv<Base>::type B;
	typedef typename remove_cv<Derived>::type D;
#else
	typedef Base B;
	typedef Derived D;
#endif
	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;
};

}

/**
 * @brief	is base of
*/
template<typename Base, typename Derived>
struct is_base_of : public is_base_of_helper::is_base_of<Base, Derived>::type
{
};


#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

/**
 * @brief	add lvalue reference
*/
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;
};

/**
 * @brief	add rvalue reference
*/
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;
};

#else

template<typename T>
struct add_rvalue_reference { typedef T type; };

#endif

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

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 IIUT_DECL_IS_FUNCTION_PTR_(n)	\
template<typename R, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (*)(IUTEST_PP_ENUM_PARAMS(n, T))> : public true_type {};	\
template<typename R, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (*)(IUTEST_PP_ENUM_PARAMS(n, T), ...)> : public true_type {}

	IIUT_DECL_IS_FUNCTION_PTR_(1);
	IIUT_DECL_IS_FUNCTION_PTR_(2);
	IIUT_DECL_IS_FUNCTION_PTR_(3);
	IIUT_DECL_IS_FUNCTION_PTR_(4);
	IIUT_DECL_IS_FUNCTION_PTR_(5);
	IIUT_DECL_IS_FUNCTION_PTR_(6);
	IIUT_DECL_IS_FUNCTION_PTR_(7);
	IIUT_DECL_IS_FUNCTION_PTR_(8);
	IIUT_DECL_IS_FUNCTION_PTR_(9);
	IIUT_DECL_IS_FUNCTION_PTR_(10);
	IIUT_DECL_IS_FUNCTION_PTR_(11);
	IIUT_DECL_IS_FUNCTION_PTR_(12);
	IIUT_DECL_IS_FUNCTION_PTR_(13);
	IIUT_DECL_IS_FUNCTION_PTR_(14);
	IIUT_DECL_IS_FUNCTION_PTR_(15);
	IIUT_DECL_IS_FUNCTION_PTR_(16);
	IIUT_DECL_IS_FUNCTION_PTR_(17);
	IIUT_DECL_IS_FUNCTION_PTR_(18);
	IIUT_DECL_IS_FUNCTION_PTR_(19);
	IIUT_DECL_IS_FUNCTION_PTR_(20);

#undef IIUT_DECL_IS_FUNCTION_PTR_

#endif

	enum { value = impl< typename remove_cv<T>::type >::value };
public:
	typedef bool_constant<value> type;
};

}

/**
 * @brief	is function pointer
*/
template<typename T>
struct is_function_pointer : public is_function_pointer_helper::is_function_pointer<T>::type
{
};

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 IIUT_DECL_IS_MEMBER_FUNCTION_PTR_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 {}

	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_(IUTEST_PP_EMPTY());
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_(const);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_(volatile);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_(const volatile);

#undef IIUT_DECL_IS_MEMBER_FUNCTION_PTR_CV_

#else

#define IIUT_DECL_IS_MEMBER_FUNCTION_PTR_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 {};
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_VOID_CV_(const);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_VOID_CV_(volatile);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_VOID_CV_(const volatile);

#undef IIUT_DECL_IS_MEMBER_FUNCTION_PTR_VOID_CV_

#define IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(n)	\
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, IUTEST_PP_EMPTY());	\
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, const);	\
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, volatile);	\
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, const volatile)

#define IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I(n, CV)	\
	template<typename R, typename U, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (U::*)(IUTEST_PP_ENUM_PARAMS(n, T)) CV> : public true_type {};	\
	template<typename R, typename U, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (U::*)(IUTEST_PP_ENUM_PARAMS(n, T), ...) CV> : public true_type {}

	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(1);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(2);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(3);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(4);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(5);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(6);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(7);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(8);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(9);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(10);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(11);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(12);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(13);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(14);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(15);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(16);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(17);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(18);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(19);
	IIUT_DECL_IS_MEMBER_FUNCTION_PTR_(20);

#undef IIUT_DECL_IS_MEMBER_FUNCTION_PTR_
#undef IIUT_DECL_IS_MEMBER_FUNCTION_PTR_I

#endif

public:
	typedef bool_constant< impl< typename remove_cv<T>::type >::value > type;
};

}

/**
 * @brief	is member function pointer
*/
template<typename T>
struct is_member_function_pointer : public is_member_function_pointer_helper::is_member_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;
};

}

/**
 * @brief	is member pointer
*/
template<typename T>
struct is_member_pointer : public is_member_pointer_helper::is_member_pointer<T>::type
{
};

#endif // #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

#endif // #if IUTEST_HAS_HDR_TYPETRAITS

#if !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)

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
{
	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;
	};
}

/**
 * @brief	has equal to operator
*/
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;
	};
}

/**
 * @brief	has not equal to operator
*/
template<typename T>
struct has_not_equal_to : public has_not_equal_to_operator_impl::has_not_equal_to_operator<T>::type
{
};

#endif

#if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

/**
 * @brief	function return 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 IIUT_DECL_FUNCTION_RETURN_TYPE_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; }

	IIUT_DECL_FUNCTION_RETURN_TYPE_CV_(const);
	IIUT_DECL_FUNCTION_RETURN_TYPE_CV_(volatile);
	IIUT_DECL_FUNCTION_RETURN_TYPE_CV_(const volatile);
#undef IIUT_DECL_FUNCTION_RETURN_TYPE_CV_

#else

#define IIUT_DECL_FUNCTION_RETURN_TYPE_(n)	\
	template<typename R, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (*)(IUTEST_PP_ENUM_PARAMS(n, T))>	\
	{ typedef R type; };	\
	template<typename R, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (*)(IUTEST_PP_ENUM_PARAMS(n, T), ...)>	\
	{ typedef R type; };	\
	IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, IUTEST_PP_EMPTY());	\
	IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, const);	\
	IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, volatile);	\
	IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, const volatile)

#define IIUT_DECL_FUNCTION_RETURN_TYPE_I(n, CV)	\
	template<typename R, typename U, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (U::*)(IUTEST_PP_ENUM_PARAMS(n, T)) CV>	\
	{ typedef R type; };	\
	template<typename R, typename U, IUTEST_PP_ENUM_PARAMS(n, typename T)>struct impl<R (U::*)(IUTEST_PP_ENUM_PARAMS(n, T), ...) CV>	\
	{ typedef R type; }

	template<typename R>struct impl<R (*)(void)>	{ typedef R type; };
	template<typename R, typename U>struct impl<R (U::*)(void)>	{ typedef R type; };

#define IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_(CV)	\
	template<typename R, typename U>struct impl<R (U::*)(void) CV>	{ typedef R type; }

	IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_(const);
	IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_(volatile);
	IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_(const volatile);

#undef IIUT_DECL_FUNCTION_RETURN_TYPE_VOID_

	IIUT_DECL_FUNCTION_RETURN_TYPE_(1);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(2);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(3);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(4);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(5);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(6);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(7);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(8);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(9);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(10);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(11);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(12);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(13);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(14);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(15);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(16);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(17);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(18);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(19);
	IIUT_DECL_FUNCTION_RETURN_TYPE_(20);

#undef IIUT_DECL_FUNCTION_RETURN_TYPE_
#undef IIUT_DECL_FUNCTION_RETURN_TYPE_I

#endif

public:
	typedef typename impl< typename remove_cv<T>::type >::type type;
};

#endif // #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)

}	// end of namespace iutest_type_traits

#endif // INCG_IRIS_IUTEST_TYPE_TRAITS_HPP_6F091F15_784A_4F50_BD18_B8F67C5AF0CF_

//======================================================================
// define
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	== テスト(collection)
 * @param	b1	= 期待値の先頭
 * @param	e1	= 期待値の終端
 * @param	b2	= 検査対象の先頭
 * @param	e2	= 検査対象の終端
*/
#ifndef IUTEST_ASSERT_EQ_COLLECTIONS
#  define	IUTEST_ASSERT_EQ_COLLECTIONS(b1, e1, b2, e2)	IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	== テスト(collection)
 * @param	b1	= 期待値の先頭
 * @param	e1	= 期待値の終端
 * @param	b2	= 検査対象の先頭
 * @param	e2	= 検査対象の終端
*/
#ifndef IUTEST_EXPECT_EQ_COLLECTIONS
#  define	IUTEST_EXPECT_EQ_COLLECTIONS(b1, e1, b2, e2)	IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	== テスト(collection)
 * @param	b1	= 期待値の先頭
 * @param	e1	= 期待値の終端
 * @param	b2	= 検査対象の先頭
 * @param	e2	= 検査対象の終端
*/
#ifndef IUTEST_INFORM_EQ_COLLECTIONS
#  define	IUTEST_INFORM_EQ_COLLECTIONS(b1, e1, b2, e2)	IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	== テスト(collection)
 * @param	b1	= 期待値の先頭
 * @param	e1	= 期待値の終端
 * @param	b2	= 検査対象の先頭
 * @param	e2	= 検査対象の終端
*/
#ifndef IUTEST_ASSUME_EQ_COLLECTIONS
#  define	IUTEST_ASSUME_EQ_COLLECTIONS(b1, e1, b2, e2)	IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	== テスト(range)
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSERT_EQ_RANGE
#  define	IUTEST_ASSERT_EQ_RANGE(expected, actual)	IUTEST_TEST_EQ_RANGE(expected, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	== テスト(range)
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_EXPECT_EQ_RANGE
#  define	IUTEST_EXPECT_EQ_RANGE(expected, actual)	IUTEST_TEST_EQ_RANGE(expected, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	== テスト(range)
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_INFORM_EQ_RANGE
#  define	IUTEST_INFORM_EQ_RANGE(expected, actual)	IUTEST_TEST_EQ_RANGE(expected, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	== テスト(range)
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSUME_EQ_RANGE
#  define	IUTEST_ASSUME_EQ_RANGE(expected, actual)	IUTEST_TEST_EQ_RANGE(expected, actual, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列長の一致 テスト
 * @param	len		= 期待文字列長
 * @param	v2		= 検査対象
*/
#ifndef IUTEST_ASSERT_STRLNEQ
#  define	IUTEST_ASSERT_STRLNEQ(len, v2)			IUTEST_TEST_STRLNEQ(len, v2, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列長の一致 テスト
 * @param	len		= 期待文字列長
 * @param	v2		= 検査対象
*/
#ifndef IUTEST_EXPECT_STRLNEQ
#  define	IUTEST_EXPECT_STRLNEQ(len, v2)			IUTEST_TEST_STRLNEQ(len, v2, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列長の一致 テスト
 * @param	len		= 期待文字列長
 * @param	v2		= 検査対象
*/
#ifndef IUTEST_INFORM_STRLNEQ
#  define	IUTEST_INFORM_STRLNEQ(len, v2)			IUTEST_TEST_STRLNEQ(len, v2, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列長の一致 テスト
 * @param	len		= 期待文字列長
 * @param	v2		= 検査対象
*/
#ifndef IUTEST_ASSUME_STRLNEQ
#  define	IUTEST_ASSUME_STRLNEQ(len, v2)			IUTEST_TEST_STRLNEQ(len, v2, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_STRIN
#  define	IUTEST_ASSERT_STRIN(substr, actual)		IUTEST_TEST_STRIN(substr, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_EXPECT_STRIN
#  define	IUTEST_EXPECT_STRIN(substr, actual)		IUTEST_TEST_STRIN(substr, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_INFORM_STRIN
#  define	IUTEST_INFORM_STRIN(substr, actual)		IUTEST_TEST_STRIN(substr, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_ASSUME_STRIN
#  define	IUTEST_ASSUME_STRIN(substr, actual)		IUTEST_TEST_STRIN(substr, actual, IUTEST_ASSUME_FAILURE)
#endif


/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_STRNOTIN
#  define	IUTEST_ASSERT_STRNOTIN(substr, actual)		IUTEST_TEST_STRNOTIN(substr, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_EXPECT_STRNOTIN
#  define	IUTEST_EXPECT_STRNOTIN(substr, actual)		IUTEST_TEST_STRNOTIN(substr, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_INFORM_STRNOTIN
#  define	IUTEST_INFORM_STRNOTIN(substr, actual)		IUTEST_TEST_STRNOTIN(substr, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_ASSUME_STRNOTIN
#  define	IUTEST_ASSUME_STRNOTIN(substr, actual)		IUTEST_TEST_STRNOTIN(substr, actual, IUTEST_ASSUME_FAILURE)
#endif

#if IUTEST_HAS_REGEX

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列正規表現一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_MATCHES_REGEXEQ
#  define	IUTEST_ASSERT_MATCHES_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列正規表現一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_EXPECT_MATCHES_REGEXEQ
#  define	IUTEST_EXPECT_MATCHES_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列正規表現一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_INFORM_MATCHES_REGEXEQ
#  define	IUTEST_INFORM_MATCHES_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列正規表現一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_ASSUME_MATCHES_REGEXEQ
#  define	IUTEST_ASSUME_MATCHES_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列正規表現不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_MATCHES_REGEXNE
#  define	IUTEST_ASSERT_MATCHES_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列正規表現不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_EXPECT_MATCHES_REGEXNE
#  define	IUTEST_EXPECT_MATCHES_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列正規表現不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_INFORM_MATCHES_REGEXNE
#  define	IUTEST_INFORM_MATCHES_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列正規表現不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_ASSUME_MATCHES_REGEXNE
#  define	IUTEST_ASSUME_MATCHES_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, IUTEST_ASSUME_FAILURE)
#endif



/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列正規表現部分一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_CONTAINS_REGEXEQ
#  define	IUTEST_ASSERT_CONTAINS_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列正規表現部分一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_EXPECT_CONTAINS_REGEXEQ
#  define	IUTEST_EXPECT_CONTAINS_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列正規表現部分一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_INFORM_CONTAINS_REGEXEQ
#  define	IUTEST_INFORM_CONTAINS_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列正規表現部分一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_ASSUME_CONTAINS_REGEXEQ
#  define	IUTEST_ASSUME_CONTAINS_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列正規表現部分不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_CONTAINS_REGEXNE
#  define	IUTEST_ASSERT_CONTAINS_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列正規表現部分不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_EXPECT_CONTAINS_REGEXNE
#  define	IUTEST_EXPECT_CONTAINS_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列正規表現部分不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_INFORM_CONTAINS_REGEXNE
#  define	IUTEST_INFORM_CONTAINS_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列正規表現部分不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_ASSUME_CONTAINS_REGEXNE
#  define	IUTEST_ASSUME_CONTAINS_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, IUTEST_ASSUME_FAILURE)
#endif

#endif

/**
 * @private
 * @brief	for gtest
 * @{
*/

#define ASSERT_EQ_COLLECTIONS	IUTEST_ASSERT_EQ_COLLECTIONS
#define ASSERT_EQ_RANGE			IUTEST_ASSERT_EQ_RANGE
#define ASSERT_STRLNEQ			IUTEST_ASSERT_STRLNEQ
#define ASSERT_STRIN			IUTEST_ASSERT_STRIN
#define ASSERT_STRNOTIN			IUTEST_ASSERT_STRNOTIN

#define EXPECT_EQ_COLLECTIONS	IUTEST_EXPECT_EQ_COLLECTIONS
#define EXPECT_EQ_RANGE			IUTEST_EXPECT_EQ_RANGE
#define EXPECT_STRLNEQ			IUTEST_EXPECT_STRLNEQ
#define EXPECT_STRIN			IUTEST_EXPECT_STRIN
#define EXPECT_STRNOTIN			IUTEST_EXPECT_STRNOTIN

#define INFORM_EQ_COLLECTIONS	IUTEST_INFORM_EQ_COLLECTIONS
#define INFORM_EQ_RANGE			IUTEST_INFORM_EQ_RANGE
#define INFORM_STRLNEQ			IUTEST_INFORM_STRLNEQ
#define INFORM_STRIN			IUTEST_INFORM_STRIN
#define INFORM_STRNOTIN			IUTEST_INFORM_STRNOTIN

#define ASSUME_EQ_COLLECTIONS	IUTEST_ASSUME_EQ_COLLECTIONS
#define ASSUME_EQ_RANGE			IUTEST_ASSUME_EQ_RANGE
#define ASSUME_STRLNEQ			IUTEST_ASSUME_STRLNEQ
#define ASSUME_STRIN			IUTEST_ASSUME_STRIN
#define ASSUME_STRNOTIN			IUTEST_ASSUME_STRNOTIN

#if IUTEST_HAS_REGEX

#define ASSERT_MATCHES_REGEXEQ	IUTEST_ASSERT_MATCHES_REGEXEQ
#define EXPECT_MATCHES_REGEXEQ	IUTEST_EXPECT_MATCHES_REGEXEQ
#define INFORM_MATCHES_REGEXEQ	IUTEST_INFORM_MATCHES_REGEXEQ
#define ASSUME_MATCHES_REGEXEQ	IUTEST_ASSUME_MATCHES_REGEXEQ

#define ASSERT_MATCHES_REGEXNE	IUTEST_ASSERT_MATCHES_REGEXNE
#define EXPECT_MATCHES_REGEXNE	IUTEST_EXPECT_MATCHES_REGEXNE
#define INFORM_MATCHES_REGEXNE	IUTEST_INFORM_MATCHES_REGEXNE
#define ASSUME_MATCHES_REGEXNE	IUTEST_ASSUME_MATCHES_REGEXNE

#define ASSERT_CONTAINS_REGEXEQ	IUTEST_ASSERT_CONTAINS_REGEXEQ
#define EXPECT_CONTAINS_REGEXEQ	IUTEST_EXPECT_CONTAINS_REGEXEQ
#define INFORM_CONTAINS_REGEXEQ	IUTEST_INFORM_CONTAINS_REGEXEQ
#define ASSUME_CONTAINS_REGEXEQ	IUTEST_ASSUME_CONTAINS_REGEXEQ

#define ASSERT_CONTAINS_REGEXNE	IUTEST_ASSERT_CONTAINS_REGEXNE
#define EXPECT_CONTAINS_REGEXNE	IUTEST_EXPECT_CONTAINS_REGEXNE
#define INFORM_CONTAINS_REGEXNE	IUTEST_INFORM_CONTAINS_REGEXNE
#define ASSUME_CONTAINS_REGEXNE	IUTEST_ASSUME_CONTAINS_REGEXNE

#endif

/**
 * @}
*/

/**
 * @private
 * @{
*/
#define IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, on_failure) IUTEST_PRED_FORMAT4_( ::iuutil::CmpHelperEqCollections, b1, e1, b2, e2, on_failure)
#define IUTEST_TEST_EQ_RANGE(expected, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperEqRange, expected, actual, on_failure)

#define	IUTEST_TEST_STRLNEQ(len, v2, on_failure)	IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperSTRLNEQ, len, v2, on_failure )
#define IUTEST_TEST_STRIN(substr, actual, on_failure)		IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperSTRIN, substr, actual, on_failure )
#define IUTEST_TEST_STRNOTIN(substr, actual, on_failure)	IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperSTRNOTIN, substr, actual, on_failure )

#if IUTEST_HAS_REGEX

#define IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperMatchesRegexEq, regex_str, actual, on_failure )
#define IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperMatchesRegexNe, regex_str, actual, on_failure )

#define IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperContainsRegexEq, regex_str, actual, on_failure )
#define IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperContainsRegexNe, regex_str, actual, on_failure )

#endif

/**
 * @}
*/

namespace iuutil
{

//======================================================================
// function
/**
 * @brief	Equal Collection Helper
*/
template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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::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();
}

/**
 * @brief	Equal Collection Helper
*/
template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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) )
		;
	else
		return ::iutest::AssertionFailure() << "error: Expected: { " << expr1b << ", " << expr1e << " } == { "
			<< expr2b << ", " << expr2e << " }\n  Actual:" << ar.message();
	return ::iutest::AssertionSuccess();
}

namespace detail
{

template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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) )
		;
	else
		return ::iutest::AssertionFailure() << "error: Expected: " << expected_expr << " == " << actual_expr
			<< " \n  Actual:" << ar.message();
	return ::iutest::AssertionSuccess();
}

}

/**
 * @brief	Equal Range Helper
*/
template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
	, T1 expected, T2 actual)
{
	return detail::CmpHelperEqRange(expected_expr, actual_expr, expected.begin(), expected.end()
		, actual.begin(), actual.end());
}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)


template<typename T1, size_t SIZE1, typename T2, size_t SIZE2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
	, T1 (&expected)[SIZE1], T2 (&actual)[SIZE2])
{
	return detail::CmpHelperEqRange(expected_expr, actual_expr, expected, expected+SIZE1
		, actual, actual+SIZE2);
}

template<typename T1, typename T2, size_t SIZE2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
	, T1 expected, T2(&actual)[SIZE2])
{
	return detail::CmpHelperEqRange(expected_expr, actual_expr, expected.begin(), expected.end()
		, actual, actual+SIZE2);
}

template<typename T1, size_t SIZE1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
	, T1(&expected)[SIZE1], T2 actual)
{
	return detail::CmpHelperEqRange(expected_expr, actual_expr, expected, expected+SIZE1
		, actual.begin(), actual.end());
}

#endif

/**
 * @brief	文字列長アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 ;
}
/**
 * @brief	文字列長アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ Compare(const char* substr, const char* actual)
{
	if( substr == NULL || actual == NULL )
	{
		return substr == actual;
	}
	return strstr(actual, substr) != NULL;
}

inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const wchar_t* substr, const wchar_t* actual)
{
	if( substr == NULL || actual == NULL )
	{
		return substr == actual;
	}
	return wcsstr(actual, substr) != NULL;
}

template<typename Elem, typename Traits, typename Ax>
inline bool IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* substr_str, const char* actual_str
	, const T1& substr, const T2& actual)
{
	if( Compare(substr, actual) )
	{
		return ::iutest::AssertionSuccess();
	}

	return ::iutest::AssertionFailure() << "error: Expected: " << "strstr(" << actual_str << ", " << substr_str << ") != NULL"
		<< "\n  Actual: " << "strstr(\"" << actual << "\", " << substr << ") == NULL";
}

}

/**
 * @brief	文字列部分一致アサーションフォーマッター
*/
template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRIN(const char* substr_str, const char* actual_str
	, const T1& substr, const T2& actual)
{
	return StrInHelper::Assertion(substr_str, actual_str, substr, actual);
}

namespace StrNotInHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& substr, const T2& actual)
{
	return !StrInHelper::Compare(substr, actual);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* substr_str, const char* actual_str
	, const T1& substr, const T2& actual)
{
	if( Compare(substr, actual) )
	{
		return ::iutest::AssertionSuccess();
	}

	return ::iutest::AssertionFailure() << "error: Expected: " << "strstr(" << actual_str << ", " << substr_str << ") == NULL"
		<< "\n  Actual: " << "strstr(\"" << actual << "\", " << substr << ") != NULL";
}

}

/**
 * @brief	文字列部分一致アサーションフォーマッター
*/
template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNOTIN(const char* substr_str, const char* actual_str
	, const T1& substr, const T2& actual)
{
	return StrNotInHelper::Assertion(substr_str, actual_str, substr, actual);
}

#if IUTEST_HAS_REGEX

namespace RegexHelper
{

inline bool FullMatch(const ::std::string& str, ::iutest::internal::RE& re)
{
	return ::iutest::internal::RE::FullMatch(str, re);
}
inline bool FullMatch(const char* str, ::iutest::internal::RE& re)
{
	if( str == NULL ) return false;
	return ::iutest::internal::RE::FullMatch(str, re);
}

inline bool PartialMatch(const ::std::string& str, ::iutest::internal::RE& re)
{
	return ::iutest::internal::RE::PartialMatch(str, re);
}
inline bool PartialMatch(const char* str, ::iutest::internal::RE& re)
{
	if( str == NULL ) return false;
	return ::iutest::internal::RE::PartialMatch(str, re);
}

}

namespace MatchesRegexEqHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& regex_str, const T2& actual)
{
	::iutest::internal::RE m(regex_str);
	return RegexHelper::FullMatch(actual, m);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* regex_str, const char* actual_str
	, const T1& regex, const T2& actual)
{
	if( Compare(regex, actual) )
	{
		return ::iutest::AssertionSuccess();
	}
	::std::string expected_str = "Matches Regex (";
	expected_str += regex_str;
	expected_str += ")";

	return ::iutest::internal::EqFailure(expected_str.c_str(), actual_str
		, ::iutest::PrintToString(regex)
		, ::iutest::PrintToString(actual)
		, false);
}

}

/**
 * @brief	文字列正規表現一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperMatchesRegexEq(const char* regex, const char* actual_str
	, const char* regex_str, const char* actual)
{
	return MatchesRegexEqHelper::Assertion(regex, actual_str, regex_str, actual);
}

namespace MatchesRegexNeHelper
{

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* regex_str, const char* actual_str
	, const T1& regex, const T2& actual)
{
	if( !MatchesRegexEqHelper::Compare(regex, actual) )
	{
		return ::iutest::AssertionSuccess();
	}
	::std::string expected_str = "Not Matches Regex (";
	expected_str += regex_str;
	expected_str += ")";

	return ::iutest::internal::EqFailure(expected_str.c_str(), actual_str
		, ::iutest::PrintToString(regex)
		, ::iutest::PrintToString(actual)
		, false);
}

}

/**
 * @brief	文字列正規表現不一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperMatchesRegexNe(const char* regex, const char* actual_str
	, const char* regex_str, const char* actual)
{
	return MatchesRegexNeHelper::Assertion(regex, actual_str, regex_str, actual);
}

namespace ContainsRegexEqHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& regex_str, const T2& actual)
{
	::iutest::internal::RE m(regex_str);
	return RegexHelper::PartialMatch(actual, m);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* regex_str, const char* actual_str
	, const T1& regex, const T2& actual)
{
	if( Compare(regex, actual) )
	{
		return ::iutest::AssertionSuccess();
	}
	::std::string expected_str = "Contains Regex (";
	expected_str += regex_str;
	expected_str += ")";

	return ::iutest::internal::EqFailure(expected_str.c_str(), actual_str
		, ::iutest::PrintToString(regex)
		, ::iutest::PrintToString(actual)
		, false);
}

}

/**
 * @brief	文字列正規表現部分一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperContainsRegexEq(const char* regex, const char* actual_str
	, const char* regex_str, const char* actual)
{
	return ContainsRegexEqHelper::Assertion(regex, actual_str, regex_str, actual);
}

namespace ContainsRegexNeHelper
{

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* regex_str, const char* actual_str
	, const T1& regex, const T2& actual)
{
	if( !ContainsRegexEqHelper::Compare(regex, actual) )
	{
		return ::iutest::AssertionSuccess();
	}
	::std::string expected_str = "Not Contains Regex (";
	expected_str += regex_str;
	expected_str += ")";

	return ::iutest::internal::EqFailure(expected_str.c_str(), actual_str
		, ::iutest::PrintToString(regex)
		, ::iutest::PrintToString(actual)
		, false);
}

}

/**
 * @brief	文字列正規表現部分不一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperContainsRegexNe(const char* regex, const char* actual_str
	, const char* regex_str, const char* actual)
{
	return ContainsRegexNeHelper::Assertion(regex, actual_str, regex_str, actual);
}

#endif

/**
 * @private
 * @{
*/
#define IIUT_COMPARE_HELPER_DEC_(name)	struct name {										\
	template<typename T1, typename T2>														\
	static ::iutest::AssertionResult Comp(const char* expr1, const char* expr2, const T1& val1, const T2& val2) {	\
		return ::iutest::internal::CmpHelper##name(expr1, expr2, val1, val2);				\
	}																						\
	}
/**
 * @}
*/

}	// end of namespace iuutil

#endif // INCG_IRIS_IUTEST_UTIL_ASSERTION_HPP_A45F8265_40E0_44F2_91C6_090B1778657C_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util_output.hpp
 * @brief		iris unit test print 出力 utility ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_OUTPUT_HPP_44C683CF_3452_4F68_B34E_10606EB9E190_
#define INCG_IRIS_IUTEST_UTIL_OUTPUT_HPP_44C683CF_3452_4F68_B34E_10606EB9E190_

//======================================================================
// include
#ifdef INCG_IRIS_IUTEST_SWITCH_HPP_
#  ifdef IUTEST_USE_GTEST
#    ifndef iutest
#      define iutest	testing
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_console.hpp
 * @brief		iris unit test console
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_
#define INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_

//======================================================================
// include
#include <stdio.h>
#include <stdarg.h>

namespace iutest {
namespace detail
{

//======================================================================
// define
#ifndef IUTEST_VPRINTF
#  define IUTEST_VPRINTF(f, a)	vprintf(f, a)	//!< vprintf 呼び出しマクロ
#endif

#ifndef IUTEST_HAS_COLORCONSOLE
#  if defined(IUTEST_OS_WINDOWS_MOBILE) || defined(IUTEST_OS_NACL)
#    define IUTEST_HAS_COLORCONSOLE	0	//!< 色つきターミナルが使用可能かどうか
#  else
#    define IUTEST_HAS_COLORCONSOLE	1	//!< 色つきターミナルが使用可能かどうか
#  endif
#endif

//======================================================================
// class
/**
 * @internal
 * @brief	カスタム Logger クラス
*/
class iuLogger
{
public:
	virtual void output(const char* fmt, ...)
	{
		va_list va;
		va_start(va, fmt);
		voutput(fmt, va);
		va_end(va);
	}
	virtual void voutput(const char* fmt, va_list va) = 0;
};

/**
 * @internal
 * @brief	コンソールクラス
*/
class iuConsole
{
	template<typename T>
	struct Variable
	{
		static iuLogger* m_pLogger;
	};

	typedef Variable<void> var;

public:
	//! コンソール文字色
	enum Color
	{
		black,
		red,
		green,
		yellow,
		blue,
		magenta,
		cyan,
		white
	};
public:
	/**
	 * @brief	標準出力
	*/
	static inline void output(const char *fmt, ...);

	/**
	 * @brief	標準出力
	*/
	static inline void voutput(const char* fmt, va_list va);

	/**
	 * @brief	色指定で標準出力
	 * @param [in]	color	= 文字色
	*/
	static inline void color_output(Color color, const char *fmt, ...);

public:
	/**
	 * @brief	標準出力
	 * @note	no logger
	*/
	static inline void nl_output(const char *fmt, ...);

	/**
	 * @brief	標準出力
	 * @note	no logger
	*/
	static inline void nl_voutput(const char* fmt, va_list va);

public:
	//! Logger のセット
	static iuLogger* SetLogger(iuLogger* logger)
	{
		iuLogger* pre = var::m_pLogger;
		var::m_pLogger = logger;
		return pre;
	}
private:
	static inline void color_output_impl(Color color, const char* fmt, va_list va);
	static inline bool IsShouldUseColor(bool use_color);

private:
	static inline bool IsStringEqual(const char* str1, const char* str2) { return strcmp(str1, str2) == 0; }

	static bool IsColorModeOff(void)
	{
#if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
		return TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_OFF);
#else
		return IUTEST_FLAG(color) == "no";
#endif
	}
	static bool IsColorModeOn(void)
	{
#if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
		return TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ON);
#else
		return IUTEST_FLAG(color) == "yes";
#endif
	}
	static bool IsColorModeAnsi(void)
	{
#if defined(INCG_IRIS_IUTEST_HPP_) && !defined(IUTEST_USE_GTEST)
		return TestFlag::IsEnableFlag(TestFlag::CONSOLE_COLOR_ANSI);
#else
		return false;
#endif
	}
};

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)
{
	if( var::m_pLogger != NULL )
	{
		var::m_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);
#if defined(IUTEST_OS_WINDOWS) && !defined(IUTEST_OS_WINDOWS_MOBILE) && !defined(IUTEST_OS_WINDOWS_PHONE) && !defined(IUTEST_OS_WINDOWS_RT)
	if( !IsColorModeAnsi() )
	{
		const WORD attr[] = {
			0,
			FOREGROUND_RED,
			FOREGROUND_GREEN,
			FOREGROUND_GREEN | FOREGROUND_RED,
			FOREGROUND_BLUE,
			FOREGROUND_RED | FOREGROUND_BLUE,
			FOREGROUND_GREEN | FOREGROUND_BLUE,
			FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
		};
		const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
		CONSOLE_SCREEN_BUFFER_INFO csbi;
		::GetConsoleScreenBufferInfo(stdout_handle, &csbi);
		const WORD wAttributes = csbi.wAttributes;

		fflush(stdout);
		::SetConsoleTextAttribute(stdout_handle, attr[color] | FOREGROUND_INTENSITY);

		voutput(fmt, va);

		fflush(stdout);
		::SetConsoleTextAttribute(stdout_handle, wAttributes);
	}
	else
#endif
	{
		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;
	}

#if !IUTEST_HAS_COLORCONSOLE
	(void)(use_color);
	return false;
#else
#if defined(IUTEST_OS_WINDOWS)
	return use_color;
#else
	const char* env = internal::posix::GetEnv("TERM");
	bool term_conf = (env != NULL) && (
		IsStringEqual(env, "xterm")
		|| IsStringEqual(env, "xterm-color")
		|| IsStringEqual(env, "xterm-256color")
		|| IsStringEqual(env, "screen")
		|| IsStringEqual(env, "screen-256color")
		|| IsStringEqual(env, "rxvt-unicode")
		|| IsStringEqual(env, "rxvt-unicode-256color")
		|| IsStringEqual(env, "linux")
		|| IsStringEqual(env, "cygwin")
		);
	return use_color && term_conf;
#endif

#endif
}

}	// end of namespace detail
}	// end of namespace iutest

#if IUTEST_HAS_LIB && IUTEST_HAS_EXTERN_TEMPLATE

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template struct ::iutest::detail::iuConsole::Variable<void>;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#else

template<typename T>
::iutest::detail::iuLogger* ::iutest::detail::iuConsole::Variable<T>::m_pLogger = NULL;

#endif

#endif // INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_
#      undef iutest
#    else
#      undef INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_
#    endif
#  endif
#endif

namespace iuutil
{

//! コンソール出力クラスの再利用
typedef ::iutest::detail::iuConsole Console;

}	// end of namespace iuutil

#endif // INCG_IRIS_IUTEST_UTIL_OUTPUT_HPP_44C683CF_3452_4F68_B34E_10606EB9E190_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util_quiet_result_printer.hpp
 * @brief		iris unit test quiet result printer ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_QUIET_RESULT_PRINTER_HPP_0DF65DD7_C97C_44BA_940D_D22ED6AF9494_
#define INCG_IRIS_IUTEST_UTIL_QUIET_RESULT_PRINTER_HPP_0DF65DD7_C97C_44BA_940D_D22ED6AF9494_

//======================================================================
// include

namespace iuutil
{

//======================================================================
// class

/**
 * @brief	コンパクトなデフォルトコンソール出力イベントリスナー
*/
class QuietResultPrinter : public ::iutest::TestEventListener
{
public:
	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) { m_default_printer->OnTestProgramStart(unit_test); }

	virtual void OnTestIterationStart(const ::iutest::UnitTest& unit_test,
		int iteration) { m_default_printer->OnTestIterationStart(unit_test, iteration); }

	virtual void OnEnvironmentsSetUpStart(const ::iutest::UnitTest& unit_test) { m_default_printer->OnEnvironmentsSetUpStart(unit_test); }

	virtual void OnEnvironmentsSetUpEnd(const ::iutest::UnitTest& unit_test) { m_default_printer->OnEnvironmentsSetUpEnd(unit_test); }

	virtual void OnTestCaseStart(const ::iutest::TestCase& test_case) { m_default_printer->OnTestCaseStart(test_case); }

#if 0
	virtual void OnTestStart(const ::iutest::TestInfo& test_info) {}

	virtual void OnTestPartResult(const ::iutest::TestPartResult& test_part_result)
	{
		if( ::iutest::UnitTest::GetInstance()->current_test_info() != NULL )
		{
			const ::iutest::TestInfo& test_info = *::iutest::UnitTest::GetInstance()->current_test_info();
			if( test_info.result()->Failed()
				&& test_info.result()->total_part_count() == 1 )
			{
				m_default_printer->OnTestStart(test_info);
			}
		}
		m_default_printer->OnTestPartResult(test_part_result);
	}
#else
	virtual void OnTestStart(const ::iutest::TestInfo& test_info) { m_default_printer->OnTestStart(test_info); }

	virtual void OnTestPartResult(const ::iutest::TestPartResult& test_part_result) { m_default_printer->OnTestPartResult(test_part_result); }
#endif

	virtual void OnTestEnd(const ::iutest::TestInfo& test_info)
	{
		if( test_info.result()->Failed() )
		{
			// 失敗したときのみ出力する
			m_default_printer->OnTestEnd(test_info);
		}
	}

	virtual void OnTestCaseEnd(const ::iutest::TestCase& test_case) { m_default_printer->OnTestCaseEnd(test_case); }

	virtual void OnEnvironmentsTearDownStart(const ::iutest::UnitTest& unit_test) { m_default_printer->OnEnvironmentsTearDownStart(unit_test); }

	virtual void OnEnvironmentsTearDownEnd(const ::iutest::UnitTest& unit_test) { m_default_printer->OnEnvironmentsTearDownEnd(unit_test); }

	virtual void OnTestIterationEnd(const ::iutest::UnitTest& unit_test,
		int iteration) { m_default_printer->OnTestIterationEnd(unit_test, iteration); }

	virtual void OnTestProgramEnd(const ::iutest::UnitTest& unit_test) { m_default_printer->OnTestProgramEnd(unit_test); }
private:
	::iutest::TestEventListener* m_default_printer;

public:
	/**
	 * @brief	QuietResultPrinter に切り替え
	*/
	static ::iutest::TestEventListener* SetUp(void)
	{
		::iutest::TestEventListeners& listeners = ::iutest::UnitTest::GetInstance()->listeners();
		::iutest::TestEventListener* default_printer = listeners.Release(listeners.default_result_printer());
		if( default_printer == NULL )
		{
			return NULL;
		}
		::iutest::TestEventListener* p = new QuietResultPrinter(default_printer);
		listeners.Append(p);
		return p;
	}
};

}	// end of namespace iuutil

#endif // INCG_IRIS_IUTEST_UTIL_QUIET_RESULT_PRINTER_HPP_0DF65DD7_C97C_44BA_940D_D22ED6AF9494_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util_tests.hpp
 * @brief		iris unit test テスト情報 utility ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_TESTS_HPP_4095FF9B_D6B8_4CD3_BF86_43DFED1760EA_
#define INCG_IRIS_IUTEST_UTIL_TESTS_HPP_4095FF9B_D6B8_4CD3_BF86_43DFED1760EA_

//======================================================================
// include
namespace iuutil
{

//======================================================================
// function

/**
 * @brief	テスト名を取得
*/
inline ::std::string TestFullName(const ::iutest::TestInfo* test_info)
{
	::std::string fullname = test_info->test_case_name();
	fullname += ".";
	fullname += test_info->name();
	return fullname;
}

/**
 * @brief	インデックスを除いたテスト名を取得
*/
inline ::std::string TestNameRemoveIndexName(const char* name)
{
	const char* const p = strrchr(name, '/');
	if( p == NULL )
	{
		return name;
	}
	return ::std::string(name, p);
}

/**
 * @brief	インデックスを除いたテストケース名を取得
*/
inline ::std::string TestCaseNameRemoveIndexName(const char* name)
{
	return TestNameRemoveIndexName(name);
}

/**
 * @brief	インスタンス名とインデックスを除いたテストケース名を取得
*/
inline ::std::string TestCaseNameRemoveInstantiateAndIndexName(const char* name)
{
	// パッケージ名があれば取得
	const char* const pkg = strrchr(name, '.');
	// 先頭にインスタンス名がある
	const char* const p1 = strchr(name, '/');
	if( p1 == NULL )
	{
		return name;
	}
	if( pkg == NULL )
	{
		return TestCaseNameRemoveIndexName(p1 + 1);
	}
	else
	{
		return ::std::string(name, pkg + 1) + TestCaseNameRemoveIndexName(p1 + 1);
	}
}

/**
 * @brief	TestCase の検索
*/
inline const ::iutest::TestCase* FindTestCase(const char* testcase_name)
{
	if( testcase_name == NULL )
	{
		return NULL;
	}
	const int testcase_count = ::iutest::UnitTest::GetInstance()->total_test_case_count();
	for( int i=0; i < testcase_count; ++i )
	{
		const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
		if( strcmp(testcase->name(), testcase_name) == 0 )
		{
			return testcase;
		}
	}
	return NULL;
}

/**
 * @brief	TestCase の検索
*/
inline const ::iutest::TestCase* FindParamTestCase(const char* testcase_name, const ::iutest::TestCase* begin=NULL)
{
	if( testcase_name == NULL )
	{
		return NULL;
	}
	const int testcase_count = ::iutest::UnitTest::GetInstance()->total_test_case_count();
	int i=0;
	if( begin != NULL )
	{
		for( ; i < testcase_count; ++i )
		{
			const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
			if( testcase == begin )
			{
				break;
			}
		}
		++i;
	}
	for( ; i < testcase_count; ++i )
	{
		const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
		const char* testcase_origin_name = strchr(testcase->name(), '/');
		if( testcase_origin_name != NULL )
		{
			if( strcmp(testcase_origin_name+1, testcase_name) == 0 )
			{
				return testcase;
			}
		}
	}
	return NULL;
}

/**
 * @brief	Typed Test の TestCase の検索
*/
inline const ::iutest::TestCase* FindTypedTestCase(const char* testcase_name, const ::iutest::TestCase* begin=NULL)
{
	if( testcase_name == NULL )
	{
		return NULL;
	}
	const int testcase_count = ::iutest::UnitTest::GetInstance()->total_test_case_count();
	int i=0;
	if( begin != NULL )
	{
		for( ; i < testcase_count; ++i )
		{
			const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
			if( testcase == begin )
			{
				break;
			}
		}
		++i;
	}
	for( ; i < testcase_count; ++i )
	{
		const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
		if( testcase != NULL )
		{
			const char* name = testcase->name();
			if( name != NULL
				&& strstr(name, testcase_name) == name
				&& name[strlen(testcase_name)] == '/' )
			{
				return testcase;
			}
		}
	}
	return NULL;
}

/**
 * @brief	Type Parameter Test の TestCase の検索
*/
inline const ::iutest::TestCase* FindParamTypedTestCase(const char* testcase_name, const ::iutest::TestCase* begin=NULL)
{
	if( testcase_name == NULL )
	{
		return NULL;
	}
	const int testcase_count = ::iutest::UnitTest::GetInstance()->total_test_case_count();
	int i=0;
	if( begin != NULL )
	{
		for( ; i < testcase_count; ++i )
		{
			const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
			if( testcase == begin )
			{
				break;
			}
		}
		++i;
	}
	for( ; i < testcase_count; ++i )
	{
		const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
		const char* name = strchr(testcase->name(), '/');
		if( name != NULL )
		{
			++name;
			if( strstr(name, testcase_name) == name
				&& name[strlen(testcase_name)] == '/' )
			{
				return testcase;
			}
		}
	}
	return NULL;
}

/**
 * @brief	TestInfo の検索
*/
inline const ::iutest::TestInfo* FindTestInfo(const ::iutest::TestCase* testcase, const char* testinfo_name)
{
	if( testcase == NULL || testinfo_name == NULL )
	{
		return NULL;
	}

	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 NULL;
}

/**
 * @brief	TestInfo の検索
*/
inline const ::iutest::TestInfo* FindTestInfo(const char* testcase_name, const char* testinfo_name)
{
	if( testcase_name == NULL || testinfo_name == NULL )
	{
		return NULL;
	}
	const ::iutest::TestCase* testcase = FindTestCase(testcase_name);
	return FindTestInfo(testcase, testinfo_name);
}

/**
 * @brief	TestInfo の検索
*/
inline const ::iutest::TestInfo* FindParamTestInfo(const ::iutest::TestCase* testcase, const char* testinfo_name, const ::iutest::TestInfo* begin=NULL)
{
	if( testcase == NULL || testinfo_name == NULL )
	{
		return NULL;
	}

	const int testinfo_count = testcase->total_test_count();
	int i=0;
	if( begin != NULL )
	{
		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 != NULL )
		{
			const char* name = testinfo->name();
			if( name != NULL
				&& strstr(name, testinfo_name) == name
				&& name[strlen(testinfo_name)] == '/' )
			{
				return testinfo;
			}
		}
	}
	return NULL;
}

}	// end of namespace iuutil

#endif // INCG_IRIS_IUTEST_UTIL_TESTS_HPP_4095FF9B_D6B8_4CD3_BF86_43DFED1760EA_

/**
 * @brief iutest utility namespace
*/
namespace iuutil {}

/**
 * @ingroup		IUTEST_UTIL
 * @brief		ファイルシステムの設定
 * @note		ユーザー定義のファイルクラスを利用するようにするためのマクロです。
*/
#define IUTEST_FILESYSTEM_INSTANTIATE(file_class_name)	IIUT_FILESYSTEM_INSTANTIATE_(file_class_name)

/**
 * @private
 * @{
*/
#define IIUT_FILESYSTEM_INSTANTIATE_(file_class_name)	static ::iutest::FileSystem< file_class_name > IUTEST_ATTRIBUTE_UNUSED_ s_iutest_filesystem_

/**
 * @}
*/

#endif // INCG_IRIS_IUTEST_UTIL_HPP_EBAC3846_4D1E_4B32_A85F_6D6A7CCFAF75_

#ifndef INCG_IRIS_IUTEST_HPP_
#  define INCG_IRIS_IUTEST_HPP_	// 以降で、iutest が include されないようにする
#endif

#endif

#endif // INCG_IRIS_IUTEST_SWITCH_HPP_
#endif

//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util.hpp
 * @brief		iris unit test utility
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_HPP_EBAC3846_4D1E_4B32_A85F_6D6A7CCFAF75_
#define INCG_IRIS_IUTEST_UTIL_HPP_EBAC3846_4D1E_4B32_A85F_6D6A7CCFAF75_

//======================================================================
// include
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util_assertion.hpp
 * @brief		iris unit test assertion 拡張 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_ASSERTION_HPP_A45F8265_40E0_44F2_91C6_090B1778657C_
#define INCG_IRIS_IUTEST_UTIL_ASSERTION_HPP_A45F8265_40E0_44F2_91C6_090B1778657C_

//======================================================================
// include

//======================================================================
// define
/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	== テスト(collection)
 * @param	b1	= 期待値の先頭
 * @param	e1	= 期待値の終端
 * @param	b2	= 検査対象の先頭
 * @param	e2	= 検査対象の終端
*/
#ifndef IUTEST_ASSERT_EQ_COLLECTIONS
#  define	IUTEST_ASSERT_EQ_COLLECTIONS(b1, e1, b2, e2)	IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	== テスト(collection)
 * @param	b1	= 期待値の先頭
 * @param	e1	= 期待値の終端
 * @param	b2	= 検査対象の先頭
 * @param	e2	= 検査対象の終端
*/
#ifndef IUTEST_EXPECT_EQ_COLLECTIONS
#  define	IUTEST_EXPECT_EQ_COLLECTIONS(b1, e1, b2, e2)	IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	== テスト(collection)
 * @param	b1	= 期待値の先頭
 * @param	e1	= 期待値の終端
 * @param	b2	= 検査対象の先頭
 * @param	e2	= 検査対象の終端
*/
#ifndef IUTEST_INFORM_EQ_COLLECTIONS
#  define	IUTEST_INFORM_EQ_COLLECTIONS(b1, e1, b2, e2)	IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	== テスト(collection)
 * @param	b1	= 期待値の先頭
 * @param	e1	= 期待値の終端
 * @param	b2	= 検査対象の先頭
 * @param	e2	= 検査対象の終端
*/
#ifndef IUTEST_ASSUME_EQ_COLLECTIONS
#  define	IUTEST_ASSUME_EQ_COLLECTIONS(b1, e1, b2, e2)	IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	== テスト(range)
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSERT_EQ_RANGE
#  define	IUTEST_ASSERT_EQ_RANGE(expected, actual)	IUTEST_TEST_EQ_RANGE(expected, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	== テスト(range)
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_EXPECT_EQ_RANGE
#  define	IUTEST_EXPECT_EQ_RANGE(expected, actual)	IUTEST_TEST_EQ_RANGE(expected, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM_
 * @brief	== テスト(range)
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_INFORM_EQ_RANGE
#  define	IUTEST_INFORM_EQ_RANGE(expected, actual)	IUTEST_TEST_EQ_RANGE(expected, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME_
 * @brief	== テスト(range)
 * @param	expected	= 期待値
 * @param	actual		= 検査対象
*/
#ifndef IUTEST_ASSUME_EQ_RANGE
#  define	IUTEST_ASSUME_EQ_RANGE(expected, actual)	IUTEST_TEST_EQ_RANGE(expected, actual, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列長の一致 テスト
 * @param	len		= 期待文字列長
 * @param	v2		= 検査対象
*/
#ifndef IUTEST_ASSERT_STRLNEQ
#  define	IUTEST_ASSERT_STRLNEQ(len, v2)			IUTEST_TEST_STRLNEQ(len, v2, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列長の一致 テスト
 * @param	len		= 期待文字列長
 * @param	v2		= 検査対象
*/
#ifndef IUTEST_EXPECT_STRLNEQ
#  define	IUTEST_EXPECT_STRLNEQ(len, v2)			IUTEST_TEST_STRLNEQ(len, v2, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列長の一致 テスト
 * @param	len		= 期待文字列長
 * @param	v2		= 検査対象
*/
#ifndef IUTEST_INFORM_STRLNEQ
#  define	IUTEST_INFORM_STRLNEQ(len, v2)			IUTEST_TEST_STRLNEQ(len, v2, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列長の一致 テスト
 * @param	len		= 期待文字列長
 * @param	v2		= 検査対象
*/
#ifndef IUTEST_ASSUME_STRLNEQ
#  define	IUTEST_ASSUME_STRLNEQ(len, v2)			IUTEST_TEST_STRLNEQ(len, v2, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_STRIN
#  define	IUTEST_ASSERT_STRIN(substr, actual)		IUTEST_TEST_STRIN(substr, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_EXPECT_STRIN
#  define	IUTEST_EXPECT_STRIN(substr, actual)		IUTEST_TEST_STRIN(substr, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_INFORM_STRIN
#  define	IUTEST_INFORM_STRIN(substr, actual)		IUTEST_TEST_STRIN(substr, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_ASSUME_STRIN
#  define	IUTEST_ASSUME_STRIN(substr, actual)		IUTEST_TEST_STRIN(substr, actual, IUTEST_ASSUME_FAILURE)
#endif


/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_STRNOTIN
#  define	IUTEST_ASSERT_STRNOTIN(substr, actual)		IUTEST_TEST_STRNOTIN(substr, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_EXPECT_STRNOTIN
#  define	IUTEST_EXPECT_STRNOTIN(substr, actual)		IUTEST_TEST_STRNOTIN(substr, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_INFORM_STRNOTIN
#  define	IUTEST_INFORM_STRNOTIN(substr, actual)		IUTEST_TEST_STRNOTIN(substr, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列部分一致 テスト
 * @param	substr	= 部分文字列
 * @param	actual	= 検査対象文字列
*/
#ifndef IUTEST_ASSUME_STRNOTIN
#  define	IUTEST_ASSUME_STRNOTIN(substr, actual)		IUTEST_TEST_STRNOTIN(substr, actual, IUTEST_ASSUME_FAILURE)
#endif

#if IUTEST_HAS_REGEX

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列正規表現一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_MATCHES_REGEXEQ
#  define	IUTEST_ASSERT_MATCHES_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列正規表現一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_EXPECT_MATCHES_REGEXEQ
#  define	IUTEST_EXPECT_MATCHES_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列正規表現一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_INFORM_MATCHES_REGEXEQ
#  define	IUTEST_INFORM_MATCHES_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列正規表現一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_ASSUME_MATCHES_REGEXEQ
#  define	IUTEST_ASSUME_MATCHES_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列正規表現不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_MATCHES_REGEXNE
#  define	IUTEST_ASSERT_MATCHES_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列正規表現不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_EXPECT_MATCHES_REGEXNE
#  define	IUTEST_EXPECT_MATCHES_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列正規表現不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_INFORM_MATCHES_REGEXNE
#  define	IUTEST_INFORM_MATCHES_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列正規表現不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_ASSUME_MATCHES_REGEXNE
#  define	IUTEST_ASSUME_MATCHES_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, IUTEST_ASSUME_FAILURE)
#endif



/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列正規表現部分一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_CONTAINS_REGEXEQ
#  define	IUTEST_ASSERT_CONTAINS_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列正規表現部分一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_EXPECT_CONTAINS_REGEXEQ
#  define	IUTEST_EXPECT_CONTAINS_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列正規表現部分一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_INFORM_CONTAINS_REGEXEQ
#  define	IUTEST_INFORM_CONTAINS_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列正規表現部分一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_ASSUME_CONTAINS_REGEXEQ
#  define	IUTEST_ASSUME_CONTAINS_REGEXEQ(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, IUTEST_ASSUME_FAILURE)
#endif

/**
 * @ingroup	IUTEST_ASSERT_
 * @brief	文字列正規表現部分不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
*/
#ifndef IUTEST_ASSERT_CONTAINS_REGEXNE
#  define	IUTEST_ASSERT_CONTAINS_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, IUTEST_ASSERT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_EXPECT_
 * @brief	文字列正規表現部分不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_EXPECT_CONTAINS_REGEXNE
#  define	IUTEST_EXPECT_CONTAINS_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, IUTEST_EXPECT_FAILURE)
#endif
/**
 * @ingroup	IUTEST_INFORM
 * @brief	文字列正規表現部分不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_INFORM_CONTAINS_REGEXNE
#  define	IUTEST_INFORM_CONTAINS_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, IUTEST_INFORM_FAILURE)
#endif
/**
 * @ingroup	IUTEST_ASSUME
 * @brief	文字列正規表現部分不一致 テスト
 * @param	regex_str	= 正規表現文字列
 * @param	actual		= 検査対象文字列
 */
#ifndef IUTEST_ASSUME_CONTAINS_REGEXNE
#  define	IUTEST_ASSUME_CONTAINS_REGEXNE(regex_str, actual)		\
	IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, IUTEST_ASSUME_FAILURE)
#endif

#endif

/**
 * @private
 * @brief	for gtest
 * @{
*/

#define ASSERT_EQ_COLLECTIONS	IUTEST_ASSERT_EQ_COLLECTIONS
#define ASSERT_EQ_RANGE			IUTEST_ASSERT_EQ_RANGE
#define ASSERT_STRLNEQ			IUTEST_ASSERT_STRLNEQ
#define ASSERT_STRIN			IUTEST_ASSERT_STRIN
#define ASSERT_STRNOTIN			IUTEST_ASSERT_STRNOTIN

#define EXPECT_EQ_COLLECTIONS	IUTEST_EXPECT_EQ_COLLECTIONS
#define EXPECT_EQ_RANGE			IUTEST_EXPECT_EQ_RANGE
#define EXPECT_STRLNEQ			IUTEST_EXPECT_STRLNEQ
#define EXPECT_STRIN			IUTEST_EXPECT_STRIN
#define EXPECT_STRNOTIN			IUTEST_EXPECT_STRNOTIN

#define INFORM_EQ_COLLECTIONS	IUTEST_INFORM_EQ_COLLECTIONS
#define INFORM_EQ_RANGE			IUTEST_INFORM_EQ_RANGE
#define INFORM_STRLNEQ			IUTEST_INFORM_STRLNEQ
#define INFORM_STRIN			IUTEST_INFORM_STRIN
#define INFORM_STRNOTIN			IUTEST_INFORM_STRNOTIN

#define ASSUME_EQ_COLLECTIONS	IUTEST_ASSUME_EQ_COLLECTIONS
#define ASSUME_EQ_RANGE			IUTEST_ASSUME_EQ_RANGE
#define ASSUME_STRLNEQ			IUTEST_ASSUME_STRLNEQ
#define ASSUME_STRIN			IUTEST_ASSUME_STRIN
#define ASSUME_STRNOTIN			IUTEST_ASSUME_STRNOTIN

#if IUTEST_HAS_REGEX

#define ASSERT_MATCHES_REGEXEQ	IUTEST_ASSERT_MATCHES_REGEXEQ
#define EXPECT_MATCHES_REGEXEQ	IUTEST_EXPECT_MATCHES_REGEXEQ
#define INFORM_MATCHES_REGEXEQ	IUTEST_INFORM_MATCHES_REGEXEQ
#define ASSUME_MATCHES_REGEXEQ	IUTEST_ASSUME_MATCHES_REGEXEQ

#define ASSERT_MATCHES_REGEXNE	IUTEST_ASSERT_MATCHES_REGEXNE
#define EXPECT_MATCHES_REGEXNE	IUTEST_EXPECT_MATCHES_REGEXNE
#define INFORM_MATCHES_REGEXNE	IUTEST_INFORM_MATCHES_REGEXNE
#define ASSUME_MATCHES_REGEXNE	IUTEST_ASSUME_MATCHES_REGEXNE

#define ASSERT_CONTAINS_REGEXEQ	IUTEST_ASSERT_CONTAINS_REGEXEQ
#define EXPECT_CONTAINS_REGEXEQ	IUTEST_EXPECT_CONTAINS_REGEXEQ
#define INFORM_CONTAINS_REGEXEQ	IUTEST_INFORM_CONTAINS_REGEXEQ
#define ASSUME_CONTAINS_REGEXEQ	IUTEST_ASSUME_CONTAINS_REGEXEQ

#define ASSERT_CONTAINS_REGEXNE	IUTEST_ASSERT_CONTAINS_REGEXNE
#define EXPECT_CONTAINS_REGEXNE	IUTEST_EXPECT_CONTAINS_REGEXNE
#define INFORM_CONTAINS_REGEXNE	IUTEST_INFORM_CONTAINS_REGEXNE
#define ASSUME_CONTAINS_REGEXNE	IUTEST_ASSUME_CONTAINS_REGEXNE

#endif

/**
 * @}
*/

/**
 * @private
 * @{
*/
#define IUTEST_TEST_EQ_COLLECTIONS(b1, e1, b2, e2, on_failure) IUTEST_PRED_FORMAT4_( ::iuutil::CmpHelperEqCollections, b1, e1, b2, e2, on_failure)
#define IUTEST_TEST_EQ_RANGE(expected, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperEqRange, expected, actual, on_failure)

#define	IUTEST_TEST_STRLNEQ(len, v2, on_failure)	IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperSTRLNEQ, len, v2, on_failure )
#define IUTEST_TEST_STRIN(substr, actual, on_failure)		IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperSTRIN, substr, actual, on_failure )
#define IUTEST_TEST_STRNOTIN(substr, actual, on_failure)	IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperSTRNOTIN, substr, actual, on_failure )

#if IUTEST_HAS_REGEX

#define IUTEST_TEST_MATCHES_REGEXEQ(regex_str, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperMatchesRegexEq, regex_str, actual, on_failure )
#define IUTEST_TEST_MATCHES_REGEXNE(regex_str, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperMatchesRegexNe, regex_str, actual, on_failure )

#define IUTEST_TEST_CONTAINS_REGEXEQ(regex_str, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperContainsRegexEq, regex_str, actual, on_failure )
#define IUTEST_TEST_CONTAINS_REGEXNE(regex_str, actual, on_failure) IUTEST_PRED_FORMAT2_( ::iuutil::CmpHelperContainsRegexNe, regex_str, actual, on_failure )

#endif

/**
 * @}
*/

namespace iuutil
{

//======================================================================
// function
/**
 * @brief	Equal Collection Helper
*/
template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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::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();
}

/**
 * @brief	Equal Collection Helper
*/
template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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) )
		;
	else
		return ::iutest::AssertionFailure() << "error: Expected: { " << expr1b << ", " << expr1e << " } == { "
			<< expr2b << ", " << expr2e << " }\n  Actual:" << ar.message();
	return ::iutest::AssertionSuccess();
}

namespace detail
{

template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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) )
		;
	else
		return ::iutest::AssertionFailure() << "error: Expected: " << expected_expr << " == " << actual_expr
			<< " \n  Actual:" << ar.message();
	return ::iutest::AssertionSuccess();
}

}

/**
 * @brief	Equal Range Helper
*/
template<typename T1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
	, T1 expected, T2 actual)
{
	return detail::CmpHelperEqRange(expected_expr, actual_expr, expected.begin(), expected.end()
		, actual.begin(), actual.end());
}
#if !defined(IUTEST_NO_FUNCTION_TEMPLATE_ORDERING)


template<typename T1, size_t SIZE1, typename T2, size_t SIZE2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
	, T1 (&expected)[SIZE1], T2 (&actual)[SIZE2])
{
	return detail::CmpHelperEqRange(expected_expr, actual_expr, expected, expected+SIZE1
		, actual, actual+SIZE2);
}

template<typename T1, typename T2, size_t SIZE2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
	, T1 expected, T2(&actual)[SIZE2])
{
	return detail::CmpHelperEqRange(expected_expr, actual_expr, expected.begin(), expected.end()
		, actual, actual+SIZE2);
}

template<typename T1, size_t SIZE1, typename T2>
::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperEqRange(const char* expected_expr, const char* actual_expr
	, T1(&expected)[SIZE1], T2 actual)
{
	return detail::CmpHelperEqRange(expected_expr, actual_expr, expected, expected+SIZE1
		, actual.begin(), actual.end());
}

#endif

/**
 * @brief	文字列長アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 ;
}
/**
 * @brief	文字列長アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ Compare(const char* substr, const char* actual)
{
	if( substr == NULL || actual == NULL )
	{
		return substr == actual;
	}
	return strstr(actual, substr) != NULL;
}

inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const wchar_t* substr, const wchar_t* actual)
{
	if( substr == NULL || actual == NULL )
	{
		return substr == actual;
	}
	return wcsstr(actual, substr) != NULL;
}

template<typename Elem, typename Traits, typename Ax>
inline bool IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ 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 IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* substr_str, const char* actual_str
	, const T1& substr, const T2& actual)
{
	if( Compare(substr, actual) )
	{
		return ::iutest::AssertionSuccess();
	}

	return ::iutest::AssertionFailure() << "error: Expected: " << "strstr(" << actual_str << ", " << substr_str << ") != NULL"
		<< "\n  Actual: " << "strstr(\"" << actual << "\", " << substr << ") == NULL";
}

}

/**
 * @brief	文字列部分一致アサーションフォーマッター
*/
template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRIN(const char* substr_str, const char* actual_str
	, const T1& substr, const T2& actual)
{
	return StrInHelper::Assertion(substr_str, actual_str, substr, actual);
}

namespace StrNotInHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& substr, const T2& actual)
{
	return !StrInHelper::Compare(substr, actual);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* substr_str, const char* actual_str
	, const T1& substr, const T2& actual)
{
	if( Compare(substr, actual) )
	{
		return ::iutest::AssertionSuccess();
	}

	return ::iutest::AssertionFailure() << "error: Expected: " << "strstr(" << actual_str << ", " << substr_str << ") == NULL"
		<< "\n  Actual: " << "strstr(\"" << actual << "\", " << substr << ") != NULL";
}

}

/**
 * @brief	文字列部分一致アサーションフォーマッター
*/
template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperSTRNOTIN(const char* substr_str, const char* actual_str
	, const T1& substr, const T2& actual)
{
	return StrNotInHelper::Assertion(substr_str, actual_str, substr, actual);
}

#if IUTEST_HAS_REGEX

namespace RegexHelper
{

inline bool FullMatch(const ::std::string& str, ::iutest::internal::RE& re)
{
	return ::iutest::internal::RE::FullMatch(str, re);
}
inline bool FullMatch(const char* str, ::iutest::internal::RE& re)
{
	if( str == NULL ) return false;
	return ::iutest::internal::RE::FullMatch(str, re);
}

inline bool PartialMatch(const ::std::string& str, ::iutest::internal::RE& re)
{
	return ::iutest::internal::RE::PartialMatch(str, re);
}
inline bool PartialMatch(const char* str, ::iutest::internal::RE& re)
{
	if( str == NULL ) return false;
	return ::iutest::internal::RE::PartialMatch(str, re);
}

}

namespace MatchesRegexEqHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& regex_str, const T2& actual)
{
	::iutest::internal::RE m(regex_str);
	return RegexHelper::FullMatch(actual, m);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* regex_str, const char* actual_str
	, const T1& regex, const T2& actual)
{
	if( Compare(regex, actual) )
	{
		return ::iutest::AssertionSuccess();
	}
	::std::string expected_str = "Matches Regex (";
	expected_str += regex_str;
	expected_str += ")";

	return ::iutest::internal::EqFailure(expected_str.c_str(), actual_str
		, ::iutest::PrintToString(regex)
		, ::iutest::PrintToString(actual)
		, false);
}

}

/**
 * @brief	文字列正規表現一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperMatchesRegexEq(const char* regex, const char* actual_str
	, const char* regex_str, const char* actual)
{
	return MatchesRegexEqHelper::Assertion(regex, actual_str, regex_str, actual);
}

namespace MatchesRegexNeHelper
{

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* regex_str, const char* actual_str
	, const T1& regex, const T2& actual)
{
	if( !MatchesRegexEqHelper::Compare(regex, actual) )
	{
		return ::iutest::AssertionSuccess();
	}
	::std::string expected_str = "Not Matches Regex (";
	expected_str += regex_str;
	expected_str += ")";

	return ::iutest::internal::EqFailure(expected_str.c_str(), actual_str
		, ::iutest::PrintToString(regex)
		, ::iutest::PrintToString(actual)
		, false);
}

}

/**
 * @brief	文字列正規表現不一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperMatchesRegexNe(const char* regex, const char* actual_str
	, const char* regex_str, const char* actual)
{
	return MatchesRegexNeHelper::Assertion(regex, actual_str, regex_str, actual);
}

namespace ContainsRegexEqHelper
{

template<typename T1, typename T2>
inline bool IUTEST_ATTRIBUTE_UNUSED_ Compare(const T1& regex_str, const T2& actual)
{
	::iutest::internal::RE m(regex_str);
	return RegexHelper::PartialMatch(actual, m);
}

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* regex_str, const char* actual_str
	, const T1& regex, const T2& actual)
{
	if( Compare(regex, actual) )
	{
		return ::iutest::AssertionSuccess();
	}
	::std::string expected_str = "Contains Regex (";
	expected_str += regex_str;
	expected_str += ")";

	return ::iutest::internal::EqFailure(expected_str.c_str(), actual_str
		, ::iutest::PrintToString(regex)
		, ::iutest::PrintToString(actual)
		, false);
}

}

/**
 * @brief	文字列正規表現部分一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperContainsRegexEq(const char* regex, const char* actual_str
	, const char* regex_str, const char* actual)
{
	return ContainsRegexEqHelper::Assertion(regex, actual_str, regex_str, actual);
}

namespace ContainsRegexNeHelper
{

template<typename T1, typename T2>
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ Assertion(const char* regex_str, const char* actual_str
	, const T1& regex, const T2& actual)
{
	if( !ContainsRegexEqHelper::Compare(regex, actual) )
	{
		return ::iutest::AssertionSuccess();
	}
	::std::string expected_str = "Not Contains Regex (";
	expected_str += regex_str;
	expected_str += ")";

	return ::iutest::internal::EqFailure(expected_str.c_str(), actual_str
		, ::iutest::PrintToString(regex)
		, ::iutest::PrintToString(actual)
		, false);
}

}

/**
 * @brief	文字列正規表現部分不一致アサーションフォーマッター
*/
inline ::iutest::AssertionResult IUTEST_ATTRIBUTE_UNUSED_ CmpHelperContainsRegexNe(const char* regex, const char* actual_str
	, const char* regex_str, const char* actual)
{
	return ContainsRegexNeHelper::Assertion(regex, actual_str, regex_str, actual);
}

#endif

/**
 * @private
 * @{
*/
#define IIUT_COMPARE_HELPER_DEC_(name)	struct name {										\
	template<typename T1, typename T2>														\
	static ::iutest::AssertionResult Comp(const char* expr1, const char* expr2, const T1& val1, const T2& val2) {	\
		return ::iutest::internal::CmpHelper##name(expr1, expr2, val1, val2);				\
	}																						\
	}
/**
 * @}
*/

}	// end of namespace iuutil

#endif // INCG_IRIS_IUTEST_UTIL_ASSERTION_HPP_A45F8265_40E0_44F2_91C6_090B1778657C_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util_output.hpp
 * @brief		iris unit test print 出力 utility ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_OUTPUT_HPP_44C683CF_3452_4F68_B34E_10606EB9E190_
#define INCG_IRIS_IUTEST_UTIL_OUTPUT_HPP_44C683CF_3452_4F68_B34E_10606EB9E190_

//======================================================================
// include
#ifdef INCG_IRIS_IUTEST_SWITCH_HPP_
#  ifdef IUTEST_USE_GTEST
#    ifndef iutest
#      define iutest	testing
#      undef iutest
#    else
#      undef INCG_IRIS_IUTEST_CONSOLE_HPP_DCAC5025_B7BB_424E_A849_9E6FE0A3B460_
#    endif
#  endif
#endif

namespace iuutil
{

//! コンソール出力クラスの再利用
typedef ::iutest::detail::iuConsole Console;

}	// end of namespace iuutil

#endif // INCG_IRIS_IUTEST_UTIL_OUTPUT_HPP_44C683CF_3452_4F68_B34E_10606EB9E190_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util_quiet_result_printer.hpp
 * @brief		iris unit test quiet result printer ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_QUIET_RESULT_PRINTER_HPP_0DF65DD7_C97C_44BA_940D_D22ED6AF9494_
#define INCG_IRIS_IUTEST_UTIL_QUIET_RESULT_PRINTER_HPP_0DF65DD7_C97C_44BA_940D_D22ED6AF9494_

//======================================================================
// include

namespace iuutil
{

//======================================================================
// class

/**
 * @brief	コンパクトなデフォルトコンソール出力イベントリスナー
*/
class QuietResultPrinter : public ::iutest::TestEventListener
{
public:
	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) { m_default_printer->OnTestProgramStart(unit_test); }

	virtual void OnTestIterationStart(const ::iutest::UnitTest& unit_test,
		int iteration) { m_default_printer->OnTestIterationStart(unit_test, iteration); }

	virtual void OnEnvironmentsSetUpStart(const ::iutest::UnitTest& unit_test) { m_default_printer->OnEnvironmentsSetUpStart(unit_test); }

	virtual void OnEnvironmentsSetUpEnd(const ::iutest::UnitTest& unit_test) { m_default_printer->OnEnvironmentsSetUpEnd(unit_test); }

	virtual void OnTestCaseStart(const ::iutest::TestCase& test_case) { m_default_printer->OnTestCaseStart(test_case); }

#if 0
	virtual void OnTestStart(const ::iutest::TestInfo& test_info) {}

	virtual void OnTestPartResult(const ::iutest::TestPartResult& test_part_result)
	{
		if( ::iutest::UnitTest::GetInstance()->current_test_info() != NULL )
		{
			const ::iutest::TestInfo& test_info = *::iutest::UnitTest::GetInstance()->current_test_info();
			if( test_info.result()->Failed()
				&& test_info.result()->total_part_count() == 1 )
			{
				m_default_printer->OnTestStart(test_info);
			}
		}
		m_default_printer->OnTestPartResult(test_part_result);
	}
#else
	virtual void OnTestStart(const ::iutest::TestInfo& test_info) { m_default_printer->OnTestStart(test_info); }

	virtual void OnTestPartResult(const ::iutest::TestPartResult& test_part_result) { m_default_printer->OnTestPartResult(test_part_result); }
#endif

	virtual void OnTestEnd(const ::iutest::TestInfo& test_info)
	{
		if( test_info.result()->Failed() )
		{
			// 失敗したときのみ出力する
			m_default_printer->OnTestEnd(test_info);
		}
	}

	virtual void OnTestCaseEnd(const ::iutest::TestCase& test_case) { m_default_printer->OnTestCaseEnd(test_case); }

	virtual void OnEnvironmentsTearDownStart(const ::iutest::UnitTest& unit_test) { m_default_printer->OnEnvironmentsTearDownStart(unit_test); }

	virtual void OnEnvironmentsTearDownEnd(const ::iutest::UnitTest& unit_test) { m_default_printer->OnEnvironmentsTearDownEnd(unit_test); }

	virtual void OnTestIterationEnd(const ::iutest::UnitTest& unit_test,
		int iteration) { m_default_printer->OnTestIterationEnd(unit_test, iteration); }

	virtual void OnTestProgramEnd(const ::iutest::UnitTest& unit_test) { m_default_printer->OnTestProgramEnd(unit_test); }
private:
	::iutest::TestEventListener* m_default_printer;

public:
	/**
	 * @brief	QuietResultPrinter に切り替え
	*/
	static ::iutest::TestEventListener* SetUp(void)
	{
		::iutest::TestEventListeners& listeners = ::iutest::UnitTest::GetInstance()->listeners();
		::iutest::TestEventListener* default_printer = listeners.Release(listeners.default_result_printer());
		if( default_printer == NULL )
		{
			return NULL;
		}
		::iutest::TestEventListener* p = new QuietResultPrinter(default_printer);
		listeners.Append(p);
		return p;
	}
};

}	// end of namespace iuutil

#endif // INCG_IRIS_IUTEST_UTIL_QUIET_RESULT_PRINTER_HPP_0DF65DD7_C97C_44BA_940D_D22ED6AF9494_
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_util_tests.hpp
 * @brief		iris unit test テスト情報 utility ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2012-2015, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_UTIL_TESTS_HPP_4095FF9B_D6B8_4CD3_BF86_43DFED1760EA_
#define INCG_IRIS_IUTEST_UTIL_TESTS_HPP_4095FF9B_D6B8_4CD3_BF86_43DFED1760EA_

//======================================================================
// include
namespace iuutil
{

//======================================================================
// function

/**
 * @brief	テスト名を取得
*/
inline ::std::string TestFullName(const ::iutest::TestInfo* test_info)
{
	::std::string fullname = test_info->test_case_name();
	fullname += ".";
	fullname += test_info->name();
	return fullname;
}

/**
 * @brief	インデックスを除いたテスト名を取得
*/
inline ::std::string TestNameRemoveIndexName(const char* name)
{
	const char* const p = strrchr(name, '/');
	if( p == NULL )
	{
		return name;
	}
	return ::std::string(name, p);
}

/**
 * @brief	インデックスを除いたテストケース名を取得
*/
inline ::std::string TestCaseNameRemoveIndexName(const char* name)
{
	return TestNameRemoveIndexName(name);
}

/**
 * @brief	インスタンス名とインデックスを除いたテストケース名を取得
*/
inline ::std::string TestCaseNameRemoveInstantiateAndIndexName(const char* name)
{
	// パッケージ名があれば取得
	const char* const pkg = strrchr(name, '.');
	// 先頭にインスタンス名がある
	const char* const p1 = strchr(name, '/');
	if( p1 == NULL )
	{
		return name;
	}
	if( pkg == NULL )
	{
		return TestCaseNameRemoveIndexName(p1 + 1);
	}
	else
	{
		return ::std::string(name, pkg + 1) + TestCaseNameRemoveIndexName(p1 + 1);
	}
}

/**
 * @brief	TestCase の検索
*/
inline const ::iutest::TestCase* FindTestCase(const char* testcase_name)
{
	if( testcase_name == NULL )
	{
		return NULL;
	}
	const int testcase_count = ::iutest::UnitTest::GetInstance()->total_test_case_count();
	for( int i=0; i < testcase_count; ++i )
	{
		const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
		if( strcmp(testcase->name(), testcase_name) == 0 )
		{
			return testcase;
		}
	}
	return NULL;
}

/**
 * @brief	TestCase の検索
*/
inline const ::iutest::TestCase* FindParamTestCase(const char* testcase_name, const ::iutest::TestCase* begin=NULL)
{
	if( testcase_name == NULL )
	{
		return NULL;
	}
	const int testcase_count = ::iutest::UnitTest::GetInstance()->total_test_case_count();
	int i=0;
	if( begin != NULL )
	{
		for( ; i < testcase_count; ++i )
		{
			const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
			if( testcase == begin )
			{
				break;
			}
		}
		++i;
	}
	for( ; i < testcase_count; ++i )
	{
		const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
		const char* testcase_origin_name = strchr(testcase->name(), '/');
		if( testcase_origin_name != NULL )
		{
			if( strcmp(testcase_origin_name+1, testcase_name) == 0 )
			{
				return testcase;
			}
		}
	}
	return NULL;
}

/**
 * @brief	Typed Test の TestCase の検索
*/
inline const ::iutest::TestCase* FindTypedTestCase(const char* testcase_name, const ::iutest::TestCase* begin=NULL)
{
	if( testcase_name == NULL )
	{
		return NULL;
	}
	const int testcase_count = ::iutest::UnitTest::GetInstance()->total_test_case_count();
	int i=0;
	if( begin != NULL )
	{
		for( ; i < testcase_count; ++i )
		{
			const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
			if( testcase == begin )
			{
				break;
			}
		}
		++i;
	}
	for( ; i < testcase_count; ++i )
	{
		const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
		if( testcase != NULL )
		{
			const char* name = testcase->name();
			if( name != NULL
				&& strstr(name, testcase_name) == name
				&& name[strlen(testcase_name)] == '/' )
			{
				return testcase;
			}
		}
	}
	return NULL;
}

/**
 * @brief	Type Parameter Test の TestCase の検索
*/
inline const ::iutest::TestCase* FindParamTypedTestCase(const char* testcase_name, const ::iutest::TestCase* begin=NULL)
{
	if( testcase_name == NULL )
	{
		return NULL;
	}
	const int testcase_count = ::iutest::UnitTest::GetInstance()->total_test_case_count();
	int i=0;
	if( begin != NULL )
	{
		for( ; i < testcase_count; ++i )
		{
			const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
			if( testcase == begin )
			{
				break;
			}
		}
		++i;
	}
	for( ; i < testcase_count; ++i )
	{
		const ::iutest::TestCase* testcase = ::iutest::UnitTest::GetInstance()->GetTestCase(i);
		const char* name = strchr(testcase->name(), '/');
		if( name != NULL )
		{
			++name;
			if( strstr(name, testcase_name) == name
				&& name[strlen(testcase_name)] == '/' )
			{
				return testcase;
			}
		}
	}
	return NULL;
}

/**
 * @brief	TestInfo の検索
*/
inline const ::iutest::TestInfo* FindTestInfo(const ::iutest::TestCase* testcase, const char* testinfo_name)
{
	if( testcase == NULL || testinfo_name == NULL )
	{
		return NULL;
	}

	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 NULL;
}

/**
 * @brief	TestInfo の検索
*/
inline const ::iutest::TestInfo* FindTestInfo(const char* testcase_name, const char* testinfo_name)
{
	if( testcase_name == NULL || testinfo_name == NULL )
	{
		return NULL;
	}
	const ::iutest::TestCase* testcase = FindTestCase(testcase_name);
	return FindTestInfo(testcase, testinfo_name);
}

/**
 * @brief	TestInfo の検索
*/
inline const ::iutest::TestInfo* FindParamTestInfo(const ::iutest::TestCase* testcase, const char* testinfo_name, const ::iutest::TestInfo* begin=NULL)
{
	if( testcase == NULL || testinfo_name == NULL )
	{
		return NULL;
	}

	const int testinfo_count = testcase->total_test_count();
	int i=0;
	if( begin != NULL )
	{
		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 != NULL )
		{
			const char* name = testinfo->name();
			if( name != NULL
				&& strstr(name, testinfo_name) == name
				&& name[strlen(testinfo_name)] == '/' )
			{
				return testinfo;
			}
		}
	}
	return NULL;
}

}	// end of namespace iuutil

#endif // INCG_IRIS_IUTEST_UTIL_TESTS_HPP_4095FF9B_D6B8_4CD3_BF86_43DFED1760EA_

/**
 * @brief iutest utility namespace
*/
namespace iuutil {}

/**
 * @ingroup		IUTEST_UTIL
 * @brief		ファイルシステムの設定
 * @note		ユーザー定義のファイルクラスを利用するようにするためのマクロです。
*/
#define IUTEST_FILESYSTEM_INSTANTIATE(file_class_name)	IIUT_FILESYSTEM_INSTANTIATE_(file_class_name)

/**
 * @private
 * @{
*/
#define IIUT_FILESYSTEM_INSTANTIATE_(file_class_name)	static ::iutest::FileSystem< file_class_name > IUTEST_ATTRIBUTE_UNUSED_ s_iutest_filesystem_

/**
 * @}
*/

#endif // INCG_IRIS_IUTEST_UTIL_HPP_EBAC3846_4D1E_4B32_A85F_6D6A7CCFAF75_

#if defined(IUTEST_USE_MAIN)
//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_default_main.hpp
 * @brief		iris unit test default main
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2014, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_DEFAULT_MAIN_HPP_954CE73E_3002_4339_AE91_030BDE594F8F_
#define INCG_IRIS_IUTEST_DEFAULT_MAIN_HPP_954CE73E_3002_4339_AE91_030BDE594F8F_

//======================================================================
// function

/**
 * @brief	default main
*/
#ifdef UNICODE
int wmain(int argc, wchar_t** argv)
#else
int main(int argc, char** argv)
#endif
{
#if !defined(IUTEST_OS_WINDOWS_MOBILE)
	setlocale(LC_CTYPE, "");
#endif

	IUTEST_INIT(&argc, argv);
	return IUTEST_RUN_ALL_TESTS();
}

#endif // INCG_IRIS_IUTEST_DEFAULT_MAIN_HPP_954CE73E_3002_4339_AE91_030BDE594F8F_
#endif

#endif // INCG_IRIS_IUTEST_HPP_
